Button initiated config service

Dependencies:   BLE_API_EddystoneConfigService_2 mbed nRF51822

Fork of BLE_EddystoneBeaconConfigService_3 by URIBeacon

Revision:
25:e20bed9e466f
Parent:
23:05e9bb3b13af
Child:
31:11e7a505a4be
--- a/EddystoneConfigService.h	Thu Jul 23 20:38:20 2015 +0000
+++ b/EddystoneConfigService.h	Fri Jul 24 02:06:57 2015 +0000
@@ -52,7 +52,7 @@
 /**
 * @class EddystoneConfigService
 * @brief Eddystone Configuration Service. Can be used to set URL, adjust power levels, and set flags.
-* See http://uribeacon.org
+* See https://github.com/google/eddystone
 *
 */
 class EddystoneConfigService
@@ -105,6 +105,9 @@
         uint8_t       tlmVersion;     // version of TLM packet
         UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B
         UIDInstanceID_t  uidInstanceID;  // UUID type, Instance ID,  6B
+        int(*tlmGetBatt(void)); // Function Pointers for user provided functions that return the Temp and Battery Voltage data for the TLM field.
+        int(*tlmGetTemp(void)); // ^^
+
     };
 
     /**
@@ -296,7 +299,7 @@
     int constructURLFrame(uint8_t * Data, uint8_t maxSize) {
         int index = 0;
         Data[index++] = FRAME_TYPE_URL;                     // 1B  Type
-        Data[index++] = params.txPowerMode;                    // 1B  TX Power
+        Data[index++] = defaultUrlPower;                    // 1B  TX Power
         for(int x = 0; x < defaultUriDataLength; x++) {     // 18B of URL Prefix + encoded URL
             Data[index++] = defaultUriData[x];
         }
@@ -427,37 +430,42 @@
         serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
         serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
 
+        // if certain frames are not enabled, then skip them. Worst case TLM is always enabled
         switch(frameIndex) {
-            case 0:
-            // TLM frame
+            case 1:
+                // URL Frame
+                if(urlIsSet) {
+                    serviceDataLen += constructURLFrame(serviceData+serviceDataLen,20);
+                    DBG("\t Swapping in URL Frame: len=%d ",serviceDataLen);
+                    updateAdvPacket(serviceData,serviceDataLen);
+                    switchFlag = false;
+                    frameIndex++;
+                    break;
+                }
+            case 2:
+                // UID Frame
+                if(uidIsSet) {
+                    serviceDataLen += constructUIDFrame(serviceData+serviceDataLen,20);
+                    DBG("\t Swapping in UID Frame: len=%d",serviceDataLen);
+                    updateAdvPacket(serviceData,serviceDataLen);
+                    switchFlag = false;
+                    frameIndex++;
+                    break;
+                }
+            default:
+                // TLM frame
                 serviceDataLen += constructTLMFrame(serviceData+serviceDataLen,20);
                 DBG("\t Swapping in TLM Frame: len=%d",serviceDataLen);
                 updateAdvPacket(serviceData,serviceDataLen);
                 frameIndex++;
                 break;
-            case 1:
-                // URL Frame
-                serviceDataLen += constructURLFrame(serviceData+serviceDataLen,20);
-                DBG("\t Swapping in URL Frame: len=%d ",serviceDataLen);
-                updateAdvPacket(serviceData,serviceDataLen);
-                switchFlag = false;
-                frameIndex++;
-                break;
-            case 2:
-                // UID Frame
-                serviceDataLen += constructUIDFrame(serviceData+serviceDataLen,20);
-                DBG("\t Swapping in UID Frame: len=%d",serviceDataLen);
-                updateAdvPacket(serviceData,serviceDataLen);
-                switchFlag = false;
-                frameIndex++;
-                break;
         }
     }
 
     /*
     *  Callback from onRadioNotification(), used to update the PDUCounter and process next state.
     */
-    #define EDDYSTONE_SWAPFRAME_DELAYMS 1
+#define EDDYSTONE_SWAPFRAME_DELAYMS 1
     void radioNotificationCallback(bool radioActive) {
         //DBG("RadioNotificationCallback : %d, %d, %d, %d",radioActive,frameIndex,TlmPduCount,TlmTimeSinceBoot);
         // Update PDUCount
@@ -471,11 +479,11 @@
         } else {
             // state machine to control which packet is being sent
             switch(frameIndex) {
-                case 0:
+                case 0: // TLM Frame
                     switchFrame.attach_us(this, &EddystoneConfigService::swapOutFrames, EDDYSTONE_SWAPFRAME_DELAYMS);
                     switchFlag = true;
                     break;
-                case 1:
+                case 1: // URL Frame
                     // switch out packets
                     if(switchFlag) {
                         switchFrame.attach_us(this, &EddystoneConfigService::swapOutFrames, EDDYSTONE_SWAPFRAME_DELAYMS);
@@ -486,9 +494,9 @@
                         }
                     }
                     break;
-                case 2:
+                case 2: // UIDFrame
                     // switch out packets
-                    if(switchFlag) {
+                    if(switchFlag ) {
                         switchFrame.attach_us(this, &EddystoneConfigService::swapOutFrames, EDDYSTONE_SWAPFRAME_DELAYMS);
                         switchFlag = false;
                     } else {
@@ -503,20 +511,90 @@
         return;
     }
 
-    /* Helper function to switch to the non-connectible normal mode for Eddystone. This gets called after a timeout. */
+    /*
+    *   This function explicityly sets the parameters used by the Eddystone beacon.
+    *   this function should be used in leu of the config service.
+    *
+    *   @param bleIn ble object used to broadcast eddystone information
+    *   @oaram beaconPeriodus is how often ble broadcasts are mde, in mili seconds
+    *   @param txPowerLevel sets the broadcasting power level.
+    *   @param uidNamespaceID 10Byte Namespace UUID
+    *   @param uidInstanceID  6Byte  Instance UUID
+    *   @param url shortened URL to broadcast (pass in as a string)
+    *   @param urlLen length of shortened url
+    *   @param tlmVersion version of telemetry data field to use (default to 0x00)
+    *
+    */
+    void setupEddystoneAdvertisements(  BLEDevice       &bleIn,
+                                        uint16_t        beaconPeriodus,
+                                        uint8_t         txPowerLevel,
+                                        uint8_t *       uidNamespaceID = NULL,
+                                        uint8_t *       uidInstanceID = NULL,
+                                        const char *    url = NULL,
+                                        uint8_t         urlLen = 0,
+                                        uint8_t         tlmVersion = 0x00) :
+                                         ble(bleIn)
+     {
+        uint8_t serviceData[SERVICE_DATA_MAX];
+        unsigned serviceDataLen = 0;
+        ERR("This function is not fully implemented yet, dont use it!!");
+        // Check optional frames, set their 'isSet' flags appropriately
+        if((uidNamespaceID != NULL) & (uidInstanceID != NULL)) {
+            uidIsSet = true;
+            setUIDFrameData(txPowerLevel,uidNamespaceID, uidInstanceID);
+        } else {
+            uidIsSet = false;
+        }
+        if(url != NULL) {
+            urlIsSet = true;
+            setURLFrameData(txPowerLevel,url);
+        } else {
+            uidIsSet = false;
+        }
+        // Default TLM frame to version 0x00, start all values at zero to be spec compliant.
+        setTLMFrameData(tlmVersion, 0x00,0x00);
+
+        // Initialize Frame transition
+        frameIndex = 0;
+        uidRFU = 0;
+        switchFlag = true;
+
+        /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */
+        ble.shutdown();
+        ble.init();
+        ble.setTxPower(txPowerLevel);
+        ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
+        ble.setAdvertisingInterval(beaconPeriodus);
+
+        // Make double sure the PDUCount and TimeSinceBoot fields are set to zero at reset
+        updateTlmPduCount(0);
+        updateTlmTimeSinceBoot(0);
+
+        // Construct TLM Frame in initial advertising.
+        serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
+        serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
+        serviceDataLen += constructTLMFrame(serviceData+serviceDataLen,SERVICE_DATA_MAX);
+
+        updateAdvPacket(serviceData, serviceDataLen);
+        ble.gap().startAdvertising();
+        ble.gap().onRadioNotification(this,&EddystoneConfigService::radioNotificationCallback);
+        timeSinceBootTick.attach(this,&EddystoneConfigService::tsbCallback,0.1); // incriment the TimeSinceBoot ticker every 0.1s
+
+    }
+
+    /*
+    *   This function actually impliments the Eddystone Beacon service. It can be called with the help of the wrapper function
+    *   to load saved config params, or it can be called explicitly to reset the eddystone beacon to hardcoded values on each reset.
+    *
+    */
     void setupEddystoneAdvertisements() {
         DBG("Switching Config -> adv");
         uint8_t serviceData[SERVICE_DATA_MAX];
         unsigned serviceDataLen = 0;
         unsigned beaconPeriod                                 = params.beaconPeriod;
-        unsigned txPowerMode                                  = params.txPowerMode;
-        unsigned uriDataLength                                = params.uriDataLength;
-
-        EddystoneConfigService::UriData_t &uriData            = params.uriData;
-        EddystoneConfigService::PowerLevels_t &advPowerLevels = params.advPowerLevels;
 
         // Initialize Frame transition
-        frameIndex = 2;
+        frameIndex = 0;
         uidRFU = 0;
         switchFlag = true;
 
@@ -701,7 +779,6 @@
 
     BLEDevice           &ble;
     Params_t            &params;
-    Ticker              callbackTick;
     Ticker              timeSinceBootTick;
     Timeout             switchFrame;
 // Default value that is restored on reset
@@ -712,6 +789,8 @@
     int8_t              defaultUidPower;
     int8_t              defaultUrlPower;
     uint16_t            uidRFU;
+    bool                uidIsSet;
+    bool                urlIsSet;
 // Default value that is restored on reset
     PowerLevels_t       &defaultAdvPowerLevels;
     uint8_t             lockedState;