Button initiated config service

Dependencies:   BLE_API_EddystoneConfigService_2 mbed nRF51822

Fork of BLE_EddystoneBeaconConfigService_3 by URIBeacon

Revision:
34:5876fbb1aa62
Parent:
33:8c65879e7d52
Child:
35:314f2152506f
--- a/EddystoneConfigService.h	Mon Jul 27 21:44:07 2015 +0000
+++ b/EddystoneConfigService.h	Wed Sep 02 20:17:38 2015 +0000
@@ -19,6 +19,7 @@
 
 #include "mbed.h"
 #include "ble/BLE.h"
+#include "ble/services/EddystoneService.h"
 
 #define EDDYSTONE_NUM_UID_FRAMES 10
 #define EDDYSTONE_NUM_URL_FRAMES 50
@@ -39,20 +40,7 @@
 static const uint8_t UUID_TX_POWER_MODE_CHAR[]    = UUID_URI_BEACON(0x20, 0x87);
 static const uint8_t UUID_BEACON_PERIOD_CHAR[]    = UUID_URI_BEACON(0x20, 0x88);
 static const uint8_t UUID_RESET_CHAR[]            = UUID_URI_BEACON(0x20, 0x89);
-static const uint8_t BEACON_EDDYSTONE[] = {0xAA, 0xFE};
-
-//Debug is disabled by default
-#if 1
-#define DBG(x, ...)  printf("[EddyStone: DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
-#define WARN(x, ...) printf("[EddyStone: WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
-#define ERR(x, ...)  printf("[EddyStone: ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
-#define INFO(x, ...) printf(x, ##__VA_ARGS__) 
-#else
-#define DBG(x, ...) //wait_us(10);
-#define WARN(x, ...) //wait_us(10);
-#define ERR(x, ...)
-#define INFO(x, ...)
-#endif
+extern const uint8_t       BEACON_EDDYSTONE[2];
 
 /**
 * @class EddystoneConfigService
@@ -70,7 +58,7 @@
     static const uint8_t TX_POWER_MODE_LOW    = 1; /*!< Low TX power mode */
     static const uint8_t TX_POWER_MODE_MEDIUM = 2; /*!< Medium TX power mode */
     static const uint8_t TX_POWER_MODE_HIGH   = 3; /*!< High TX power mode */
-    static const unsigned int NUM_POWER_MODES = 4; /*!< Number of Power Modes defined */
+    static const unsigned NUM_POWER_MODES     = 4; /*!< Number of Power Modes defined */
 
     static const int ADVERTISING_INTERVAL_MSEC = 1000;  // Advertising interval for config service.
     static const int SERVICE_DATA_MAX = 31;             // Maximum size of service data in ADV packets
@@ -87,9 +75,9 @@
 
     // UID Frame Type subfields
     static const int UID_NAMESPACEID_SIZE = 10;
-    typedef uint8_t  UIDNamespaceID_t[UID_NAMESPACEID_SIZE];
+    typedef size_t  UIDNamespaceID_t[UID_NAMESPACEID_SIZE];
     static const int UID_INSTANCEID_SIZE = 6;
-    typedef uint8_t  UIDInstanceID_t[UID_INSTANCEID_SIZE];
+    typedef size_t  UIDInstanceID_t[UID_INSTANCEID_SIZE];
 
     // Eddystone Frame Type ID
     static const uint8_t FRAME_TYPE_UID = 0x00;
@@ -100,16 +88,17 @@
     static const uint8_t FRAME_SIZE_UID = 20; // includes RFU bytes
 
     struct Params_t {
+        uint8_t       lockedState;
         Lock_t        lock;
-        size_t        uriDataLength;
+        uint8_t        uriDataLength;
         UriData_t     uriData;
         uint8_t       flags;
         PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels
         uint8_t       txPowerMode;    // Firmware power levels used with setTxPower()
         uint16_t      beaconPeriod;
-        //uint8_t       tlmVersion;     // version of TLM packet
-        //UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B
-        //UIDInstanceID_t  uidInstanceID;  // UUID type, Instance ID,  6B
+        uint8_t       tlmVersion;     // version of TLM packet
+        UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B
+        UIDInstanceID_t  uidInstanceID;  // UUID type, Instance ID,  6B
     };
 
     /**
@@ -123,25 +112,31 @@
      *                    If true, it indicates that paramsIn is potentially
      *                    un-initialized, and default values should be used
      *                    instead. Otherwise, paramsIn overrides the defaults.
-     * @param[in]     defaultUriDataIn
-     *                    Default un-encoded URI; applies only if the resetToDefaultsFlag is true.
      * @param[in]     defaultAdvPowerLevelsIn
      *                    Default power-levels array; applies only if the resetToDefaultsFlag is true.
+     * @param[in]     defaultUriDataIn
+     *                    Default un-encoded URI; optional parameter, applies only if the resetToDefaultsFlag is true
+     * @param[in]     defaultUIDNamespaceIDIn
+     *                    Default 10Byte UID Namespace ID; optional parameter, applies only if the resetToDefaultsFlag is true
+     * @param[in]     defaultUIDInstanceIDIn
+     *                    Default 6byte UID Instance ID; optional parameter, applies only if the resetToDefaultsFlag is true
+     * @param[in]     defaultTLMVersionIn
+     *                    Default TLM version; defaults to 0, applies only if the resetToDefaultsFlag is true
      */
     EddystoneConfigService(BLEDevice     &bleIn,
                            Params_t      &paramsIn,
                            bool          resetToDefaultsFlag,
-                           const char   *defaultURIDataIn,
-                           UIDNamespaceID_t uidNamespaceID,
-                           UIDInstanceID_t  uidInstanceID,
-                           uint8_t tlmVersion,
-                           PowerLevels_t &defaultAdvPowerLevelsIn) :
+                           PowerLevels_t &defaultAdvPowerLevelsIn,
+                           const char   *defaultURIDataIn = NULL,
+                           UIDNamespaceID_t *defaultUIDNamespaceIDIn = NULL,
+                           UIDInstanceID_t  *defaultUIDInstanceIDIn = NULL,
+                           uint8_t defaultTLMVersionIn = 0) :
         ble(bleIn),
         params(paramsIn),       // Initialize URL Data
         defaultUriDataLength(),
         defaultUriData(),
-        //defaultUidNamespaceID(uidNamespaceID), // Initialize UID Data
-        //defaultUidInstanceID(uidInstanceID),
+        defaultUidNamespaceID(), // Initialize UID Data
+        defaultUidInstanceID(),
         defaultUrlPower(params.advPowerLevels[params.txPowerMode]),
         defaultUidPower(params.advPowerLevels[params.txPowerMode]),
         uidIsSet(true),
@@ -149,12 +144,12 @@
         defaultAdvPowerLevels(defaultAdvPowerLevelsIn),
         initSucceeded(false),
         resetFlag(),
-        TlmVersion(tlmVersion), // Initialize TLM Data
+        lockedStateChar(UUID_LOCK_STATE_CHAR, &params.lockedState),
+        TlmVersion(defaultTLMVersionIn), // Initialize TLM Data
         TlmBatteryVoltage(0),
         TlmBeaconTemp(0),
         TlmPduCount(0),
         TlmTimeSinceBoot(0),
-        lockedStateChar(UUID_LOCK_STATE_CHAR, &lockedState),
         lockChar(UUID_LOCK_CHAR, &params.lock),
         uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX,
                     GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE),
@@ -166,8 +161,8 @@
         resetChar(UUID_RESET_CHAR, &resetFlag) 
         {
         //Set UID frame
-        memcpy(defaultUidNamespaceID,uidNamespaceID,UID_NAMESPACEID_SIZE);
-        memcpy(defaultUidInstanceID,uidInstanceID,UID_INSTANCEID_SIZE);
+        memcpy(defaultUidNamespaceID,defaultUIDNamespaceIDIn,UID_NAMESPACEID_SIZE);
+        memcpy(defaultUidInstanceID,defaultUIDInstanceIDIn,UID_INSTANCEID_SIZE);
         
         // Set URL Frame
         encodeURI(defaultURIDataIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting
@@ -240,7 +235,7 @@
         ble.setTxPower(params.advPowerLevels[params.txPowerMode]);
         ble.setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME));
         ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-        ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC));
+        ble.setAdvertisingInterval(GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC));
     }
 
     /*
@@ -549,8 +544,8 @@
     void setupEddystoneAdvertisements(  //BLEDevice       &bleIn,
                                         uint16_t        beaconPeriodus,
                                         uint8_t         txPowerLevel,
-                                        uint8_t *       uidNamespaceID = NULL,
-                                        uint8_t *       uidInstanceID = NULL,
+                                        size_t *       uidNamespaceID = NULL,
+                                        size_t *       uidInstanceID = NULL,
                                         const char *    url = NULL,
                                         uint8_t         urlLen = 0,
                                         uint8_t         tlmVersion = 0x00)
@@ -667,26 +662,26 @@
             // Validated earlier
             memcpy(params.lock, writeParams->data, sizeof(Lock_t));
             // use isLocked() in case bits are being set to all 0's
-            lockedState = isLocked();
+            params.lockedState = true;
         } else if (handle == unlockChar.getValueHandle()) {
             // Validated earlier
             memset(params.lock, 0, sizeof(Lock_t));
-            lockedState = false;
+            params.lockedState = false;
         } else if (handle == uriDataChar.getValueHandle()) {
             params.uriDataLength = writeParams->len;
             memcpy(params.uriData, writeParams->data, params.uriDataLength);
-            //memcpy(defaultUriData, writeParams->data, params.uriDataLength);
-            //defaultUriDataLength = params.uriDataLength;
-            DBG("URI = %s, URILen = %d", writeParams->data, writeParams->len);
+            memcpy(defaultUriData, writeParams->data, params.uriDataLength);
+            defaultUriDataLength = params.uriDataLength;
+            INFO("URI = %s, URILen = %d", writeParams->data, writeParams->len);
         } else if (handle == flagsChar.getValueHandle()) {
             params.flags = *(writeParams->data);
-            DBG("flagsChar = 0x%x",params.flags);
+            INFO("flagsChar = 0x%x",params.flags);
         } else if (handle == advPowerLevelsChar.getValueHandle()) {
             memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t));
-            DBG("PowerLevelsChar = %4x",writeParams->data);
+            INFO("PowerLevelsChar = %4x",writeParams->data);
         } else if (handle == txPowerModeChar.getValueHandle()) {
             params.txPowerMode = *(writeParams->data);
-            DBG("TxPowerModeChar = %d",params.txPowerMode);
+            INFO("TxPowerModeChar = %d",params.txPowerMode);
         } else if (handle == beaconPeriodChar.getValueHandle()) {
             params.beaconPeriod = *((uint16_t *)(writeParams->data));
 
@@ -713,17 +708,17 @@
      * Reset the default values.
      */
     void resetToDefaults(void) {
-        lockedState             = false;
+        params.lockedState      = false;
         memset(params.lock, 0, sizeof(Lock_t));
         memcpy(params.uriData, defaultUriData, URI_DATA_MAX);
         params.uriDataLength    = defaultUriDataLength;
-        params.flags            = 0;
+        params.flags            = 0x10;
         memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t));
         params.txPowerMode      = TX_POWER_MODE_LOW;
         params.beaconPeriod     = 1000;
-        //memcpy(params.uidNamespaceID, defaultUidNamespaceID, UID_NAMESPACEID_SIZE);
-        //memcpy(params.uidInstanceID,  defaultUidInstanceID,  UID_INSTANCEID_SIZE);
-        //params.tlmVersion = 0;
+        memcpy(params.uidNamespaceID, defaultUidNamespaceID, UID_NAMESPACEID_SIZE);
+        memcpy(params.uidInstanceID,  defaultUidInstanceID,  UID_INSTANCEID_SIZE);
+        params.tlmVersion = TlmVersion;
         updateCharacteristicValues();
     }
 
@@ -732,7 +727,7 @@
      * change to the internal state of the service object.
      */
     void updateCharacteristicValues(void) {
-        ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), &lockedState, 1);
+        ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), &params.lockedState, 1);
         ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength);
         ble.updateCharacteristicValue(flagsChar.getValueHandle(), &params.flags, 1);
         ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(),
@@ -744,7 +739,7 @@
 
 private:
     void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
-        if (lockedState) {
+        if (params.lockedState) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
         } else if (authParams->len != sizeof(Lock_t)) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
@@ -757,7 +752,7 @@
 
 
     void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
-        if (!lockedState) {
+        if ((!params.lockedState) && (authParams->len == sizeof(Lock_t))) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
         } else if (authParams->len != sizeof(Lock_t)) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
@@ -771,7 +766,7 @@
     }
 
     void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
-        if (lockedState) {
+        if (params.lockedState) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
         } else if (authParams->offset != 0) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
@@ -781,7 +776,7 @@
     }
 
     void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
-        if (lockedState) {
+        if (params.lockedState) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
         } else if (authParams->len != sizeof(uint8_t)) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
@@ -796,7 +791,7 @@
 
     template <typename T>
     void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
-        if (lockedState) {
+        if (params.lockedState) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
         } else if (authParams->len != sizeof(T)) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
@@ -812,7 +807,7 @@
     Ticker              timeSinceBootTick;
     Timeout             switchFrame;
 // Default value that is restored on reset
-    size_t              defaultUriDataLength;
+    uint8_t             defaultUriDataLength;
     UriData_t           defaultUriData;
     UIDNamespaceID_t    defaultUidNamespaceID;
     UIDInstanceID_t     defaultUidInstanceID;
@@ -849,14 +844,14 @@
     /*
      *  Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification).
      */
-    static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, size_t &sizeofURIDataOut) {
+    static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, uint8_t &sizeofURIDataOut) {
         const char *prefixes[] = {
             "http://www.",
             "https://www.",
             "http://",
             "https://",
         };
-        const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *);
+        const uint8_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *);
         const char *suffixes[] = {
             ".com/",
             ".org/",
@@ -873,7 +868,7 @@
             ".biz",
             ".gov"
         };
-        const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *);
+        const uint8_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *);
 
         sizeofURIDataOut = 0;
         memset(uriDataOut, 0, sizeof(UriData_t));
@@ -886,7 +881,7 @@
          * handle prefix
          */
         for (unsigned i = 0; i < NUM_PREFIXES; i++) {
-            size_t prefixLen = strlen(prefixes[i]);
+            uint8_t prefixLen = strlen(prefixes[i]);
             if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) {
                 uriDataOut[sizeofURIDataOut++]  = i;
                 uriDataIn                      += prefixLen;
@@ -901,7 +896,7 @@
             /* check for suffix match */
             unsigned i;
             for (i = 0; i < NUM_SUFFIXES; i++) {
-                size_t suffixLen = strlen(suffixes[i]);
+                uint8_t suffixLen = strlen(suffixes[i]);
                 if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) {
                     uriDataOut[sizeofURIDataOut++]  = i;
                     uriDataIn                      += suffixLen;