Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
EddystoneService.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 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 #ifndef __EDDYSTONESERVICE_H__ 00018 #define __EDDYSTONESERVICE_H__ 00019 // 00020 // 2016-03 Eddystone Unified GATT 00021 // 00022 #include "EventQueue/EventQueue.h" 00023 #include "ble/BLE.h" 00024 #include "EddystoneTypes.h" 00025 #include "UIDFrame.h" 00026 #include "URLFrame.h" 00027 #include "TLMFrame.h" 00028 #include "EIDFrame.h" 00029 #include <string.h> 00030 #include "mbedtls/aes.h" 00031 #include "mbedtls/entropy.h" 00032 #include "mbedtls/ctr_drbg.h" 00033 00034 #ifdef YOTTA_CFG_MBED_OS 00035 #include "mbed-drivers/mbed.h" 00036 #include "mbed-drivers/CircularBuffer.h" 00037 #else 00038 #include "mbed.h" 00039 #include "CircularBuffer.h" 00040 #endif 00041 00042 #include "stdio.h" 00043 #include "Eddystone_config.h" 00044 00045 /** 00046 * This class implements the Eddystone-URL Config Service and the Eddystone 00047 * Protocol Specification as defined in the publicly available specification at 00048 * https://github.com/google/eddystone/blob/master/protocol-specification.md. 00049 */ 00050 class EddystoneService 00051 { 00052 public: 00053 /** 00054 * Total number of GATT Characteristics in the Eddystonei-URL Configuration 00055 * Service. 00056 */ 00057 static const uint16_t TOTAL_CHARACTERISTICS = 12; 00058 00059 /** 00060 * Max data that can be written to the data characteristic 00061 */ 00062 static const uint8_t MAX_DATA_WRITE = 34; // FrameType+32B(IdentityKey)+Exp 00063 00064 /** 00065 * Default interval for advertising packets for the Eddystone-URL 00066 * Configuration Service. 00067 */ 00068 static const uint32_t DEFAULT_CONFIG_PERIOD_MSEC = EDDYSTONE_DEFAULT_CONFIG_ADV_INTERVAL; 00069 00070 /** 00071 * Enumeration that defines the various operation modes of the 00072 * EddystoneService. 00073 * 00074 * @note The main app can change the mode of EddystoneService at any point 00075 * of time by calling startConfigService() or startBeaconService(). 00076 * Resources from the previous mode will be freed. 00077 * 00078 * @note It is currently NOT possible to force EddystoneService back into 00079 * EDDYSTONE_MODE_NONE. 00080 */ 00081 enum OperationModes { 00082 /** 00083 * NONE: EddystoneService has been initialized but no memory has been 00084 * dynamically allocated. Additionally, no services are running 00085 * nothing is being advertised. 00086 */ 00087 EDDYSTONE_MODE_NONE, 00088 /** 00089 * CONFIG: EddystoneService has been initialized, the configuration 00090 * service started and memory has been allocated for BLE 00091 * characteristics. Memory consumption peaks during CONFIG 00092 * mode. 00093 */ 00094 EDDYSTONE_MODE_CONFIG, 00095 /** 00096 * BEACON: Eddystone service is running as a beacon advertising URL, 00097 * UID and/or TLM frames depending on how it is configured. 00098 */ 00099 EDDYSTONE_MODE_BEACON 00100 }; 00101 00102 /** 00103 * Structure that encapsulates the Eddystone configuration parameters. This 00104 * structure is particularly useful when storing the parameters to 00105 * persistent storage. 00106 */ 00107 struct EddystoneParams_t { 00108 /** 00109 * A buffer describing the capabilities of the beacon 00110 */ 00111 Capability_t capabilities; 00112 00113 /** 00114 * Defines the slot that advInterval, radioPower, advPower, advSlotData operate on 00115 */ 00116 uint8_t activeSlot; 00117 00118 /** 00119 * The Beacon interval for each beacon slot 00120 * 00121 * @note A value of zero disables Eddystone-URL frame trasmissions. 00122 */ 00123 SlotAdvIntervals_t slotAdvIntervals; 00124 00125 /** 00126 * The Radio TX Powers supported by this beacon 00127 */ 00128 PowerLevels_t radioTxPowerLevels; 00129 00130 /** 00131 * The Radio TX Power set for each slot 00132 */ 00133 SlotTxPowerLevels_t slotRadioTxPowerLevels; 00134 00135 /** 00136 * The Calibrated Adv TX Powers supported by this beacon (one for each radio power) 00137 */ 00138 PowerLevels_t advTxPowerLevels; 00139 00140 /** 00141 * The Adv TX Power set for each slot 00142 */ 00143 SlotTxPowerLevels_t slotAdvTxPowerLevels; 00144 00145 /** 00146 * The value of the Eddystone-URL Configuration Service Lock State 00147 * characteristic. 00148 */ 00149 uint8_t lockState; 00150 00151 /** 00152 * The value of the Eddystone-URL Configuration Service Unlock 00153 * characteristic that can be used to unlock the beacon and clear the 00154 * single-use lock-code. 00155 */ 00156 Lock_t unlockToken; 00157 00158 /** 00159 * An array holding the 128-bit unlockKey (big endian) 00160 */ 00161 Lock_t unlockKey; 00162 00163 /** 00164 * An array holding the 128-bit challenge (big endian) in the 00165 * challenge/response unlock protocol 00166 */ 00167 Lock_t challenge; 00168 00169 /** 00170 * EID: An array holding the 256-bit private Ecdh Key (big endian) 00171 */ 00172 //PrivateEcdhKey_t privateEcdhKey; 00173 00174 /** 00175 * EID: An array holding the 256-bit public Ecdh Key (big endian) 00176 */ 00177 //PublicEcdhKey_t publicEcdhKey; 00178 00179 /** 00180 * EID: An array holding the slot next rotation times 00181 */ 00182 //SlotEidNextRotationTimes_t slotEidNextRotationTimes; 00183 00184 /** 00185 * EID: An array holding the slot rotation period exponents 00186 */ 00187 SlotEidRotationPeriodExps_t slotEidRotationPeriodExps; 00188 00189 /** 00190 * EID: An array holding the slot 128-bit EID Identity Key (big endian) 00191 */ 00192 SlotEidIdentityKeys_t slotEidIdentityKeys; 00193 00194 /** 00195 * Specifies the type of each frame indexed by slot 00196 */ 00197 SlotFrameTypes_t slotFrameTypes; 00198 00199 /** 00200 * A buffer that contains all slot frames, 32-bytes allocated to each frame 00201 */ 00202 SlotStorage_t slotStorage; 00203 00204 /** 00205 * The state of the recently invoked Factory Reset characteristic 00206 */ 00207 uint8_t factoryReset; 00208 00209 /** 00210 * The state of the recently invoked Remain Connectable characteristic 00211 */ 00212 uint8_t remainConnectable; 00213 }; 00214 00215 /** 00216 * Enumeration that defines the various error codes for EddystoneService. 00217 */ 00218 enum EddystoneError_t { 00219 /** 00220 * No error occurred. 00221 */ 00222 EDDYSTONE_ERROR_NONE, 00223 /** 00224 * The supplied advertising interval is invalid. The interval may be 00225 * too short/long for the type of advertising packets being broadcast. 00226 * 00227 * @note For the acceptable range of advertising interval refer to the 00228 * following functions in mbed BLE API: 00229 * - Gap::getMinNonConnectableAdvertisingInterval() 00230 * - Gap::getMinAdvertisingInterval() 00231 * - Gap::getMaxAdvertisingInterval() 00232 */ 00233 EDDYSTONE_ERROR_INVALID_ADVERTISING_INTERVAL, 00234 /** 00235 * The result of executing a call when the the EddystoneService is in 00236 * the incorrect operation mode. 00237 */ 00238 EDDYSTONE_ERROR_INVALID_STATE 00239 }; 00240 00241 /** 00242 * Enumeration that defines the available frame types within Eddystone 00243 * advertising packets. 00244 */ 00245 enum FrameType { 00246 /** 00247 * The Eddystone-UID frame. Refer to 00248 * https://github.com/google/eddystone/tree/master/eddystone-uid. 00249 */ 00250 EDDYSTONE_FRAME_UID, 00251 /** 00252 * The Eddystone-URL frame. Refer to 00253 * https://github.com/google/eddystone/tree/master/eddystone-url. 00254 */ 00255 EDDYSTONE_FRAME_URL, 00256 /** 00257 * The Eddystone-TLM frame. Refer to 00258 * https://github.com/google/eddystone/tree/master/eddystone-tlm. 00259 */ 00260 EDDYSTONE_FRAME_TLM, 00261 /** 00262 * The Eddystone-EID frame. Refer to 00263 * https://github.com/google/eddystone/tree/master/eddystone-eid. 00264 */ 00265 EDDYSTONE_FRAME_EID, 00266 /** 00267 * The total number Eddystone frame types. 00268 */ 00269 NUM_EDDYSTONE_FRAMES 00270 }; 00271 00272 typedef eq::EventQueue event_queue_t; 00273 00274 /** 00275 * Constructor that Initializes the EddystoneService using parameters from 00276 * the supplied EddystoneParams_t. This constructor is particularly useful 00277 * for configuring the EddystoneService with parameters fetched from 00278 * persistent storage. 00279 * 00280 * @param[in] bleIn 00281 * The BLE instance. 00282 * @param[in] paramIn 00283 * The input Eddystone configuration parameters. 00284 * @param[in] radioPowerLevelsIn 00285 * The value set internally into the radion tx power. 00286 * @param[in] eventQueue 00287 * The event queue used by the service to schedule tasks. 00288 * @param[in] advConfigIntervalIn 00289 * The advertising interval for advertising packets of the 00290 * Eddystone-URL Configuration Service. 00291 */ 00292 EddystoneService(BLE &bleIn, 00293 EddystoneParams_t ¶msIn, 00294 const PowerLevels_t &radioPowerLevelsIn, 00295 event_queue_t &eventQueue, 00296 uint32_t advConfigIntervalIn = DEFAULT_CONFIG_PERIOD_MSEC); 00297 00298 /** 00299 * Constructor to initialize the EddystoneService to default values. 00300 * 00301 * @param[in] bleIn 00302 * The BLE instance. 00303 * @param[in] advPowerLevelsIn 00304 * The value of the Eddystone-URL Configuration Service TX 00305 * Power Mode characteristic. 00306 * @param[in] radioPowerLevelsIn 00307 * The value set internally into the radion tx power. 00308 * @param[in] eventQueue 00309 * The event queue used by the service to schedule tasks. 00310 * @param[in] advConfigIntervalIn 00311 * The advertising interval for advertising packets of the 00312 * Eddystone-URL Configuration Service. 00313 * 00314 * @note When using this constructor the setURLData(), setTMLData() and 00315 * setUIDData() and setEIDData() functions must be called to initialize 00316 * EddystoneService manually. 00317 */ 00318 EddystoneService(BLE &bleIn, 00319 const PowerLevels_t &advPowerLevelsIn, 00320 const PowerLevels_t &radioPowerLevelsIn, 00321 event_queue_t &eventQueue, 00322 uint32_t advConfigIntervalIn = DEFAULT_CONFIG_PERIOD_MSEC); 00323 00324 00325 /** 00326 * Generate the EID Beacon Random ECHD Keys (private and Public) 00327 */ 00328 void genEIDBeaconKeys(void); 00329 00330 /** 00331 * Factory Reset all parameters in the beacon 00332 */ 00333 void doFactoryReset(void); 00334 00335 /** 00336 * Setup callback to update BatteryVoltage in Eddystone-TLM frames 00337 * 00338 * @param[in] tlmBatteryVoltageCallbackIn 00339 * The callback being registered. 00340 */ 00341 void onTLMBatteryVoltageUpdate(TlmUpdateCallback_t tlmBatteryVoltageCallbackIn); 00342 00343 /** 00344 * Setup callback to update BeaconTemperature in Eddystone-TLM frames 00345 * 00346 * @param[in] tlmBeaconTemperatureCallbackIn 00347 * The callback being registered. 00348 */ 00349 void onTLMBeaconTemperatureUpdate(TlmUpdateCallback_t tlmBeaconTemperatureCallbackIn); 00350 00351 /** 00352 * Change the EddystoneService OperationMode to EDDYSTONE_MODE_CONFIG. 00353 * 00354 * @retval EDDYSTONE_ERROR_NONE if the operation succeeded. 00355 * @retval EDDYSONE_ERROR_INVALID_ADVERTISING_INTERVAL if the configured 00356 * advertising interval is zero. 00357 * 00358 * @note If EddystoneService was previously in EDDYSTONE_MODE_BEACON, then 00359 * the resources allocated to that mode of operation such as memory 00360 * are freed and the BLE instance shutdown before the new operation 00361 * mode is configured. 00362 */ 00363 EddystoneError_t startConfigService(void); 00364 00365 /** 00366 * Change the EddystoneService to start transmitting Eddystone beacons 00367 * operationMode = EDDYSTONE_MODE_BEACON 00368 * 00369 * @retval EDDYSTONE_ERROR_NONE if the operation succeeded. 00370 * @retval EDDYSONE_ERROR_INVALID_ADVERTISING_INTERVAL if the configured 00371 * advertising interval is zero. 00372 * 00373 * @note If EddystoneService was previously in EDDYSTONE_MODE_CONFIG, then 00374 * the resources allocated to that mode of operation such as memory 00375 * are freed and the BLE instance shutdown before the new operation 00376 * mode is configured. 00377 */ 00378 EddystoneError_t startEddystoneBeaconAdvertisements(void); 00379 00380 /** 00381 * Set the Comple Local Name for the BLE device. This not only updates 00382 * the value of the Device Name Characteristic, it also updates the scan 00383 * response payload if the EddystoneService is currently in 00384 * EDDYSTONE_MODE_CONFIG. 00385 * 00386 * @param[in] deviceNameIn 00387 * A pointer to a null terminated string containing the new 00388 * device name. 00389 * 00390 * @return BLE_ERROR_NONE if the name was successfully set. Otherwise an 00391 * appropriate error. 00392 * 00393 * @note EddystoneService does not make an internal copy of the string 00394 * pointed to by @p deviceNameIn. Therefore, the user is responsible 00395 * for ensuring that the string persists in memory as long as it is 00396 * in use by the EddystoneService. 00397 * 00398 * @note The device name is not considered an Eddystone configuration 00399 * parameter; therefore, it is not contained within the 00400 * EddystoneParams_t structure and must be stored to persistent 00401 * storage separately. 00402 */ 00403 ble_error_t setCompleteDeviceName(const char *deviceNameIn); 00404 00405 /** 00406 * Get the Eddystone Configuration parameters. This is particularly useful 00407 * for storing the configuration parameters in persistent storage. 00408 * It is not the responsibility of the Eddystone implementation to store 00409 * the configured parameters in persistent storage since this is 00410 * platform-specific. 00411 * 00412 * @param[out] params 00413 * A reference to an EddystoneParams_t structure with the 00414 * configured parameters of the EddystoneService. 00415 */ 00416 void getEddystoneParams(EddystoneParams_t ¶ms); 00417 00418 /** 00419 * Start advertising packets indicating the Eddystone Configuration state 00420 * operationMode = EDDYSTONE_MODE_CONFIG 00421 */ 00422 EddystoneService::EddystoneError_t startEddystoneConfigAdvertisements(void); 00423 00424 /** 00425 * Free the resources acquired by a call to setupBeaconService() and 00426 * cancel all pending callbacks that operate the radio and frame queue. 00427 * 00428 * @note This call will not modify the current state of the BLE device. 00429 * EddystoneService::stopBeaconService should only be called after 00430 * a call to BLE::shutdown(). 00431 */ 00432 void stopEddystoneBeaconAdvertisements(void); 00433 00434 /** 00435 * Initialize and start the BLE Eddystone Configuration Service 00436 * This will create the 12-characteristics of the service and make them 00437 * available when a client connects 00438 */ 00439 void startEddystoneConfigService(); 00440 00441 /** 00442 * Stops the Eddystone Configuration Service and frees its resources 00443 * and cancels all pending callbacks that operate the radio and frame queue. 00444 * 00445 * @note This call will not modify the current state of the BLE device. 00446 * EddystoneService::stopBeaconService should only be called after 00447 * a call to BLE::shutdown(). 00448 */ 00449 void stopEddystoneConfigService(); 00450 00451 /** 00452 * Print an array as a set of hex values 00453 * 00454 * @param[in] a 00455 * The array to be printed. 00456 * 00457 * @param[in] len 00458 * The length of the array. 00459 * 00460 * @return void 00461 * 00462 */ 00463 static void logPrintHex(uint8_t* a, int len); 00464 00465 /** 00466 * Swaps the endianess of an array ptrIn[size] to ptrOut[size] 00467 * 00468 * @param[in] *ptrIn 00469 * The input array 00470 * @param[in] *ptrOut 00471 * The output array 00472 * @param[in] size 00473 * The sizes of the arrays (num bytes to be reversed) 00474 */ 00475 static void swapEndianArray(uint8_t *ptrIn, uint8_t *ptrOut, int size); 00476 00477 /** 00478 * Generate a random array of bytes of length size 00479 * 00480 * @param[in] *ain 00481 * The input/output array 00482 * @param[in] size 00483 * The size of the array in bytes 00484 */ 00485 static void generateRandom(uint8_t *ain, int size); 00486 00487 /** 00488 * Timer that keeps track of the time since boot. 00489 */ 00490 00491 static Timer timeSinceBootTimer; 00492 00493 private: 00494 00495 static const uint8_t NO_EID_SLOT_SET = 0xff; 00496 00497 static const uint8_t UNDEFINED_FRAME_FORMAT = 0xff; 00498 00499 static const uint8_t REMAIN_CONNECTABLE_SET = 0x01; 00500 00501 static const uint8_t REMAIN_CONNECTABLE_UNSET = 0x00; 00502 00503 /** 00504 * Helper funtion that will be registered as an initialization complete 00505 * callback when BLE::shutdown() is called. This is necessary when changing 00506 * Eddystone OperationModes. Once the BLE initialization is complete, this 00507 * callback will initialize all the necessary resource to operate 00508 * Eddystone service in the selected mode. 00509 * 00510 * @param[in] initContext 00511 * The context provided by BLE API when initialization 00512 * completes. 00513 */ 00514 void bleInitComplete(BLE::InitializationCompleteCallbackContext* initContext); 00515 00516 /** 00517 * When in EDDYSTONE_MODE_BEACON this function is called to update the 00518 * advertising payload to contain the information related to the specified 00519 * FrameType. 00520 * 00521 * @param[in] slot 00522 * The slot to populate the advertising payload with. 00523 */ 00524 void swapAdvertisedFrame(int slot); 00525 00526 /** 00527 * Helper function that manages the BLE radio that is used to broadcast 00528 * advertising packets. To advertise frames at the configured intervals 00529 * the actual advertising interval of the BLE instance is set to the value 00530 * returned by Gap::getMaxAdvertisingInterval() from the BLE API. When a 00531 * frame needs to be advertised, the enqueueFrame() callbacks add the frame 00532 * type to the advFrameQueue and post a manageRadio() callback. When the 00533 * callback is executed, the frame is dequeued and advertised using the 00534 * radio (by updating the advertising payload). manageRadio() also posts a 00535 * callback to itself Gap::getMinNonConnectableAdvertisingInterval() 00536 * milliseconds later. In this callback, manageRadio() will advertise the 00537 * next frame in the queue, yet if there is none it calls 00538 * Gap::stopAdvertising() and does not post any further callbacks. 00539 */ 00540 void manageRadio(void); 00541 00542 /** 00543 * Regular callbacks posted at the rate of slotAdvPeriod[slot] milliseconds 00544 * enqueue frames to be advertised. If the 00545 * frame queue is currently empty, then this function directly calls 00546 * manageRadio() to broadcast the required FrameType. 00547 * 00548 * @param[in] frameType 00549 * The FrameType to enqueue for broadcasting. 00550 */ 00551 void enqueueFrame(int slot); 00552 00553 /** 00554 * Helper function that updates the advertising payload when in 00555 * EDDYSTONE_MODE_BEACON to contain a new frame. 00556 * 00557 * @param[in] rawFrame 00558 * The raw bytes of the frame to advertise. 00559 * @param[in] rawFrameLength 00560 * The length in bytes of the array pointed to by @p rawFrame. 00561 */ 00562 void updateAdvertisementPacket(const uint8_t* rawFrame, size_t rawFrameLength); 00563 00564 /** 00565 * Helper function that updates the information in the Eddystone-TLM frames 00566 * Internally, this function executes the registered callbacks to update 00567 * beacon Battery Voltage and Temperature (if available). Furthermore, this 00568 * function updates the raw frame data. This operation must be done fairly 00569 * often because the Eddystone-TLM frame Time Since Boot must have a 0.1 00570 * seconds resolution according to the Eddystone specification. 00571 */ 00572 void updateRawTLMFrame(uint8_t* frame); 00573 00574 /** 00575 * Calculate the Frame pointer from the slot number 00576 */ 00577 uint8_t* slotToFrame(int slot); 00578 00579 /** 00580 * Free the characteric resources acquired by a call to 00581 * startEddystoneConfigService(). 00582 */ 00583 void freeConfigCharacteristics(void); 00584 00585 /** 00586 * Helper function used to update the GATT database following any 00587 * change to the internal state of the service object. 00588 */ 00589 void updateCharacteristicValues(void); 00590 00591 /** 00592 * Helper function to setup the payload of scan response packets for 00593 * Eddystone-URL Configuration Service. 00594 */ 00595 void setupEddystoneConfigScanResponse(void); 00596 00597 /** 00598 * Callback registered to the BLE API to authorize write operations to the 00599 * Eddystone Configuration Service Lock characteristic. 00600 * 00601 * @param[in] authParams 00602 * Write authentication information. 00603 */ 00604 void writeLockAuthorizationCallback(GattWriteAuthCallbackParams *authParams); 00605 00606 /** 00607 * Callback registered to the BLE API to authorize write operations to the 00608 * Eddystone Configuration Service Unlock characteristic. 00609 * 00610 * @param[in] authParams 00611 * Write authentication information. 00612 */ 00613 void writeUnlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams); 00614 00615 /** 00616 * Callback registered to the BLE API to authorize write operations to the 00617 * Eddystone Configuration Service advSlotData characteristic. 00618 * 00619 * @param[in] authParams 00620 * Write authentication information. 00621 */ 00622 void writeVarLengthDataAuthorizationCallback(GattWriteAuthCallbackParams *authParams); 00623 00624 /** 00625 * Callback registered to the BLE API to authorize write operations to the 00626 * lockState characteristic which can be 1 byte or 17 bytes long. 00627 * 00628 * @param[in] authParams 00629 * Write authentication information. 00630 */ 00631 void writeLockStateAuthorizationCallback(GattWriteAuthCallbackParams *authParams); 00632 00633 /** 00634 * Callback registered to the BLE API to authorize write operations to simple fixed length 00635 * value characteristic types. 00636 * 00637 * @param[in] authParams 00638 * Write authentication information. 00639 */ 00640 template <typename T> 00641 void writeBasicAuthorizationCallback(GattWriteAuthCallbackParams *authParams); 00642 00643 /** 00644 * This callback is invoked when a GATT client attempts to write to the 00645 * Active Slot characteristic of the service. 00646 * 00647 * @param[in] authParams 00648 * Information about the values that are being read. 00649 */ 00650 template <typename T> 00651 void writeActiveSlotAuthorizationCallback(GattWriteAuthCallbackParams *authParams); 00652 00653 /** 00654 * READ AUTHORIZATIONS 00655 */ 00656 00657 /** 00658 * This callback is invoked when a GATT client attempts to read from a 00659 * basic characteristic of the Eddystone Configuration Service, which 00660 * is blocked if the beacon lock is set to LOCKED. 00661 * 00662 * @param[in] authParams 00663 * Information about the values that are being read. 00664 */ 00665 void readBasicTestLockAuthorizationCallback(GattReadAuthCallbackParams *authParams); 00666 00667 /** 00668 * This callback is invoked when a GATT client attempts to read from the 00669 * EidIdentityKey characteristic of the Eddystone Configuration Service, 00670 * which is blocked if the beacon lock is set to LOCKED, or the key has not 00671 * been set/initialized. 00672 * 00673 * @param[in] authParams 00674 * Information about the values that are being read. 00675 */ 00676 void readEidIdentityAuthorizationCallback(GattReadAuthCallbackParams *authParams); 00677 00678 /** 00679 * This callback is invoked when a GATT client attempts to read from the 00680 * PublicEcdhKey characteristic of the Eddystone Configuration Service, 00681 * which is blocked if the beacon lock is set to LOCKED, or the key has not 00682 * been set/initialized. 00683 * 00684 * @param[in] authParams 00685 * Information about the values that are being read. 00686 */ 00687 void readPublicEcdhKeyAuthorizationCallback(GattReadAuthCallbackParams *authParams); 00688 00689 00690 /** 00691 * This callback is invoked when a GATT client attempts to read from the 00692 * Adv Slot Data characteristic of the Eddystone Configuration Service, 00693 * which isblocked if the beacon lock is set to LOCKED. 00694 * 00695 * @param[in] authParams 00696 * Information about the values that are being read. 00697 */ 00698 void readDataAuthorizationCallback(GattReadAuthCallbackParams *authParams); 00699 00700 /** 00701 * Checks if this is valid frame data (i.e. length > 0) 00702 * 00703 * @param[in] frame 00704 * The frame being tested 00705 * @returns frame is valid or not. 00706 */ 00707 bool testValidFrame(uint8_t* frame); 00708 00709 /** 00710 * This callback is invoked when a GATT client attempts to read the challenge 00711 * from the Unlock characteristic of the Eddystone Configuration Service, 00712 * which is blocked if the beacon lock is set to UNLOCKED. 00713 * 00714 * @param[in] authParams 00715 * Information about the values that are being read. 00716 */ 00717 void readUnlockAuthorizationCallback(GattReadAuthCallbackParams *authParams); 00718 00719 /** 00720 * This callback is invoked when a GATT client attempts to read from the 00721 * Radio Tx Power characteristic of the Eddystone Configuration Service, 00722 * which is blocked if the beacon lock is set to LOCKED. 00723 * 00724 * @param[in] authParams 00725 * Information about the values that are being read. 00726 */ 00727 void readRadioTxPowerAuthorizationCallback(GattReadAuthCallbackParams *authParams); 00728 00729 /** 00730 * This callback is invoked when a GATT client attempts to read from the 00731 * Radio Tx Power characteristic of the Eddystone Configuration Service, 00732 * which is blocked if the beacon lock is set to LOCKED. 00733 * 00734 * @param[in] authParams 00735 * Information about the values that are being read. 00736 */ 00737 void readAdvTxPowerAuthorizationCallback(GattReadAuthCallbackParams *authParams); 00738 00739 /** 00740 * This callback is invoked when a GATT client attempts to read from the 00741 * Adv Interval characteristic of the Eddystone Configuration Service, 00742 * which is blocked if the beacon lock is set to LOCKED. 00743 * 00744 * @param[in] authParams 00745 * Information about the values that are being read. 00746 */ 00747 void readAdvIntervalAuthorizationCallback(GattReadAuthCallbackParams *authParams); 00748 00749 /** 00750 * Calculates the index in the radio power levels array which can be used 00751 * to index into the adv power levels array to find the calibrated adv power 00752 * used in the adv frame. 00753 */ 00754 uint8_t radioTxPowerToIndex(int8_t txPower); 00755 00756 /** 00757 * This callback is invoked when a GATT client attempts to modify any of the 00758 * characteristics of this service. Attempts to do so are also applied to 00759 * the internal state of this service object. 00760 * 00761 * @param[in] writeParams 00762 * Information about the values that are being written. 00763 */ 00764 void onDataWrittenCallback(const GattWriteCallbackParams *writeParams); 00765 00766 /** 00767 * Sets the power for the frame in a particular slot using the 00768 * adv tx power parmeter 00769 * 00770 * @param[in] slot 00771 * The the current slot number being considered 00772 * @param[in] advTxPower 00773 * The adv power required in a frame 00774 */ 00775 void setFrameTxPower(uint8_t slot, int8_t advTxPower); 00776 00777 /** 00778 * AES128 ECB Encrypts a 16-byte input array with a key, to an output array 00779 * 00780 * @param[in] *key 00781 * The encryption key 00782 * @param[in] *input 00783 * The input array 00784 * @param[in] *output 00785 * The output array (contains the encrypted data) 00786 */ 00787 void aes128Encrypt(uint8_t *key, uint8_t *input, uint8_t *output); 00788 00789 /** 00790 * AES128 ECB Deccrypts a 16-byte input array with a key, to an output array 00791 * 00792 * @param[in] *key 00793 * The decryption key 00794 * @param[in] *input 00795 * The input array 00796 * @param[in] *output 00797 * The output array (containing the decrypted data) 00798 */ 00799 void aes128Decrypt(uint8_t *key, uint8_t *input, uint8_t *output); 00800 00801 00802 00803 /** 00804 * Swaps the endianess of a 16-bit unsigned int 00805 * 00806 * @param[in] arg 00807 * The value with the byte order to be reversed 00808 * 00809 * @return The resulting 16-bit value with byte order reversed 00810 */ 00811 uint16_t swapEndian(uint16_t arg); 00812 00813 /** 00814 * Correct the advertising interval for non-connectable packets. 00815 * 00816 * @param[in] beaconPeriodIn 00817 * The input interval in milliseconds. 00818 * 00819 * @return The corrected interval in milliseconds. 00820 * 00821 * @note For the acceptable range of advertising interval refer to the 00822 * following functions in mbed BLE API: 00823 * - Gap::getMinNonConnectableAdvertisingInterval() 00824 * - Gap::getMaxAdvertisingInterval() 00825 */ 00826 uint16_t correctAdvertisementPeriod(uint16_t beaconPeriodIn) const; 00827 00828 /** 00829 * Swaps the endianess of a 16-bit unsigned int 00830 * 00831 * @param[in] arg 00832 * The value with the byte order to be reversed 00833 * 00834 * @return The resulting 16-bit value with byte order reversed 00835 */ 00836 void setRandomMacAddress(void); 00837 00838 /** 00839 * Finds the first EID slot set 00840 * 00841 * @return slot number (and if not, returns NO_EID_SLOT_SET = -1) 00842 */ 00843 int getEidSlot(void); 00844 00845 /** 00846 * BLE instance that EddystoneService will operate on. 00847 */ 00848 BLE &ble; 00849 00850 /** 00851 * The advertising interval for Eddystone-URL Config Service advertising 00852 * packets. 00853 */ 00854 uint32_t advConfigInterval; 00855 /** 00856 * Current EddystoneServce operation mode. 00857 */ 00858 uint8_t operationMode; 00859 00860 int genBeaconKeyRC; 00861 00862 /** 00863 * GATT Service Variables 00864 */ 00865 00866 /** 00867 * An array describing the capabilites of the beacon. 00868 */ 00869 Capability_t capabilities; 00870 00871 /** 00872 * The currenty defined active slot. 00873 */ 00874 uint8_t activeSlot; 00875 00876 /** 00877 * An array containing all the adv intervals for each slot index 00878 */ 00879 SlotAdvIntervals_t slotAdvIntervals; 00880 00881 /** 00882 * The value of the Eddystone Configuration Service radioTX Power 00883 * characteristic. 00884 */ 00885 SlotTxPowerLevels_t slotRadioTxPowerLevels; 00886 00887 /** 00888 * An array containing the supported radio tx power levels for this beacon 00889 */ 00890 PowerLevels_t radioTxPowerLevels; 00891 00892 /** 00893 * An array containing all possible values for advertised tx power in Eddystone 00894 * slots. 00895 */ 00896 SlotTxPowerLevels_t slotAdvTxPowerLevels; 00897 00898 /** 00899 * An array containing the supported adv tx power levels for this beacon 00900 */ 00901 PowerLevels_t advTxPowerLevels; 00902 00903 /** 00904 * The value of the Eddystone Configuration Service Lock State 00905 * characteristic. 00906 */ 00907 uint8_t lockState; 00908 00909 00910 /** 00911 * The value of the Eddystone Configuration Service Lock State 00912 * buffer 00913 */ 00914 LockState_t lockStateBuf; 00915 00916 /** 00917 * The value of the Eddystone Configuration Service unlock key 00918 */ 00919 Lock_t unlockKey; 00920 00921 /** 00922 * The value of the Eddystone Configuration Service unlock challenge 00923 */ 00924 Lock_t challenge; 00925 00926 /** 00927 * The value of the Eddystone Configuration Service unlock token. A write 00928 * to the unlock characteristic must contain this token to unlock the beacon 00929 */ 00930 Lock_t unlockToken; 00931 00932 00933 /** 00934 * EID: An array holding the 256-bit private Ecdh Key (big endian) 00935 */ 00936 PrivateEcdhKey_t privateEcdhKey; 00937 00938 /** 00939 * EID: An array holding the 256-bit public Ecdh Key (big endian) 00940 */ 00941 PublicEcdhKey_t publicEcdhKey; 00942 00943 /** 00944 * EID: An array holding the 256-bit public Ecdh Key (little endian) 00945 */ 00946 PublicEcdhKey_t publicEcdhKeyLE; 00947 00948 /** 00949 * EID: An array holding the slot rotation period exponents 00950 */ 00951 SlotEidRotationPeriodExps_t slotEidRotationPeriodExps; 00952 00953 /** 00954 * EID: An array holding the slot Eid Identity Keys 00955 */ 00956 SlotEidIdentityKeys_t slotEidIdentityKeys; 00957 00958 /** 00959 * EID: An array holding the slot Eid Public Ecdh Keys 00960 */ 00961 //SlotEidPublicEcdhKeys_t slotEidPublicEcdhKeys; 00962 00963 /** 00964 * Instance of the UID frame. 00965 */ 00966 UIDFrame uidFrame; 00967 00968 /** 00969 * Instance of the URL frame. 00970 */ 00971 URLFrame urlFrame; 00972 00973 /** 00974 * Instance of the TLM frame. 00975 */ 00976 TLMFrame tlmFrame; 00977 00978 /** 00979 * Instance of the EID frame. 00980 */ 00981 EIDFrame eidFrame; 00982 00983 /** 00984 * The value of the Eddystone Configuration Service reset 00985 * characteristic. 00986 */ 00987 uint8_t factoryReset; 00988 00989 /** 00990 * The value of the Eddystone Configuration Service Remain Connectable 00991 * characteristic. 00992 */ 00993 uint8_t remainConnectable; 00994 00995 /** 00996 * CHARACTERISTIC STORAGE 00997 */ 00998 00999 /** 01000 * Pointer to the BLE API characteristic encapsulation for the Eddystone 01001 * Configuration Service Capabilities characteristic. 01002 */ 01003 ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(Capability_t)> *capabilitiesChar; 01004 01005 /** 01006 * Pointer to the BLE API characteristic encapsulation for the Eddystone 01007 * Configuration Service Active Slot characteristic. 01008 */ 01009 ReadWriteGattCharacteristic<uint8_t> *activeSlotChar; 01010 01011 /** 01012 * Pointer to the BLE API characteristic encapsulation for the Eddystone 01013 * Configuration Service Adv Interval characteristic. 01014 */ 01015 ReadWriteGattCharacteristic<uint16_t> *advIntervalChar; 01016 01017 /** 01018 * Pointer to the BLE API characteristic encapsulation for the Eddystone 01019 * Configuration Service Radio Tx Power characteristic. 01020 */ 01021 ReadWriteGattCharacteristic<int8_t> *radioTxPowerChar; 01022 01023 /** 01024 * Pointer to the BLE API characteristic encapsulation for the Eddystone 01025 * Configuration Service Adv Tx Power characteristic. 01026 */ 01027 ReadWriteGattCharacteristic<int8_t> *advTxPowerChar; 01028 01029 /** 01030 * Pointer to the BLE API characteristic encapsulation for the Eddystone 01031 * Configuration Service Lock State characteristic. 01032 */ 01033 GattCharacteristic *lockStateChar; 01034 01035 /** 01036 * Pointer to the BLE API characteristic encapsulation for the Eddystone 01037 * Configuration Service Unlock characteristic. 01038 */ 01039 ReadWriteArrayGattCharacteristic<uint8_t, sizeof(Lock_t)> *unlockChar; 01040 01041 /** 01042 * Pointer to the BLE API characteristic encapsulation for the Eddystone 01043 * Configuration Service Public ECDH Key characteristic. 01044 */ 01045 GattCharacteristic *publicEcdhKeyChar; 01046 01047 /** 01048 * Pointer to the BLE API characteristic encapsulation for the Eddystone-URL 01049 * Configuration Service EID Identity Key characteristic. 01050 */ 01051 GattCharacteristic *eidIdentityKeyChar; 01052 01053 /** 01054 * Pointer to the BLE API characteristic encapsulation for the Eddystone-URL 01055 * Configuration Service Adv Slot Data characteristic. 01056 */ 01057 GattCharacteristic *advSlotDataChar; 01058 01059 /** 01060 * Pointer to the BLE API characteristic encapsulation for the Eddystone-URL 01061 * Configuration Service Factory Reset characteristic. 01062 */ 01063 WriteOnlyGattCharacteristic<uint8_t> *factoryResetChar; 01064 01065 /** 01066 * Pointer to the BLE API characteristic encapsulation for the Eddystone-GATT 01067 * Configuration Service Remain Connectable characteristic. 01068 */ 01069 ReadWriteGattCharacteristic<uint8_t> *remainConnectableChar; 01070 01071 /** 01072 * END OF GATT CHARACTERISTICS 01073 */ 01074 01075 /** 01076 * EID: An array holding the slot next rotation times 01077 */ 01078 SlotEidNextRotationTimes_t slotEidNextRotationTimes; 01079 01080 /** 01081 * EID: Storage for the current slot encrypted EID Identity Key 01082 */ 01083 EidIdentityKey_t encryptedEidIdentityKey; 01084 01085 /* 01086 * Storage for all the slots / frames 01087 */ 01088 SlotStorage_t slotStorage; 01089 01090 /** 01091 * An array that defines the frame type of each slot using the slot number 01092 * as an index. 01093 */ 01094 SlotFrameTypes_t slotFrameTypes; 01095 01096 /** 01097 * Circular buffer that represents of Eddystone frames to be advertised. 01098 */ 01099 CircularBuffer<uint8_t, MAX_ADV_SLOTS> advFrameQueue; 01100 01101 /** 01102 * The registered callback to update the Eddystone-TLM frame Battery 01103 * Voltage. 01104 */ 01105 TlmUpdateCallback_t tlmBatteryVoltageCallback; 01106 01107 /** 01108 * The registered callback to update the Eddystone-TLM frame Beacon 01109 * Temperature. 01110 */ 01111 TlmUpdateCallback_t tlmBeaconTemperatureCallback; 01112 01113 /** 01114 * Type for the array of callback handles for all the slot timers 01115 */ 01116 typedef event_queue_t::event_handle_t SlotCallbackHandles_t[MAX_ADV_SLOTS]; 01117 01118 /** 01119 * An array of all the slot timer callbacks handles 01120 */ 01121 SlotCallbackHandles_t slotCallbackHandles; 01122 01123 /** 01124 * Callback handle to keep track of manageRadio() callbacks. 01125 */ 01126 event_queue_t::event_handle_t radioManagerCallbackHandle; 01127 01128 /** 01129 * GattCharacteristic table used to populate the BLE ATT table in the 01130 * GATT Server. 01131 */ 01132 GattCharacteristic *charTable[TOTAL_CHARACTERISTICS]; 01133 01134 /** 01135 * Pointer to the device name currently being used. 01136 */ 01137 const char *deviceName; 01138 01139 /** 01140 * Defines an array of string constants (a container) used to initialise any URL slots 01141 */ 01142 static const char* const slotDefaultUrls[]; 01143 01144 /** 01145 * Defines an array of UIDs to initialize UID slots 01146 */ 01147 static const uint8_t slotDefaultUids[MAX_ADV_SLOTS][16]; 01148 01149 /** 01150 * Defines an array of EID (Identity keys) to initialize EID slots 01151 */ 01152 static const uint8_t slotDefaultEidIdentityKeys[MAX_ADV_SLOTS][16]; 01153 01154 /** 01155 * Defines default EID payload before being updated with the first EID rotation value 01156 */ 01157 static const uint8_t allSlotsDefaultEid[8]; 01158 01159 /** 01160 * Reference to the event queue used to post tasks 01161 */ 01162 event_queue_t& eventQueue; 01163 01164 /** 01165 * Next EID slot frame that will be transmitted 01166 */ 01167 uint8_t nextEidSlot; 01168 }; 01169 01170 #endif /* __EDDYSTONESERVICE_H__ */
Generated on Thu Jul 14 2022 09:28:18 by
1.7.2