Scott Jenson / Mbed 2 deprecated BLE_EddystoneBeaconConfigService_Button

Dependencies:   BLE_API_EddystoneConfigService_2 mbed nRF51822

Fork of BLE_EddystoneBeaconConfigService_3 by URIBeacon

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "BLE.h"
00019 #include "EddystoneConfigService.h"
00020 
00021 #include "ConfigParamsPersistence.h"
00022 //#include "BLEDevice.h"
00023 #include "DeviceInformationService.h"
00024 
00025 BLE ble;
00026 EddystoneConfigService *EddystoneBeaconConfig;
00027 EddystoneConfigService::Params_t params;
00028 
00029 //Serial pc(USBTX,USBRX);   // uncomment to use printf(...)
00030 
00031 #define TINYBLE false
00032 #define SEEEDARCH true
00033 
00034 #if TINYBLE
00035 int ledOn = 0;
00036 int ledOff = 1;
00037 
00038 InterruptIn button1(P0_17);
00039 DigitalOut ledRed(P0_22);
00040 DigitalOut ledGreen(P0_21);
00041 DigitalOut ledBlue(P0_23);
00042 #endif
00043 
00044 #if SEEEDARCH
00045 int ledOn = 1;
00046 int ledOff = 0;
00047 
00048 InterruptIn button1(P0_18);
00049 DigitalOut ledRed(P0_16);
00050 DigitalOut ledGreen(P0_12);
00051 DigitalOut ledBlue(P0_15);
00052 #endif
00053 
00054 // Make sure to turn off before and after animation
00055 // to separate it from the LED which may already be on
00056 void ledRebootAnimation(void) {
00057     ledRed = ledOff;
00058     wait(0.1);
00059     ledRed = ledOn;
00060     wait(0.1);
00061     ledRed = ledOff;
00062     wait(0.1);
00063     ledRed = ledOn;
00064     wait(0.1);
00065     ledRed = ledOff;
00066     wait(0.1);
00067     ledRed = ledOn;
00068     wait(0.1);
00069     ledRed = ledOff; 
00070     wait(0.1);
00071 }
00072 
00073 /**
00074  * URIBeaconConfig service can operate in two modes: a configuration mode which
00075  * allows a user to update settings over a connection; and normal URIBeacon mode
00076  * which involves advertising a URI. Constructing an object from URIBeaconConfig
00077  * service sets up advertisements for the configuration mode. It is then up to
00078  * the application to switch to URIBeacon mode based on some timeout.
00079  *
00080  * The following help with this switch.
00081  */
00082 static const int CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS = 30;  // Duration after power-on that config service is available.
00083 
00084 Ticker configAdvertisementTimeout;
00085 
00086 /**
00087  * Stop advertising the Config Service after a delay; and switch to a non-connectable advertising mode only beacon.
00088  */
00089 void timeout(void)
00090 {
00091     ledRed = ledOff;
00092     Gap::GapState_t state;
00093     state = ble.getGapState();
00094     if (!state.connected) { /* don't switch if we're in a connected state. */
00095         configAdvertisementTimeout.detach(); /* disable the callback from the timeout Ticker. */
00096         EddystoneBeaconConfig->setupEddystoneAdvertisements();        
00097     }
00098 }
00099 
00100 /**
00101  * Callback triggered upon a disconnection event.
00102  */
00103 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
00104 {
00105     ledRed = ledOff;
00106     if (true == params.isConfigured){
00107         // end advertising, the beacon is configured
00108         timeout();
00109     }
00110     else{
00111         // eddystone is not configured, continue advertising    
00112         ble.gap().startAdvertising();
00113     }
00114 }
00115 int reboot = false; // global used later to reboot the beacon
00116 int dirty = false;  // global used to mark params is dirty and needs to be saved
00117 
00118 void handle_button1() {
00119     ble.gap().stopAdvertising();
00120     params.deepSleep = !params.deepSleep;
00121     dirty = true;
00122     }
00123 
00124 extern void pstorageSetup();
00125 
00126 int main(void)
00127 {
00128     ledRed = ledOff;
00129     ledGreen = ledOff;
00130     ledBlue = ledOff;
00131     ble.init();
00132     ble.gap().onDisconnection(disconnectionCallback);
00133 
00134     // Initialize button1 and pull up
00135     // set interrupt callback for button1    
00136     button1.fall(&handle_button1);
00137     button1.mode(PullUp);
00138 
00139     /*
00140      * Load parameters from (platform specific) persistent storage. Parameters
00141      * can be set to non-default values while the URIBeacon is in configuration
00142      * mode (within the first 60 seconds of power-up). Thereafter, parameters
00143      * get copied out to persistent storage before switching to normal URIBeacon
00144      * operation.
00145      */
00146     bool fetchedFromPersistentStorage = loadURIBeaconConfigParams(&params);
00147     
00148     // only setup beacon if device is NOT in deepSleep
00149     // Set UID and TLM frame data
00150     //EddystoneConfigService::UIDNamespaceID_t uidNamespaceID = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}; // 10Byte Namespace UUID
00151     //EddystoneConfigService::UIDInstanceID_t  uidInstanceID = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; // 6Byte Instance ID
00152     //uint8_t tlmVersion = 0x00;
00153     
00154     /* Initialize a EddystoneBeaconConfig service providing config params, default URI, and power levels. */
00155     static EddystoneConfigService::PowerLevels_t defaultAdvPowerLevels = {-48, -41, -35, -26}; // Values for ADV packets related to firmware levels, calibrated based on measured values at 1m
00156     static EddystoneConfigService::PowerLevels_t radioPowerLevels =      {-20, -12, -4, 4};    // Values for radio power levels, provided by manufacturer.
00157     EddystoneBeaconConfig = new EddystoneConfigService(ble, params, defaultAdvPowerLevels, radioPowerLevels);
00158     EddystoneBeaconConfig->setDefaultURIFrameData("http://physical-web.org",2);
00159     //EddystoneBeaconConfig->setDefaultUIDFrameData(&uidNamespaceID, &uidInstanceID,5);
00160     //EddystoneBeaconConfig->setDefaultTLMFrameData(tlmVersion,10);
00161     EddystoneBeaconConfig->start(!fetchedFromPersistentStorage);
00162     
00163     if (!EddystoneBeaconConfig->initSuccessfully()) {
00164         error("failed to accommodate URI");
00165     }
00166     if (!params.deepSleep) {
00167         ledRed = ledOn;
00168         configAdvertisementTimeout.attach(timeout, CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS);
00169         ble.gap().startAdvertising(); /* Set the whole thing in motion. After this call a GAP central can scan the EddystoneBeaconConfig
00170                                        * service. This can then be switched to the normal URIBeacon functionality after a timeout. */
00171         void pstorageSetup();
00172     }
00173     else {
00174         ledRed = ledOff;
00175     }
00176    
00177     while (true) {
00178         ble.waitForEvent();
00179         if (dirty) {
00180             saveURIBeaconConfigParams(&params);
00181         }
00182     }
00183 }