Run on TY51822r3 board with ACC sensor (LIS3DH or BMC050)

Dependencies:   BLE_API LIS3DH mbed nRF51822 BMC050 nRF51_LowPwr nRF51_Vdd

Fork of BLE_EddystoneBeacon_Service by Bluetooth Low Energy

Committer:
kenjiArai
Date:
Sat Jun 11 01:51:59 2016 +0000
Revision:
37:ea459e6c6a35
Parent:
34:f6d4a699a1ea
Added low power mode (use nRF51_LowPwr library) for reduce Idle Current

Who changed what in which revision?

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