Kenji Arai / Mbed 2 deprecated BLE_EddystoneBeacon_w_ACC_TY51822

Dependencies:   BLE_API LIS3DH mbed nRF51822 BMC050 nRF51_LowPwr nRF51_Vdd

Fork of BLE_EddystoneBeacon_Service by Bluetooth Low Energy

Files at this revision

API Documentation at this revision

Comitter:
mbedAustin
Date:
Mon Jul 20 19:31:40 2015 +0000
Parent:
14:5a2a104a21a8
Child:
16:a7d07ea94b31
Commit message:
[[Testing]] - confirmed all packets are being encoded correctly. Currently using Ticker to switch payloads. Need to add stuff to BLE library to enable callbacks to object functions.;

Changed in this revision

ZipBeaconConfigService.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/ZipBeaconConfigService.h	Mon Jul 20 04:29:07 2015 +0000
+++ b/ZipBeaconConfigService.h	Mon Jul 20 19:31:40 2015 +0000
@@ -43,8 +43,9 @@
 * See http://uribeacon.org
 *
 */
-class ZipBeaconConfigService {
-  public:
+class ZipBeaconConfigService
+{
+public:
     /**
      * @brief Transmission Power Modes for UriBeacon
      */
@@ -60,12 +61,13 @@
     typedef uint8_t Lock_t[16];               /* 128 bits */
     typedef int8_t PowerLevels_t[NUM_POWER_MODES];
 
-    #define EDDYSTONE_MAX_FRAMETYPE 3
+    // There are currently 3 subframes defined, URI, UID, and TLM
+#define EDDYSTONE_MAX_FRAMETYPE 3
     void (*frames[EDDYSTONE_MAX_FRAMETYPE])(uint8_t *, uint32_t);
     uint8_t frameIndex;
     static const int URI_DATA_MAX = 18;
     typedef uint8_t  UriData_t[URI_DATA_MAX];
-    
+
     // UID Frame Type subfields
     static const int UID_NAMESPACEID_SIZE = 10;
     typedef uint8_t  UIDNamespaceID_t[UID_NAMESPACEID_SIZE];
@@ -76,7 +78,7 @@
     static const uint8_t FRAME_TYPE_UID = 0x00;
     static const uint8_t FRAME_TYPE_URL = 0x10;
     static const uint8_t FRAME_TYPE_TLM = 0x20;
-    
+
     static const uint8_t FRAME_SIZE_TLM = 14; // TLM frame is a constant 14Bytes
     static const uint8_t FRAME_SIZE_UID = 20; // includes RFU bytes
 
@@ -92,7 +94,7 @@
         UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B
         UIDInstanceID_t  uidInstanceID;  // UUID type, Instance ID,  6B
     };
-    
+
     /**
      * @param[ref]    ble
      *                    BLEDevice object for the underlying controller.
@@ -179,8 +181,7 @@
     /* Start out by advertising the configService for a limited time after
      * startup; and switch to the normal non-connectible beacon functionality
      * afterwards. */
-    void setupZipBeaconConfigAdvertisements()
-    {
+    void setupZipBeaconConfigAdvertisements() {
         const char DEVICE_NAME[] = "eddystone Config";
 
         ble.clearAdvertisingPayload();
@@ -205,59 +206,56 @@
         ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
         ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC));
     }
-    
+
     /*
-    *  Set Eddystone UID Frame information. 
+    *  Set Eddystone UID Frame information.
     *  @param[in] power   TX Power in dB measured at 0 meters from the device. Range of -100 to +20 dB.
     *  @param namespaceID 10B namespace ID
     *  @param instanceID  6B instance ID
-    *  @param RFU         2B of RFU, initialized to 0x0000 and not broadcast, included for future reference. 
+    *  @param RFU         2B of RFU, initialized to 0x0000 and not broadcast, included for future reference.
     *
     */
-    void setUIDFrameData(int8_t power, UIDNamespaceID_t namespaceID, UIDInstanceID_t instanceID, uint16_t RFU = 0x00)
-    {
+    void setUIDFrameData(int8_t power, UIDNamespaceID_t namespaceID, UIDInstanceID_t instanceID, uint16_t RFU = 0x0000) {
         defaultUidPower = power;
         memcpy(defaultUidNamespaceID, namespaceID, UID_NAMESPACEID_SIZE);
         memcpy(defaultUidInstanceID,  instanceID,  UID_INSTANCEID_SIZE);
-        uidRFU = (uint16_t)RFU; // this is probably bad form, but it doesnt really matter yet. 
+        uidRFU = (uint16_t)RFU; // this is probably bad form, but it doesnt really matter yet.
         return;
     }
-    
+
     /*
     *  Construct UID frame from private variables
     *  @param[in/out] Data pointer to array to store constructed frame in
     *  @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
-    *  @return number of bytes used. negative number indicates error message. 
+    *  @return number of bytes used. negative number indicates error message.
     */
-    int constructUIDFrame(uint8_t * Data, uint8_t maxSize)
-    {
-        if(maxSize < FRAME_SIZE_UID){
-            return -1; // not enough space to encode UIDframe in advertising packet. 
+    int constructUIDFrame(uint8_t * Data, uint8_t maxSize) {
+        if(maxSize < FRAME_SIZE_UID) {
+            return -1; // not enough space to encode UIDframe in advertising packet.
         }
         int index = 0;
         Data[index++] = FRAME_TYPE_UID;                     // 1B  Type
         Data[index++] = defaultUidPower;                    // 1B  Power @ 0meter
-        for(int x = 0; x < UID_NAMESPACEID_SIZE; x++){      // 10B Namespce ID
+        for(int x = 0; x < UID_NAMESPACEID_SIZE; x++) {     // 10B Namespce ID
             Data[index++] = defaultUidNamespaceID[x];
-            } 
-        for(int x = 0; x< UID_INSTANCEID_SIZE; x++){        // 6B  Instance ID
+        }
+        for(int x = 0; x< UID_INSTANCEID_SIZE; x++) {       // 6B  Instance ID
             Data[index++] = defaultUidInstanceID[x];
-            }
-        if(0x00 != uidRFU){                                 // 2B RFU, include if non-zero, otherwise ignore
+        }
+        if(0x00 != uidRFU) {                                // 2B RFU, include if non-zero, otherwise ignore
             Data[index++] = (uint8_t)(uidRFU >> 8);
             Data[index++] = (uint8_t)uidRFU;
         }
         return index;
     }
-    
+
     /*
-    *  Set Eddystone URL Frame information. 
+    *  Set Eddystone URL Frame information.
     *  @param[in] power   TX Power in dB measured at 0 meters from the device.
-    *  @param url         URL to encode 
+    *  @param url         URL to encode
     *  @return            false on success, true on failure.
     */
-    bool setURLFrameData(int8_t power, const char * url)
-    {
+    bool setURLFrameData(int8_t power, const char * url) {
         defaultUrlPower = power;
         encodeURI(url, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting
         if (defaultUriDataLength > URI_DATA_MAX) {
@@ -265,53 +263,50 @@
         }
         return false;
     }
-    
+
     /*
     *  Construct URL frame from private variables
     *  @param[in/out] Data pointer to array to store constructed frame in
     *  @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
-    *  @return number of bytes used. negative number indicates error message. 
+    *  @return number of bytes used. negative number indicates error message.
     */
-    int constructURLFrame(uint8_t * Data, uint8_t maxSize)
-    {
-        if(maxSize < (2 + defaultUriDataLength)){
-            return -1; // not enough space to encode URL frame in advertising packet. 
+    int constructURLFrame(uint8_t * Data, uint8_t maxSize) {
+        if(maxSize < (2 + defaultUriDataLength)) {
+            return -1; // not enough space to encode URL frame in advertising packet.
         }
         int index = 0;
         Data[index++] = FRAME_TYPE_URL;                     // 1B  Type
-        Data[index++] = defaultUrlPower;                    // 1B  TX Power
-        for(int x = 0; x < defaultUriDataLength; x++){      // 18B of URL Prefix + encoded URL 
+        Data[index++] = params.txPowerMode;                    // 1B  TX Power
+        for(int x = 0; x < defaultUriDataLength; x++) {     // 18B of URL Prefix + encoded URL
             Data[index++] = defaultUriData[x];
         }
-        return index;        
+        return index;
     }
-    
+
     /*
-    *  Set Eddystone TLM Frame information. 
+    *  Set Eddystone TLM Frame information.
     *  @param[in] Version    of the TLM beacon data format
     *  @param batteryVoltage in milivolts
     *  @param beaconTemp     in 8.8 floating point notation
     *
     */
-    void setTLMFrameData(uint8_t version, uint16_t batteryVoltage, uint16_t beaconTemp, uint32_t pduCount = 0, uint32_t timeSinceBoot = 0)
-    {
+    void setTLMFrameData(uint8_t version, uint16_t batteryVoltage, uint16_t beaconTemp, uint32_t pduCount = 0, uint32_t timeSinceBoot = 0) {
         TlmVersion = version;
         TlmBatteryVoltage = batteryVoltage;
         TlmBeaconTemp = beaconTemp;
         TlmPduCount = pduCount; // reset
         TlmTimeSinceBoot = timeSinceBoot; // reset
-        return;        
+        return;
     }
-    
+
     /*
     *  Construct TLM frame from private variables
     *  @param[in/out] Data pointer to array to store constructed frame in
     *  @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
-    *  @return number of bytes used. negative number indicates error message. 
+    *  @return number of bytes used. negative number indicates error message.
     */
-    int constructTLMFrame(uint8_t * Data, uint8_t maxSize)
-    {
-        if(maxSize < FRAME_SIZE_TLM){       // error, not enough space to add TLM frame. 14B, every time
+    int constructTLMFrame(uint8_t * Data, uint8_t maxSize) {
+        if(maxSize < FRAME_SIZE_TLM) {      // error, not enough space to add TLM frame. 14B, every time
             return -1;
         }
         int index = 0;
@@ -329,93 +324,102 @@
         Data[index++] = (uint8_t)(TlmTimeSinceBoot>>8);    // Time Since Boot [1]
         Data[index++] = (uint8_t)(TlmTimeSinceBoot>>16);   // Time Since Boot [2]
         Data[index++] = (uint8_t)(TlmTimeSinceBoot>>24);   // Time Since Boot [3]
-        
+
         return index;
     }
-    
+
     /*
     *  Update the TLM frame battery voltage value
     *  @param[in] voltagemv Voltage to update the TLM field battery voltage with (in mV)
     *  @return nothing
     */
-    void updateTlmBatteryVoltage(uint16_t voltagemv){
+    void updateTlmBatteryVoltage(uint16_t voltagemv) {
         TlmBatteryVoltage = voltagemv;
-        return;        
+        return;
     }
-    
+
     /*
-    *  Update the TLM frame beacon temperature 
+    *  Update the TLM frame beacon temperature
     *  @param[in] temp Temperature of beacon (in 8.8fpn)
     *  @return nothing
     */
-    void updateTlmBeaconTemp(uint16_t temp){
+    void updateTlmBeaconTemp(uint16_t temp) {
         TlmBeaconTemp = temp;
-        return;        
+        return;
     }
-    
+
     /*
     *  Update the TLM frame PDU Count field
     *  @param[in] pduCount Number of Advertisiting frames sent since powerup
     *  @return nothing
     */
-    void updateTlmPduCount(uint32_t pduCount){
+    void updateTlmPduCount(uint32_t pduCount) {
         TlmPduCount = pduCount;
-        return;        
+        return;
     }
-    
+
     /*
     *  Update the TLM frame Time since boot in 0.1s incriments
     *  @param[in] timeSinceBoot Time since boot in 0.1s incriments
     *  @return nothing
     */
-    void updateTlmTimeSinceBoot(uint32_t timeSinceBoot){
+    void updateTlmTimeSinceBoot(uint32_t timeSinceBoot) {
         TlmTimeSinceBoot = timeSinceBoot;
-        return;        
+        return;
     }
-    
+
     /*
     *  Callback from onRadioNotification(), used to update the PDUCounter and maybe other stuff eventually?
     *
     *
     */
-    void pduCountCallback(){
+    //void radioNotificationCallback(bool radioActive){
+    void radioNotificationCallback(void) {
         // Update Time and PDUCount
         TlmPduCount++;
-        TlmTimeSinceBoot += 10;
-        
+        TlmTimeSinceBoot++;
+
         // Every 1 second switch the frame types
-        if((TlmPduCount % 10) == 1){
+        if((TlmPduCount % 10) == 1) {
             frameIndex = frameIndex % EDDYSTONE_MAX_FRAMETYPE;
             uint8_t serviceData[SERVICE_DATA_MAX];
             unsigned serviceDataLen = 0;
             //switch payloads
             serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
             serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
-            switch(frameIndex){
+            switch(frameIndex) {
                 case 0:
-                    constructTLMFrame(serviceData+serviceDataLen,20);
+                    printf("constructing TLM Frame: ");
+                    serviceDataLen += constructTLMFrame(serviceData+serviceDataLen,20);
                     break;
                 case 1:
-                    constructURLFrame(serviceData+serviceDataLen,20);
+                    printf("constructing URL Frame: ");
+                    serviceDataLen += constructURLFrame(serviceData+serviceDataLen,20);
                     break;
                 case 2:
-                    constructUIDFrame(serviceData+serviceDataLen,20);
+                    printf("constructing UID Frame: ");
+                    serviceDataLen += constructUIDFrame(serviceData+serviceDataLen,20);
                     break;
-                }
+            }
             ble.accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen);
+            for(int x = 0; x<serviceDataLen; x++) {
+                printf("%2.2x:",serviceData[x]);
+            }
+            printf("\r\n");
         }
         //TODO: add bit to keep timer / update time
         frameIndex++;
-        return;        
+        return;
     }
 
     /* Helper function to switch to the non-connectible normal mode for ZipBeacon. This gets called after a timeout. */
-    void setupZipBeaconAdvertisements()
-    {
+    void setupZipBeaconAdvertisements() {
+        printf("Switching Config -> adv\r\n");
         uint8_t serviceData[SERVICE_DATA_MAX];
         unsigned serviceDataLen = 0;
         // Initialize Frame transition
         frameIndex = 0;
+        uidRFU = 0;
 
         /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */
         ble.shutdown();
@@ -438,12 +442,12 @@
         ble.setAdvertisingInterval(beaconPeriod);
         ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
         ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_EDDYSTONE, sizeof(BEACON_EDDYSTONE));
-        
+
         setTLMFrameData(0x00,22,33,0,0); // Initialize TLM Data, for testing, remove for release
         updateTlmPduCount(0);
         updateTlmTimeSinceBoot(0);
-        
-        // Construct TLM Frame in initial advertising. 
+
+        // Construct TLM Frame in initial advertising.
         serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
         serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
         constructTLMFrame(serviceData+serviceDataLen,20);
@@ -454,12 +458,13 @@
 //        }
 
         // attach callback to count number of sent packets
-       //TODO: ble.gap().onRadioNotification(pduCountCallback);
+        //ble.gap().onRadioNotification(this,&ZipBeaconConfigService::radioNotificationCallback);
         ble.accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen);
-        //callbackTick.attach(&pduCountCallback,2.0); // switch services every 2 seconds
+        callbackTick.attach(this,&ZipBeaconConfigService::radioNotificationCallback, 0.1); // switch services every 2 seconds
+        //callbackTick.attach(stupidWrapperFn,2.0);
     }
 
-  private:
+private:
     // True if the lock bits are non-zero
     bool isLocked() {
         Lock_t testLock;
@@ -548,7 +553,7 @@
                                       reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t));
     }
 
-  private:
+private:
     void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
         if (lockedState) {
             authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
@@ -629,7 +634,7 @@
     uint8_t             lockedState;
     bool                initSucceeded;
     uint8_t             resetFlag;
-    
+
     // Private Variables for Telemetry Data
     uint8_t                      TlmVersion;
     volatile uint16_t            TlmBatteryVoltage;
@@ -647,7 +652,7 @@
     ReadWriteGattCharacteristic<uint16_t>      beaconPeriodChar;
     WriteOnlyGattCharacteristic<uint8_t>       resetChar;
 
-  public:
+public:
     /*
      *  Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification).
      */
--- a/main.cpp	Mon Jul 20 04:29:07 2015 +0000
+++ b/main.cpp	Mon Jul 20 19:31:40 2015 +0000
@@ -23,7 +23,7 @@
 
 BLE ble;
 ZipBeaconConfigService *zipBeaconConfig;
-InterruptIn button(p17);
+//InterruptIn button(p17);
 
 /**
  * URIBeaconConfig service can operate in two modes: a configuration mode which
@@ -34,14 +34,14 @@
  *
  * The following help with this switch.
  */
-static const int CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS = 60;  // Duration after power-on that config service is available.
+static const int CONFIG_ADVERTISEMENT_TIMEOUT_SECONDS = 5;  // Duration after power-on that config service is available.
 Ticker configAdvertisementTimeoutTicker;
 
 //
 // Have to use this to add a interrupt, because C++ is stupid. 
 //
 void stupidWrapperFn(){
-    zipBeaconConfig->pduCountCallback();
+    zipBeaconConfig->radioNotificationCallback();
     }
 
 /**
@@ -56,6 +56,7 @@
         ble.gap().startAdvertising();
 
         configAdvertisementTimeoutTicker.detach(); /* disable the callback from the timeout Ticker. */
+        printf("removing config service\r\n");
     }
 }
 
@@ -65,10 +66,12 @@
 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
 {
     ble.gap().startAdvertising();
+    printf("disconnect CB\r\n");
 }
 
 int main(void)
 {
+    printf("Starting Example\r\n");
     ble.init();
     ble.gap().onDisconnection(disconnectionCallback);
 
@@ -84,7 +87,7 @@
 
     /* Initialize a zipBeaconConfig service providing config params, default URI, and power levels. */
     static ZipBeaconConfigService::PowerLevels_t defaultAdvPowerLevels = {-20, -4, 0, 10}; // Values for ADV packets related to firmware levels
-    zipBeaconConfig = new ZipBeaconConfigService(ble, params, !fetchedFromPersistentStorage, "http://uribeacon.org", defaultAdvPowerLevels);
+    zipBeaconConfig = new ZipBeaconConfigService(ble, params, !fetchedFromPersistentStorage, "http://mbed.org", defaultAdvPowerLevels);
     if (!zipBeaconConfig->configuredSuccessfully()) {
         error("failed to accommodate URI");
     }
@@ -96,8 +99,8 @@
 
     ble.gap().startAdvertising(); /* Set the whole thing in motion. After this call a GAP central can scan the zipBeaconConfig
                                    * service. This can then be switched to the normal URIBeacon functionality after a timeout. */
-
-    button.rise(&stupidWrapperFn);
+    printf("Running...\r\n");
+    //button.rise(&stupidWrapperFn);
     while (true) {
         ble.waitForEvent();
     }