The eddystone config service allows you to configure the eddystone frame data over BLE for a set period of time and then starts an eddystone beacon. This example defaults to 30 seconds of config time.
Dependencies: BLE_API mbed nRF51822 X_NUCLEO_IDB0XA1
Fork of BLE_EddystoneBeaconConfigServiceRelease by
This is the eddystone config service. This code starts up and for a user configured time period (default 30 seconds) will advertise the configuration service.
The configuration service allows for modifying various frames of the eddystone specification.
For more details on the Configuration Service please see : https://github.com/google/eddystone/blob/master/eddystone-url/docs/config-service-spec.md
EddystoneService.h@8:f53d48e5d64f, 2016-09-20 (annotated)
- Committer:
- Vincent Coubard
- Date:
- Tue Sep 20 14:21:04 2016 +0100
- Revision:
- 8:f53d48e5d64f
- Parent:
- 6:321047f0190a
Update libraries and add support of ST shield.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andresag | 6:321047f0190a | 1 | /* mbed Microcontroller Library |
andresag | 6:321047f0190a | 2 | * Copyright (c) 2006-2015 ARM Limited |
andresag | 6:321047f0190a | 3 | * |
andresag | 6:321047f0190a | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
andresag | 6:321047f0190a | 5 | * you may not use this file except in compliance with the License. |
andresag | 6:321047f0190a | 6 | * You may obtain a copy of the License at |
andresag | 6:321047f0190a | 7 | * |
andresag | 6:321047f0190a | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
andresag | 6:321047f0190a | 9 | * |
andresag | 6:321047f0190a | 10 | * Unless required by applicable law or agreed to in writing, software |
andresag | 6:321047f0190a | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
andresag | 6:321047f0190a | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
andresag | 6:321047f0190a | 13 | * See the License for the specific language governing permissions and |
andresag | 6:321047f0190a | 14 | * limitations under the License. |
andresag | 6:321047f0190a | 15 | */ |
andresag | 6:321047f0190a | 16 | |
andresag | 6:321047f0190a | 17 | #ifndef __EDDYSTONESERVICE_H__ |
andresag | 6:321047f0190a | 18 | #define __EDDYSTONESERVICE_H__ |
andresag | 6:321047f0190a | 19 | |
andresag | 6:321047f0190a | 20 | #include "ble/BLE.h" |
andresag | 6:321047f0190a | 21 | #include "EddystoneTypes.h" |
andresag | 6:321047f0190a | 22 | #include "URLFrame.h" |
andresag | 6:321047f0190a | 23 | #include "UIDFrame.h" |
andresag | 6:321047f0190a | 24 | #include "TLMFrame.h" |
andresag | 6:321047f0190a | 25 | #include <string.h> |
andresag | 6:321047f0190a | 26 | #ifdef YOTTA_CFG_MBED_OS |
andresag | 6:321047f0190a | 27 | #include "mbed-drivers/mbed.h" |
andresag | 6:321047f0190a | 28 | #else |
andresag | 6:321047f0190a | 29 | #include "mbed.h" |
andresag | 6:321047f0190a | 30 | #endif |
andresag | 6:321047f0190a | 31 | |
andresag | 6:321047f0190a | 32 | class EddystoneService |
andresag | 6:321047f0190a | 33 | { |
andresag | 6:321047f0190a | 34 | public: |
andresag | 6:321047f0190a | 35 | static const uint16_t TOTAL_CHARACTERISTICS = 9; |
andresag | 6:321047f0190a | 36 | |
andresag | 6:321047f0190a | 37 | static const uint32_t DEFAULT_CONFIG_PERIOD_MSEC = 1000; |
andresag | 6:321047f0190a | 38 | static const uint16_t DEFAULT_BEACON_PERIOD_MSEC = 1000; |
andresag | 6:321047f0190a | 39 | |
andresag | 6:321047f0190a | 40 | /* Operation modes of the EddystoneService: |
andresag | 6:321047f0190a | 41 | * NONE: EddystoneService has been initialised but no memory has been |
andresag | 6:321047f0190a | 42 | * dynamically allocated. Additionally, no services are running |
andresag | 6:321047f0190a | 43 | * nothing is being advertised. |
andresag | 6:321047f0190a | 44 | * CONFIG: EddystoneService has been initialised, the configuration |
andresag | 6:321047f0190a | 45 | * service started and memory has been allocated for BLE |
andresag | 6:321047f0190a | 46 | * characteristics. Memory consumption peaks during CONFIG |
andresag | 6:321047f0190a | 47 | * mode. |
andresag | 6:321047f0190a | 48 | * BEACON: Eddystone service is running as a beacon advertising URL, |
andresag | 6:321047f0190a | 49 | * UID and/or TLM frames depending on how it is configured. |
andresag | 6:321047f0190a | 50 | * Note: The main app can change the mode of EddystoneService at any point |
andresag | 6:321047f0190a | 51 | * of time by calling startConfigService() or startBeaconService(). |
andresag | 6:321047f0190a | 52 | * Resources from the previous mode will be freed. It is currently NOT |
andresag | 6:321047f0190a | 53 | * possible to force EddystoneService back into MODE_NONE. |
andresag | 6:321047f0190a | 54 | */ |
andresag | 6:321047f0190a | 55 | enum OperationModes { |
andresag | 6:321047f0190a | 56 | EDDYSTONE_MODE_NONE, |
andresag | 6:321047f0190a | 57 | EDDYSTONE_MODE_CONFIG, |
andresag | 6:321047f0190a | 58 | EDDYSTONE_MODE_BEACON |
andresag | 6:321047f0190a | 59 | }; |
andresag | 6:321047f0190a | 60 | |
andresag | 6:321047f0190a | 61 | struct EddystoneParams_t { |
andresag | 6:321047f0190a | 62 | bool lockState; |
andresag | 6:321047f0190a | 63 | Lock_t lock; |
andresag | 6:321047f0190a | 64 | Lock_t unlock; |
andresag | 6:321047f0190a | 65 | uint8_t flags; |
andresag | 6:321047f0190a | 66 | PowerLevels_t advPowerLevels; |
andresag | 6:321047f0190a | 67 | uint8_t txPowerMode; |
andresag | 6:321047f0190a | 68 | uint16_t beaconPeriod; |
andresag | 6:321047f0190a | 69 | uint8_t tlmVersion; |
andresag | 6:321047f0190a | 70 | uint8_t urlDataLength; |
andresag | 6:321047f0190a | 71 | UrlData_t urlData; |
andresag | 6:321047f0190a | 72 | UIDNamespaceID_t uidNamespaceID; |
andresag | 6:321047f0190a | 73 | UIDInstanceID_t uidInstanceID; |
andresag | 6:321047f0190a | 74 | }; |
andresag | 6:321047f0190a | 75 | |
andresag | 6:321047f0190a | 76 | enum EddystoneError_t { |
andresag | 6:321047f0190a | 77 | EDDYSTONE_ERROR_NONE, |
andresag | 6:321047f0190a | 78 | EDDYSTONE_ERROR_INVALID_BEACON_PERIOD, |
andresag | 6:321047f0190a | 79 | EDDYSTONE_ERROR_INVALID_CONSEC_FRAMES, |
andresag | 6:321047f0190a | 80 | EDDYSTONE_ERROR_INVALID_ADVERTISING_INTERVAL |
andresag | 6:321047f0190a | 81 | }; |
andresag | 6:321047f0190a | 82 | |
andresag | 6:321047f0190a | 83 | enum FrameType { |
andresag | 6:321047f0190a | 84 | EDDYSTONE_FRAME_URL, |
andresag | 6:321047f0190a | 85 | EDDYSTONE_FRAME_UID, |
andresag | 6:321047f0190a | 86 | EDDYSTONE_FRAME_TLM, |
andresag | 6:321047f0190a | 87 | NUM_EDDYSTONE_FRAMES |
andresag | 6:321047f0190a | 88 | }; |
andresag | 6:321047f0190a | 89 | |
andresag | 6:321047f0190a | 90 | /* Initialise the EddystoneService using parameters from persistent storage */ |
andresag | 6:321047f0190a | 91 | EddystoneService(BLE &bleIn, |
andresag | 6:321047f0190a | 92 | EddystoneParams_t ¶msIn, |
andresag | 6:321047f0190a | 93 | const PowerLevels_t &advPowerLevelsIn, |
andresag | 6:321047f0190a | 94 | const PowerLevels_t &radioPowerLevelsIn, |
andresag | 6:321047f0190a | 95 | uint32_t advConfigIntervalIn = DEFAULT_CONFIG_PERIOD_MSEC); |
andresag | 6:321047f0190a | 96 | |
andresag | 6:321047f0190a | 97 | /* When using this constructor we need to call setURLData, |
andresag | 6:321047f0190a | 98 | * setTMLData and setUIDData to initialise values manually |
andresag | 6:321047f0190a | 99 | */ |
andresag | 6:321047f0190a | 100 | EddystoneService(BLE &bleIn, |
andresag | 6:321047f0190a | 101 | const PowerLevels_t &advPowerLevelsIn, |
andresag | 6:321047f0190a | 102 | const PowerLevels_t &radioPowerLevelsIn, |
andresag | 6:321047f0190a | 103 | uint32_t advConfigIntervalIn = DEFAULT_CONFIG_PERIOD_MSEC); |
andresag | 6:321047f0190a | 104 | |
andresag | 6:321047f0190a | 105 | /* Setup callback to update BatteryVoltage in TLM frame */ |
andresag | 6:321047f0190a | 106 | void onTLMBatteryVoltageUpdate(TlmUpdateCallback_t tlmBatteryVoltageCallbackIn); |
andresag | 6:321047f0190a | 107 | |
andresag | 6:321047f0190a | 108 | /* Setup callback to update BeaconTemperature in TLM frame */ |
andresag | 6:321047f0190a | 109 | void onTLMBeaconTemperatureUpdate(TlmUpdateCallback_t tlmBeaconTemperatureCallbackIn); |
andresag | 6:321047f0190a | 110 | |
andresag | 6:321047f0190a | 111 | void setTLMData(uint8_t tlmVersionIn = 0); |
andresag | 6:321047f0190a | 112 | |
andresag | 6:321047f0190a | 113 | void setURLData(const char *urlDataIn); |
andresag | 6:321047f0190a | 114 | |
andresag | 6:321047f0190a | 115 | void setUIDData(const UIDNamespaceID_t *uidNamespaceIDIn, const UIDInstanceID_t *uidInstanceIDIn); |
andresag | 6:321047f0190a | 116 | |
andresag | 6:321047f0190a | 117 | EddystoneError_t startConfigService(void); |
andresag | 6:321047f0190a | 118 | |
andresag | 6:321047f0190a | 119 | EddystoneError_t startBeaconService(uint16_t consecUrlFramesIn = 2, uint16_t consecUidFramesIn = 2, uint16_t consecTlmFramesIn = 2); |
andresag | 6:321047f0190a | 120 | |
andresag | 6:321047f0190a | 121 | /* It is not the responsibility of the Eddystone implementation to store |
andresag | 6:321047f0190a | 122 | * the configured parameters in persistent storage since this is |
andresag | 6:321047f0190a | 123 | * platform-specific. So we provide this function that returns the |
andresag | 6:321047f0190a | 124 | * configured values that need to be stored and the main application |
andresag | 6:321047f0190a | 125 | * takes care of storing them. |
andresag | 6:321047f0190a | 126 | */ |
andresag | 6:321047f0190a | 127 | void getEddystoneParams(EddystoneParams_t *params); |
andresag | 6:321047f0190a | 128 | |
andresag | 6:321047f0190a | 129 | private: |
andresag | 6:321047f0190a | 130 | /* Helper function used only once during constructing the object to avoid |
andresag | 6:321047f0190a | 131 | * duplicated code. |
andresag | 6:321047f0190a | 132 | */ |
andresag | 6:321047f0190a | 133 | void eddystoneConstructorHelper(const PowerLevels_t &advPowerLevelsIn, |
andresag | 6:321047f0190a | 134 | const PowerLevels_t &radioPowerLevelsIn, |
andresag | 6:321047f0190a | 135 | uint32_t advConfigIntervalIn); |
andresag | 6:321047f0190a | 136 | |
andresag | 6:321047f0190a | 137 | /* When changing modes, we shutdown and init the BLE instance, so |
andresag | 6:321047f0190a | 138 | * this is needed to complete the initialisation task. |
andresag | 6:321047f0190a | 139 | */ |
andresag | 6:321047f0190a | 140 | void bleInitComplete(BLE::InitializationCompleteCallbackContext* initContext); |
andresag | 6:321047f0190a | 141 | |
andresag | 6:321047f0190a | 142 | void swapAdvertisedFrame(void); |
andresag | 6:321047f0190a | 143 | |
andresag | 6:321047f0190a | 144 | void updateAdvertisementPacket(const uint8_t* rawFrame, size_t rawFrameLength); |
andresag | 6:321047f0190a | 145 | |
andresag | 6:321047f0190a | 146 | /* Helper function that calls user-defined functions to update Battery Voltage and Temperature (if available), |
andresag | 6:321047f0190a | 147 | * then updates the raw frame data and finally updates the actual advertised packet. This operation must be |
andresag | 6:321047f0190a | 148 | * done fairly often because the TLM frame TimeSinceBoot must have a 0.1 secs resolution according to the |
andresag | 6:321047f0190a | 149 | * Eddystone specification. |
andresag | 6:321047f0190a | 150 | */ |
andresag | 6:321047f0190a | 151 | void updateRawTLMFrame(void); |
andresag | 6:321047f0190a | 152 | |
andresag | 6:321047f0190a | 153 | void setupBeaconService(void); |
andresag | 6:321047f0190a | 154 | |
andresag | 6:321047f0190a | 155 | void setupConfigService(void); |
andresag | 6:321047f0190a | 156 | |
andresag | 6:321047f0190a | 157 | void freeConfigCharacteristics(void); |
andresag | 6:321047f0190a | 158 | |
andresag | 6:321047f0190a | 159 | void freeBeaconFrames(void); |
andresag | 6:321047f0190a | 160 | |
andresag | 6:321047f0190a | 161 | void radioNotificationCallback(bool radioActive); |
andresag | 6:321047f0190a | 162 | |
andresag | 6:321047f0190a | 163 | /* |
andresag | 6:321047f0190a | 164 | * Internal helper function used to update the GATT database following any |
andresag | 6:321047f0190a | 165 | * change to the internal state of the service object. |
andresag | 6:321047f0190a | 166 | */ |
andresag | 6:321047f0190a | 167 | void updateCharacteristicValues(void); |
andresag | 6:321047f0190a | 168 | |
andresag | 6:321047f0190a | 169 | void setupEddystoneConfigAdvertisements(void); |
andresag | 6:321047f0190a | 170 | |
andresag | 6:321047f0190a | 171 | void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams); |
andresag | 6:321047f0190a | 172 | |
andresag | 6:321047f0190a | 173 | void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams); |
andresag | 6:321047f0190a | 174 | |
andresag | 6:321047f0190a | 175 | void urlDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams); |
andresag | 6:321047f0190a | 176 | |
andresag | 6:321047f0190a | 177 | void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams); |
andresag | 6:321047f0190a | 178 | |
andresag | 6:321047f0190a | 179 | template <typename T> |
andresag | 6:321047f0190a | 180 | void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams); |
andresag | 6:321047f0190a | 181 | |
andresag | 6:321047f0190a | 182 | /* |
andresag | 6:321047f0190a | 183 | * This callback is invoked when a GATT client attempts to modify any of the |
andresag | 6:321047f0190a | 184 | * characteristics of this service. Attempts to do so are also applied to |
andresag | 6:321047f0190a | 185 | * the internal state of this service object. |
andresag | 6:321047f0190a | 186 | */ |
andresag | 6:321047f0190a | 187 | void onDataWrittenCallback(const GattWriteCallbackParams *writeParams); |
andresag | 6:321047f0190a | 188 | |
andresag | 6:321047f0190a | 189 | uint16_t correctAdvertisementPeriod(uint16_t beaconPeriodIn) const; |
andresag | 6:321047f0190a | 190 | |
andresag | 6:321047f0190a | 191 | BLE &ble; |
andresag | 6:321047f0190a | 192 | uint32_t advConfigInterval; |
andresag | 6:321047f0190a | 193 | uint8_t operationMode; |
andresag | 6:321047f0190a | 194 | |
andresag | 6:321047f0190a | 195 | URLFrame urlFrame; |
andresag | 6:321047f0190a | 196 | UIDFrame uidFrame; |
andresag | 6:321047f0190a | 197 | TLMFrame tlmFrame; |
andresag | 6:321047f0190a | 198 | |
andresag | 6:321047f0190a | 199 | PowerLevels_t radioPowerLevels; |
andresag | 6:321047f0190a | 200 | PowerLevels_t advPowerLevels; |
andresag | 6:321047f0190a | 201 | bool lockState; |
andresag | 6:321047f0190a | 202 | bool resetFlag; |
andresag | 6:321047f0190a | 203 | Lock_t lock; |
andresag | 6:321047f0190a | 204 | Lock_t unlock; |
andresag | 6:321047f0190a | 205 | uint8_t flags; |
andresag | 6:321047f0190a | 206 | uint8_t txPowerMode; |
andresag | 6:321047f0190a | 207 | uint16_t beaconPeriod; |
andresag | 6:321047f0190a | 208 | |
andresag | 6:321047f0190a | 209 | ReadOnlyGattCharacteristic<bool> *lockStateChar; |
andresag | 6:321047f0190a | 210 | WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(Lock_t)> *lockChar; |
andresag | 6:321047f0190a | 211 | WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(Lock_t)> *unlockChar; |
andresag | 6:321047f0190a | 212 | GattCharacteristic *urlDataChar; |
andresag | 6:321047f0190a | 213 | ReadWriteGattCharacteristic<uint8_t> *flagsChar; |
andresag | 6:321047f0190a | 214 | ReadWriteArrayGattCharacteristic<int8_t, sizeof(PowerLevels_t)> *advPowerLevelsChar; |
andresag | 6:321047f0190a | 215 | ReadWriteGattCharacteristic<uint8_t> *txPowerModeChar; |
andresag | 6:321047f0190a | 216 | ReadWriteGattCharacteristic<uint16_t> *beaconPeriodChar; |
andresag | 6:321047f0190a | 217 | WriteOnlyGattCharacteristic<bool> *resetChar; |
andresag | 6:321047f0190a | 218 | |
andresag | 6:321047f0190a | 219 | uint8_t *rawUrlFrame; |
andresag | 6:321047f0190a | 220 | uint8_t *rawUidFrame; |
andresag | 6:321047f0190a | 221 | uint8_t *rawTlmFrame; |
andresag | 6:321047f0190a | 222 | |
andresag | 6:321047f0190a | 223 | uint16_t consecFrames[NUM_EDDYSTONE_FRAMES]; |
andresag | 6:321047f0190a | 224 | uint16_t currentConsecFrames[NUM_EDDYSTONE_FRAMES]; |
andresag | 6:321047f0190a | 225 | uint8_t currentAdvertisedFrame; |
andresag | 6:321047f0190a | 226 | |
andresag | 6:321047f0190a | 227 | TlmUpdateCallback_t tlmBatteryVoltageCallback; |
andresag | 6:321047f0190a | 228 | TlmUpdateCallback_t tlmBeaconTemperatureCallback; |
andresag | 6:321047f0190a | 229 | |
andresag | 6:321047f0190a | 230 | Timer timeSinceBootTimer; |
andresag | 6:321047f0190a | 231 | #ifndef YOTTA_CFG_MBED_OS |
andresag | 6:321047f0190a | 232 | Timeout swapAdvertisedFrameTimeout; |
andresag | 6:321047f0190a | 233 | #endif |
andresag | 6:321047f0190a | 234 | |
andresag | 6:321047f0190a | 235 | GattCharacteristic *charTable[TOTAL_CHARACTERISTICS]; |
andresag | 6:321047f0190a | 236 | }; |
andresag | 6:321047f0190a | 237 | |
andresag | 6:321047f0190a | 238 | #endif /* __EDDYSTONESERVICE_H__ */ |