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 Austin Blackstone

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

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?

UserRevisionLine numberNew 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 &paramsIn,
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__ */