Roy Want / Mbed OS beaconCompileReadyFork
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EddystoneService.h Source File

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   &paramsIn,
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 &params);
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__ */