Button initiated config service
Dependencies: BLE_API_EddystoneConfigService_2 mbed nRF51822
Fork of BLE_EddystoneBeaconConfigService_3 by
main.cpp@68:f7f7ec038494, 2015-10-12 (annotated)
- Committer:
- scottjenson
- Date:
- Mon Oct 12 21:18:21 2015 +0000
- Revision:
- 68:f7f7ec038494
- Parent:
- 67:345bc62c748d
support for button initiated config (for nRFgo usb board and Seeed)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
screamer | 0:c04d932e96c9 | 1 | /* mbed Microcontroller Library |
screamer | 0:c04d932e96c9 | 2 | * Copyright (c) 2006-2013 ARM Limited |
screamer | 0:c04d932e96c9 | 3 | * |
screamer | 0:c04d932e96c9 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
screamer | 0:c04d932e96c9 | 5 | * you may not use this file except in compliance with the License. |
screamer | 0:c04d932e96c9 | 6 | * You may obtain a copy of the License at |
screamer | 0:c04d932e96c9 | 7 | * |
screamer | 0:c04d932e96c9 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
screamer | 0:c04d932e96c9 | 9 | * |
screamer | 0:c04d932e96c9 | 10 | * Unless required by applicable law or agreed to in writing, software |
screamer | 0:c04d932e96c9 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
screamer | 0:c04d932e96c9 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
screamer | 0:c04d932e96c9 | 13 | * See the License for the specific language governing permissions and |
screamer | 0:c04d932e96c9 | 14 | * limitations under the License. |
screamer | 0:c04d932e96c9 | 15 | */ |
screamer | 0:c04d932e96c9 | 16 | |
screamer | 0:c04d932e96c9 | 17 | #include "mbed.h" |
rgrover1 | 7:e9800c45e065 | 18 | #include "BLE.h" |
mbedAustin | 23:05e9bb3b13af | 19 | #include "EddystoneConfigService.h" |
mbedAustin | 34:5876fbb1aa62 | 20 | |
rgrover1 | 2:8020d6d4455a | 21 | #include "ConfigParamsPersistence.h" |
scottjenson | 67:345bc62c748d | 22 | //#include "BLEDevice.h" |
scottjenson | 67:345bc62c748d | 23 | #include "DeviceInformationService.h" |
screamer | 0:c04d932e96c9 | 24 | |
rgrover1 | 8:1a21308e5008 | 25 | BLE ble; |
mbedAustin | 24:8edfe6730cc2 | 26 | EddystoneConfigService *EddystoneBeaconConfig; |
mbedAustin | 39:2c73bc1ff4f5 | 27 | EddystoneConfigService::Params_t params; |
screamer | 0:c04d932e96c9 | 28 | |
scottjenson | 68:f7f7ec038494 | 29 | //Serial pc(USBTX,USBRX); // uncomment to use printf(...) |
scottjenson | 67:345bc62c748d | 30 | |
scottjenson | 67:345bc62c748d | 31 | #define TINYBLE false |
scottjenson | 67:345bc62c748d | 32 | #define SEEEDARCH true |
scottjenson | 67:345bc62c748d | 33 | |
scottjenson | 67:345bc62c748d | 34 | #if TINYBLE |
scottjenson | 67:345bc62c748d | 35 | int ledOn = 0; |
scottjenson | 67:345bc62c748d | 36 | int ledOff = 1; |
scottjenson | 67:345bc62c748d | 37 | |
scottjenson | 67:345bc62c748d | 38 | InterruptIn button1(P0_17); |
scottjenson | 67:345bc62c748d | 39 | DigitalOut ledRed(P0_22); |
scottjenson | 67:345bc62c748d | 40 | DigitalOut ledGreen(P0_21); |
scottjenson | 67:345bc62c748d | 41 | DigitalOut ledBlue(P0_23); |
scottjenson | 67:345bc62c748d | 42 | #endif |
scottjenson | 67:345bc62c748d | 43 | |
scottjenson | 67:345bc62c748d | 44 | #if SEEEDARCH |
scottjenson | 67:345bc62c748d | 45 | int ledOn = 1; |
scottjenson | 67:345bc62c748d | 46 | int ledOff = 0; |
scottjenson | 67:345bc62c748d | 47 | |
scottjenson | 68:f7f7ec038494 | 48 | InterruptIn button1(P0_18); |
scottjenson | 68:f7f7ec038494 | 49 | DigitalOut ledRed(P0_16); |
scottjenson | 68:f7f7ec038494 | 50 | DigitalOut ledGreen(P0_12); |
scottjenson | 68:f7f7ec038494 | 51 | DigitalOut ledBlue(P0_15); |
scottjenson | 67:345bc62c748d | 52 | #endif |
scottjenson | 67:345bc62c748d | 53 | |
scottjenson | 67:345bc62c748d | 54 | // Make sure to turn off before and after animation |
scottjenson | 67:345bc62c748d | 55 | // to separate it from the LED which may already be on |
scottjenson | 67:345bc62c748d | 56 | void ledRebootAnimation(void) { |
scottjenson | 67:345bc62c748d | 57 | ledRed = ledOff; |
scottjenson | 67:345bc62c748d | 58 | wait(0.1); |
scottjenson | 67:345bc62c748d | 59 | ledRed = ledOn; |
scottjenson | 67:345bc62c748d | 60 | wait(0.1); |
scottjenson | 67:345bc62c748d | 61 | ledRed = ledOff; |
scottjenson | 67:345bc62c748d | 62 | wait(0.1); |
scottjenson | 67:345bc62c748d | 63 | ledRed = ledOn; |
scottjenson | 67:345bc62c748d | 64 | wait(0.1); |
scottjenson | 67:345bc62c748d | 65 | ledRed = ledOff; |
scottjenson | 67:345bc62c748d | 66 | wait(0.1); |
scottjenson | 67:345bc62c748d | 67 | ledRed = ledOn; |
scottjenson | 67:345bc62c748d | 68 | wait(0.1); |
scottjenson | 67:345bc62c748d | 69 | ledRed = ledOff; |
scottjenson | 67:345bc62c748d | 70 | wait(0.1); |
scottjenson | 67:345bc62c748d | 71 | } |
scottjenson | 67:345bc62c748d | 72 | |
screamer | 0:c04d932e96c9 | 73 | /** |
screamer | 0:c04d932e96c9 | 74 | * URIBeaconConfig service can operate in two modes: a configuration mode which |
screamer | 0:c04d932e96c9 | 75 | * allows a user to update settings over a connection; and normal URIBeacon mode |
screamer | 0:c04d932e96c9 | 76 | * which involves advertising a URI. Constructing an object from URIBeaconConfig |
screamer | 0:c04d932e96c9 | 77 | * service sets up advertisements for the configuration mode. It is then up to |
screamer | 0:c04d932e96c9 | 78 | * the application to switch to URIBeacon mode based on some timeout. |
screamer | 0:c04d932e96c9 | 79 | * |
screamer | 0:c04d932e96c9 | 80 | * The following help with this switch. |
screamer | 0:c04d932e96c9 | 81 | */ |
scottjenson | 68:f7f7ec038494 | 82 | static const int CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS = 30; // Duration after power-on that config service is available. |
mbedAustin | 55:3818a9fa827d | 83 | |
mbedAustin | 24:8edfe6730cc2 | 84 | Ticker configAdvertisementTimeout; |
screamer | 0:c04d932e96c9 | 85 | |
screamer | 0:c04d932e96c9 | 86 | /** |
mbedAustin | 19:f7c33fa88ca5 | 87 | * Stop advertising the Config Service after a delay; and switch to a non-connectable advertising mode only beacon. |
screamer | 0:c04d932e96c9 | 88 | */ |
screamer | 0:c04d932e96c9 | 89 | void timeout(void) |
screamer | 0:c04d932e96c9 | 90 | { |
scottjenson | 67:345bc62c748d | 91 | ledRed = ledOff; |
screamer | 0:c04d932e96c9 | 92 | Gap::GapState_t state; |
screamer | 0:c04d932e96c9 | 93 | state = ble.getGapState(); |
screamer | 0:c04d932e96c9 | 94 | if (!state.connected) { /* don't switch if we're in a connected state. */ |
mbedAustin | 24:8edfe6730cc2 | 95 | configAdvertisementTimeout.detach(); /* disable the callback from the timeout Ticker. */ |
mbedAustin | 50:52a8b18d5bf1 | 96 | EddystoneBeaconConfig->setupEddystoneAdvertisements(); |
screamer | 0:c04d932e96c9 | 97 | } |
screamer | 0:c04d932e96c9 | 98 | } |
screamer | 0:c04d932e96c9 | 99 | |
screamer | 0:c04d932e96c9 | 100 | /** |
mbedAustin | 40:6f39aee31205 | 101 | * Callback triggered upon a disconnection event. |
screamer | 0:c04d932e96c9 | 102 | */ |
screamer | 0:c04d932e96c9 | 103 | void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) |
screamer | 0:c04d932e96c9 | 104 | { |
scottjenson | 67:345bc62c748d | 105 | ledRed = ledOff; |
mbedAustin | 39:2c73bc1ff4f5 | 106 | if (true == params.isConfigured){ |
mbedAustin | 39:2c73bc1ff4f5 | 107 | // end advertising, the beacon is configured |
mbedAustin | 39:2c73bc1ff4f5 | 108 | timeout(); |
mbedAustin | 39:2c73bc1ff4f5 | 109 | } |
mbedAustin | 39:2c73bc1ff4f5 | 110 | else{ |
mbedAustin | 40:6f39aee31205 | 111 | // eddystone is not configured, continue advertising |
mbedAustin | 39:2c73bc1ff4f5 | 112 | ble.gap().startAdvertising(); |
mbedAustin | 39:2c73bc1ff4f5 | 113 | } |
screamer | 0:c04d932e96c9 | 114 | } |
scottjenson | 67:345bc62c748d | 115 | int reboot = false; // global used later to reboot the beacon |
scottjenson | 67:345bc62c748d | 116 | int dirty = false; // global used to mark params is dirty and needs to be saved |
scottjenson | 67:345bc62c748d | 117 | |
scottjenson | 67:345bc62c748d | 118 | void handle_button1() { |
scottjenson | 67:345bc62c748d | 119 | ble.gap().stopAdvertising(); |
scottjenson | 67:345bc62c748d | 120 | params.deepSleep = !params.deepSleep; |
scottjenson | 67:345bc62c748d | 121 | dirty = true; |
scottjenson | 67:345bc62c748d | 122 | } |
scottjenson | 67:345bc62c748d | 123 | |
scottjenson | 67:345bc62c748d | 124 | extern void pstorageSetup(); |
screamer | 0:c04d932e96c9 | 125 | |
screamer | 0:c04d932e96c9 | 126 | int main(void) |
screamer | 0:c04d932e96c9 | 127 | { |
scottjenson | 67:345bc62c748d | 128 | ledRed = ledOff; |
scottjenson | 67:345bc62c748d | 129 | ledGreen = ledOff; |
scottjenson | 67:345bc62c748d | 130 | ledBlue = ledOff; |
screamer | 0:c04d932e96c9 | 131 | ble.init(); |
rgrover1 | 8:1a21308e5008 | 132 | ble.gap().onDisconnection(disconnectionCallback); |
screamer | 0:c04d932e96c9 | 133 | |
scottjenson | 67:345bc62c748d | 134 | // Initialize button1 and pull up |
scottjenson | 67:345bc62c748d | 135 | // set interrupt callback for button1 |
scottjenson | 67:345bc62c748d | 136 | button1.fall(&handle_button1); |
scottjenson | 67:345bc62c748d | 137 | button1.mode(PullUp); |
scottjenson | 67:345bc62c748d | 138 | |
screamer | 0:c04d932e96c9 | 139 | /* |
screamer | 0:c04d932e96c9 | 140 | * Load parameters from (platform specific) persistent storage. Parameters |
screamer | 0:c04d932e96c9 | 141 | * can be set to non-default values while the URIBeacon is in configuration |
screamer | 0:c04d932e96c9 | 142 | * mode (within the first 60 seconds of power-up). Thereafter, parameters |
screamer | 0:c04d932e96c9 | 143 | * get copied out to persistent storage before switching to normal URIBeacon |
screamer | 0:c04d932e96c9 | 144 | * operation. |
screamer | 0:c04d932e96c9 | 145 | */ |
rgrover1 | 2:8020d6d4455a | 146 | bool fetchedFromPersistentStorage = loadURIBeaconConfigParams(¶ms); |
mbedAustin | 44:0e27ee7800b8 | 147 | |
scottjenson | 67:345bc62c748d | 148 | // only setup beacon if device is NOT in deepSleep |
mbedAustin | 44:0e27ee7800b8 | 149 | // Set UID and TLM frame data |
scottjenson | 67:345bc62c748d | 150 | //EddystoneConfigService::UIDNamespaceID_t uidNamespaceID = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}; // 10Byte Namespace UUID |
scottjenson | 67:345bc62c748d | 151 | //EddystoneConfigService::UIDInstanceID_t uidInstanceID = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; // 6Byte Instance ID |
scottjenson | 67:345bc62c748d | 152 | //uint8_t tlmVersion = 0x00; |
mbedAustin | 31:11e7a505a4be | 153 | |
mbedAustin | 24:8edfe6730cc2 | 154 | /* Initialize a EddystoneBeaconConfig service providing config params, default URI, and power levels. */ |
scottjenson | 68:f7f7ec038494 | 155 | static EddystoneConfigService::PowerLevels_t defaultAdvPowerLevels = {-48, -41, -35, -26}; // Values for ADV packets related to firmware levels, calibrated based on measured values at 1m |
scottjenson | 68:f7f7ec038494 | 156 | static EddystoneConfigService::PowerLevels_t radioPowerLevels = {-20, -12, -4, 4}; // Values for radio power levels, provided by manufacturer. |
mbedAustin | 55:3818a9fa827d | 157 | EddystoneBeaconConfig = new EddystoneConfigService(ble, params, defaultAdvPowerLevels, radioPowerLevels); |
scottjenson | 68:f7f7ec038494 | 158 | EddystoneBeaconConfig->setDefaultURIFrameData("http://physical-web.org",2); |
scottjenson | 67:345bc62c748d | 159 | //EddystoneBeaconConfig->setDefaultUIDFrameData(&uidNamespaceID, &uidInstanceID,5); |
scottjenson | 67:345bc62c748d | 160 | //EddystoneBeaconConfig->setDefaultTLMFrameData(tlmVersion,10); |
mbedAustin | 44:0e27ee7800b8 | 161 | EddystoneBeaconConfig->start(!fetchedFromPersistentStorage); |
mbedAustin | 44:0e27ee7800b8 | 162 | |
mbedAustin | 39:2c73bc1ff4f5 | 163 | if (!EddystoneBeaconConfig->initSuccessfully()) { |
screamer | 0:c04d932e96c9 | 164 | error("failed to accommodate URI"); |
screamer | 0:c04d932e96c9 | 165 | } |
scottjenson | 67:345bc62c748d | 166 | if (!params.deepSleep) { |
scottjenson | 67:345bc62c748d | 167 | ledRed = ledOn; |
scottjenson | 67:345bc62c748d | 168 | configAdvertisementTimeout.attach(timeout, CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS); |
scottjenson | 67:345bc62c748d | 169 | ble.gap().startAdvertising(); /* Set the whole thing in motion. After this call a GAP central can scan the EddystoneBeaconConfig |
scottjenson | 67:345bc62c748d | 170 | * service. This can then be switched to the normal URIBeacon functionality after a timeout. */ |
scottjenson | 67:345bc62c748d | 171 | void pstorageSetup(); |
scottjenson | 67:345bc62c748d | 172 | } |
scottjenson | 67:345bc62c748d | 173 | else { |
scottjenson | 67:345bc62c748d | 174 | ledRed = ledOff; |
scottjenson | 67:345bc62c748d | 175 | } |
scottjenson | 67:345bc62c748d | 176 | |
screamer | 0:c04d932e96c9 | 177 | while (true) { |
screamer | 0:c04d932e96c9 | 178 | ble.waitForEvent(); |
scottjenson | 67:345bc62c748d | 179 | if (dirty) { |
scottjenson | 67:345bc62c748d | 180 | saveURIBeaconConfigParams(¶ms); |
scottjenson | 67:345bc62c748d | 181 | } |
screamer | 0:c04d932e96c9 | 182 | } |
screamer | 0:c04d932e96c9 | 183 | } |