BLE ADV Gateway, converts advertisement to proper JSON serial output

Dependencies:   BLE_API mbed mbedtls nRF51822

Revision:
9:1ea51b2048a8
Parent:
8:46c5e0bfab05
Child:
10:9db2ac7e1eea
diff -r 46c5e0bfab05 -r 1ea51b2048a8 main.cpp
--- a/main.cpp	Mon Jul 10 03:57:10 2017 +0000
+++ b/main.cpp	Mon Jul 10 04:13:45 2017 +0000
@@ -1,198 +1,196 @@
-/*
-
- Eric Tsai
- todo:  hash mac to create unqiue identifier for "my" sensors.
-
-
- */
-
-//required to call the ecb functions
-extern "C"
-{
-   #include "nrf_ecb.h"
-}
- 
-#include "mbed.h"
-#include "toolchain.h"
-#include "ble/BLE.h"
-#include "TMP_nrf51/TMP_nrf51.h"
-
-//comment out when done with debug uart, else eats batteries
-#define MyDebugEnb 1
-
-//Pin "P0.4" on nRF51822 = mbed "p4".
-//InterruptIn is pulled-up.  GND the pin to activate.
-
-// waveshare board ******
-//InterruptIn button1(p10);
-//InterruptIn button2(p11);
-
-// purple board ******
-InterruptIn button1(p23);
-InterruptIn button2(p24);
-
+/* 
 
-//Serial device(p9, p11);  // tx, rx, purple board and Rigado
-#if MyDebugEnb
-// if you see ~1mA consumption during sleep, that's because uart is enabled.
-Serial device(p9, p11);  //nRF51822 uart :  TX=p9.  RX=p11
-#endif
-
-//InterruptIn button(p4);     //Pin P0.4 on  = mbed "p3"; 
-
-
-static Ticker tic_adv;   //stop adv
-static Ticker tic_debounce; //debounce I/O
-static Ticker tic_periodic; //regular updates
-//static TMP_nrf51  tempSensor;
-static bool flag_update_io = false;
-static bool flag_periodic_call = false;
-static bool flag_detach_adv_tic = false;
-static bool flag_set_debounce_tic = false;  //not used
-
-//static DigitalOut alivenessLED(LED1, 1);
-float mySensor = 2.0f;
-
-
-/* Optional: Device Name, add for human read-ability */
-const static char     DEVICE_NAME[] = "CUU";
-
-/* You have up to 26 bytes of advertising data to use. */
-/*
-Advertisement
-
-DECvolt:3.11111111,mag:1
-AdvData[0-2] = Look for DEC on observer
-AdvData[3] = beginning of data
-*/
-//full with nullls
-static uint8_t AdvData[] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};   /* Example of hex data */
-char buffer[10]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //battery analog reading
-uint8_t magnet_near=0;
+ 
+ Eric Tsai
+ 
+Scans for advertisements and captures the ones identified as mine
+Takes UUID fields and injects the MAC and RSSI data.  Assumes UUID JSON data.
 
 
 
-static uint8_t key[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4};
-//26 bytes adv data
-static uint8_t encrypted[26] = {0x0,0x0,0x0,0x1,0x1,0x1,0x2,0x2,0x2,0x3,0x3,0x3,0x4,0x4,0x4,0x5,0x5,0x5,0x6,0x6,0x6,0x7,0x7,0x7,0x8,0x8};   /* Example of hex data */
-//static uint8_t key_buf[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4};
-static uint8_t key_buf[16] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x1, 0x2};
-static uint8_t src_buf[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4};
-static uint8_t des_buf[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4};
+----------------------------------------------
+
+
+Example output:
+{"mac":"c56e806d7cfb","rssi":-54,"volt":3.01,"mag/p":2}
+added timer
+{"mac":"c56e806d7cfb","rssi":-54,"tmr":3232,"volt":3.01,"mag/p":2}
+{"mac":"c2f154bb0af9","rssi":-76,"tmr":250,"volt":3.14,"mag/p":1}
 
-//const static uint8_t AdvData[] = {"ChangeThisData"};         /* Example of character data */
+todo:  hash MAC to create unique identifiers for sensors seen as "mine"
+todo:  create search for ensure gateway only accepts tmr values that match, else
+        are consecutive transmits in case we miss power up transmit.
+ */
 
+#include "mbed.h"
+#include "ble/BLE.h"
+#include "mbedtls/aes.h"
 
 
-/* **** NOT USED **** */
-//16byte UUID loading happens here
-//Look at <GapAdvertisingData.h> for rest of definition
-struct ApplicationData_t {
-    //Byte 0:  AppID High Byte
-    //Byte 1:  AppID Low Byte
-    //Byte 2:  sensor High Word
-    //Byte 3:
-    //Byte 4:
-    //Byte 5:  sensor Low Byte
-    
-    
-    //app ID is 16 bit, (0xFEFE)
-    uint16_t    applicationSpecificId; /* An ID used to identify temperature value in the manufacture specific AD data field */
-    
-    //float = 32-bit.  
-    //tsai: change this to uint32_t!!!
-    TMP_nrf51::TempSensorValue_t tmpSensorValue;        /* this is a float (32-bit), user data */
-} PACKED;
+//comment out when done with debug uart, else eats batteries
+#define MyDebugEnb 0
 
 
+//DigitalOut led1(LED1, 1);
+Ticker     ticker;
 
-void debounce_Callback(void)
+//aes stuff
+uint8_t src_buf[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4};
+uint8_t des_buf[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4};
+
+mbedtls_aes_context aes;
+
+unsigned char iv[16] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x1, 0x2};       //16-byte key
+size_t input_len = 16;
+size_t output_len = 0;
+
+Serial device(p9, p11);  //nRF51822 uart :  TX=p9.  RX=p11
+
+void periodicCallback(void)
 {
-    tic_debounce.detach();
-    flag_set_debounce_tic = false;      //not used
-    flag_update_io = true;  //start advertising
-    /* Note that the buttonPressedCallback() executes in interrupt context, so it is safer to access
-     * BLE device API from the main thread. */
-    //buttonState = PRESSED;
+    //led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
+    //device.printf("periodic 5...");
+    //device.printf("\r\n");
 }
 
-//----- button rising ---
-void buttonPressedCallback(void)
-{
+void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
 
 
-    //flag_update_io = true;
-    
-    tic_debounce.attach(debounce_Callback, 1); //ok to attach multiple times, first one wins
+    //BLE MAC Address (6 bytes):
+    //      params->peerAddr[5]
+    //      params->peerAddr[4]
+    //      ...
+    //      params->peerAddr[0]
+    //RSSI = params->rssi
+    //Payload
+    //  params->advertisingData[#<advertisingDataLen]
     
 
-    //buttonState = PRESSED;
     
-    /*
-    if (flag_set_debounce_tic == false)
-    {
-        flag_set_debounce_tic = true;
-        
-    }
-    */
-}
-
-//----- button falling ---
-void buttonReleasedCallback(void)
-{
-    
+    //              [<---MY DATA-->]
+    //0x02      0x01    0x06    0x06    0xff    D   E   C   ?  ?
+    //0         1       2       3       4       5   6   7   8   9
 
-    //flag_update_io = true;
-    
-    tic_debounce.attach(debounce_Callback, 1);
-    
-    
-  
-}
-
+    if ( (params->advertisingDataLen) >= 8)
+    {
+        //if one of "ours", these UUID fields will be this value.  Arbitrary " 
+        //todo:  use MAC to make a hash of what these 3 bytes should be.
+        if ( (params->advertisingData[5] == 0x44) && (params->advertisingData[6] == 0x45) && (params->advertisingData[7]==0x43) )
+        {
+            /*
+            BLE Received from MAC C2F154BB0AF9
+            volt:3.11,mag:1
+            
+            uart-transmit:
+            mac:C2F154BB0AF9,rssi:##,volt:3.11,mag:1
+            
+            /ble/C2F154BB0AF9/rssi
+            /ble/C2F154BB0AF9/1st_token
+            /ble/c2F153
+            
+            */
+            /*
+            device.printf("Adv peerAddr: [%02x%02x%02x%02x%02x%02x] rssi %d, ScanResp: %u, AdvType: %u\r\n",
+              params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
+              params->rssi, params->isScanResponse, params->type);
+            */
+            device.printf("{\"mac\":\"%02x%02x%02x%02x%02x%02x\",\"rssi\":%d,",
+                params->peerAddr[5], 
+                params->peerAddr[4], 
+                params->peerAddr[3], 
+                params->peerAddr[2], 
+                params->peerAddr[1], 
+                params->peerAddr[0],
+                params->rssi
+                );
+            //mac:"c2f154bb0af9"
+            
+            //device.printf("\r\n copy adv length:  %d \r\n", params->advertisingDataLen);
+            for (int i = 0; i<16; i++)
+            {
+                
+                src_buf[i]=params->advertisingData[i+8];
+#if MyDebugEnb
+                device.printf("%x ", src_buf[i]);
+#endif
+            }
+#if MyDebugEnb
+            device.printf("...\r\n  ");
+#endif    
+            mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, src_buf, des_buf );
+#if MyDebugEnb
+            
+            device.printf("decoded first 16 bytes \r\n");
+            for (int i = 0; i<16; i++)
+            {
+                //device.printf("%02x", params->advertisingData[index]);
+                if (i < 2)
+                {
+                   device.printf("%x ", des_buf[i]); 
+                }
+                else
+                {
+                    device.printf("%c ", des_buf[i]);
+                }
+            }
+            device.printf("done----- \r\n");
+#endif
 
-void stop_adv_Callback(void)
-{
-    //stops advertising after X seconds
-    /* Note that the Callback() executes in interrupt context, so it is safer to do
-     * heavy-weight sensor polling from the main thread (where we should be able to block safely, if needed). */
-    
-    //tic_adv.detach();
-    
-    flag_detach_adv_tic = true;
-    //ble.gap().stopAdvertising();
-    
+            //print clock
+            //     "tmr":3232,
+            //des_buf[0] = lower byte, des_buf[1] = higher byte
+            uint16_t beacon_timer = des_buf[0] | (des_buf[1] << 8);
+            device.printf("\"tmr\":%d,", beacon_timer);
+            //device.printf("\"tmr\":%d,", des_buf[0]);
+            
+            for (int i = 2; i< 16; i++)
+            {
+                //device.printf("%02x", params->advertisingData[index]);
+                device.printf("%c", des_buf[i]);
+            }
 
-}
+            if (params->advertisingDataLen > 24)
+            {
+                for (unsigned index = 24; index < params->advertisingDataLen; index++)
+                {
+                    //device.printf("%02x", params->advertisingData[index]);
+                    device.printf("%c", params->advertisingData[index]);
+                }   
+            }
+
+            /*
+            for (unsigned index = 8; index < params->advertisingDataLen; index++)
+            {
+                //device.printf("%02x", params->advertisingData[index]);
+                device.printf("%c", params->advertisingData[index]);
+            }
+            */
+            
+            device.printf("}");
+            device.printf("\r\n");
+            
+            /*
+            mac:c2f154bb0af9,rssi:-55,volt:3.05,mag:1
+            mac:c2f154bb0af9,rssi:-67,volt:3.05,mag:1
+            mac:c2f154bb0af9,rssi:-60,volt:3.07,mag:0
+            */
+            
+        }//end if it's our adv
+    }//end if advertisingDataLen
 
 
 
 
-
-void periodic_Callback(void)
-{
-    flag_update_io = true;
-    flag_periodic_call = true;
-}
-
-void setupApplicationData(ApplicationData_t &appData)
-{
-    // two byte ID:  0xFEFE
-    static const uint16_t APP_SPECIFIC_ID_TEST = 0xFEFE;        //2 byte application ID
-
-    appData.applicationSpecificId = APP_SPECIFIC_ID_TEST;
-    //appData.tmpSensorValue        = tempSensor.get();
-    appData.tmpSensorValue        = mySensor;
-}
-
-
+}//end advertisementCallback
 
 /**
- * This function is called when the ble initialization process has failled
+ * This function is called when the ble initialization process has failed
  */
 void onBleInitError(BLE &ble, ble_error_t error)
 {
     /* Initialization error handling should go here */
+    device.printf("periodic callback ");
+    device.printf("\r\n");
 }
 
 /**
@@ -213,416 +211,27 @@
     if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
         return;
     }
-    
-    /* Set device name characteristic data */
-    ble.gap().setDeviceName((const uint8_t *) DEVICE_NAME);
-
-    /* Setup advertising payload */
-    //set modes "no EDR", "discoverable" for beacon type advertisements
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
-    
-    //set device profile in ADV/GATT
-    //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);
-    
-    //set advertising data (ADV data)
-    //ApplicationData_t appData;
-    //setupApplicationData(appData);
-    //in /BLE_API/ble/GapAdvertisingData.h:  sets payload (uuid)
-    //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t));
-
-    //from GAP example
-    /* Sacrifice 2B of 31B to AdvType overhead, rest goes to AdvData array you define */
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, AdvData, sizeof(AdvData));
-
-    /* Setup advertising parameters:  not connectable */
-    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
-    ble.gap().setAdvertisingInterval(300);  //one advertisment every 300ms.  Self tickers, so you don't have to worry.
-
-
-
-    //don't start advertising on init.  Only advertise on pin interrupt.
-    //ble.gap().startAdvertising();
-}
-
-
-//https://developer.mbed.org/users/MarceloSalazar/notebook/measuring-battery-voltage-with-nordic-nrf51x/
-void my_analogin_init(void)
-{
-    NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
-    NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
-                      (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
-                      (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
-                      (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos) |
-                      (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
-}
-
-uint16_t my_analogin_read_u16(void)
-{
-    NRF_ADC->CONFIG     &= ~ADC_CONFIG_PSEL_Msk;
-    NRF_ADC->CONFIG     |= ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos;
-    NRF_ADC->TASKS_START = 1;
-    
-    
-    //while loop doesn't actually loop until reading comlete, use a wait.
-    while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {};
-    wait_ms(2);
-
-    //save off RESULT before disabling.
-    //uint16_t myresult = (uint16_t)NRF_ADC->RESULT;
-    
-    //disable ADC to lower bat consumption
-    //NRF_ADC->TASKS_STOP = 1;
-    //NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled;    //disable to shutdown ADC & lower bat consumption
-    
-    return (uint16_t)NRF_ADC->RESULT; // 10 bit
-    //return myresult;
+ 
+    // in ms.  Duty cycle = (interval / window);  200ms/500ms = 40%
+    ble.gap().setScanParams(500 /* scan interval */, 200 /* scan window */);
+    ble.gap().startScan(advertisementCallback);
 }
 
 int main(void)
 {
-
-#if MyDebugEnb
     device.baud(9600);
-    device.printf("started sensor node 36 ");
+    device.printf("started main 04... ");
     device.printf("\r\n");
-#endif
-
-    
+    ticker.attach(periodicCallback, 5);
     
-    Timer myTimer;  //timed advertising
-    myTimer.start();
-
-
-    AdvData[0] = 0x44;          //D
-    AdvData[1] = 0x45;          //E
-    AdvData[2] = 0x43;          //C
-    AdvData[3] = 0x22;          //"
-    AdvData[4] = 0x76;          //V volt
-    AdvData[5] = 0x6f;          //o
-    AdvData[6] = 0x22;          //"
-    AdvData[7] = 0x3a;          //:
-    AdvData[8] = 0x24;          //3     #
-    AdvData[9] = 0x24;          //.     #
-    AdvData[10] = 0x24;         //1     #
-    AdvData[11] = 0x24;         //1     #
-    AdvData[12] = 0x2c;         //,     
-    AdvData[13] = 0x22;         //" mag
-    AdvData[14] = 0x6d;         //a
-    AdvData[15] = 0x22;         //"
-    AdvData[16] = 0x3a;         //:
-    AdvData[17] = 0x24;         //0 or 1, 30 or 31
-
-    button1.fall(buttonPressedCallback);
-    button1.rise(buttonReleasedCallback);
-    button1.mode(PullNone);
-    button1.fall(NULL);
-    button1.rise(NULL); 
+    //mbedtls_aes_init(&aes);
+    mbedtls_aes_setkey_dec( &aes, iv, 128 );
+    //mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, input, output );
 
     BLE &ble = BLE::Instance();
     ble.init(bleInitComplete);
-    
-    //debug uart
-    //device.baud(115200);
-    float bat_reading;  //hold battery voltage reading (Vbg/Vcc)
-    
-    my_analogin_init();//routes band-gap to analog input
-
-    /* SpinWait for initialization to complete. This is necessary because the
-     * BLE object is used in the main loop below. */
-    while (ble.hasInitialized() == false) { /* spin loop */ }
-    
-    //every X seconds, sends period update, up to 1800 (30 minutes)
-    tic_periodic.attach(periodic_Callback, 10);
 
     while (true) {
-        
-        uint16_t mySeconds =(uint16_t)(myTimer.read_ms()/1000); //problem:  mySeconds is only 2 byte
-        //reading the ADV value, only goes up to 0-255;
-        //reading the uart:  current time in seconds: -1782, goes negative.
-        //need to be able to count 1800 seconds since that's the length of timer.
-        
-#if MyDebugEnb
-        device.printf("current time in seconds: %d \r\n", mySeconds);
-#endif
-        //**** set which pin should be interrupt, set pullups ***
-        
-        //set both pins to pull-up, so they're not floating when we read state
-        button1.mode(PullUp);
-        button2.mode(PullUp);
-        
-        //wait_ms(300);   //contact settle
-        
-
-        //AdvData[12] is automatically CR?  why?
-        
-        //0x33 0x2E 0x33 0x32 0x13
-        //   3    .    3    2   CR
-        
-        //expect either button1 or button2 is grounded, b/c using SPDT reed switch
-        //the "common" pin on the reed switch should be on GND
-        uint8_t button1_state = button1.read();
-        uint8_t button2_state = button2.read();
-        
-        
-        //let's just update the pins on every wake.  Insurance against const drain.
-        //if state == 0, pin is grounded.  Unset interrupt and float pin
-        //set the other input
-        if ( (button1_state == 0) && (button2_state == 1) )
-        {
-            magnet_near = 1;
-            //AdvData[4] = 0x11;  //dont' set ADV data directly.  Using json now, need spacing
-            //button1.disable_irq() //don't know if disables IRQ on port or pin
-            button1.fall(NULL);     //disable interrupt
-            button1.rise(NULL);     //disable interrupt
-            button1.mode(PullNone); //float pin to save battery
-            
-            //button2.disable_irq() //don't know if disables IRQ on port or pin
-            button2.fall(buttonReleasedCallback);     //disable interrupt
-            button2.rise(buttonReleasedCallback);     //disable interrupt
-            button2.mode(PullUp); //float pin to save battery
-        }
-        else if ( (button1_state == 1) && (button2_state == 0) )       //assume other pin is open circuit
-        {
-            magnet_near = 0;
-            //AdvData[4] = 0x22;    //dont' set ADV data directly.  Using json now, need spacing
-            //button1.disable_irq() //don't know if disables IRQ on port or pin
-            button1.fall(buttonReleasedCallback);     //disable interrupt
-            button1.rise(buttonReleasedCallback);     //disable interrupt
-            button1.mode(PullUp); //float pin to save battery
-            
-            //button2.disable_irq() //don't know if disables IRQ on port or pin
-            button2.fall(NULL);     //disable interrupt
-            button2.rise(NULL);     //disable interrupt
-            button2.mode(PullNone); //float pin to save battery
-        }    
-        else    //odd state, shouldn't happen, suck battery and pullup both pins
-        {
-            magnet_near = 2;
-            //AdvData[4] = 0x33;
-            //button1.disable_irq() //don't know if disables IRQ on port or pin
-            button1.fall(buttonReleasedCallback);     //disable interrupt
-            button1.rise(buttonReleasedCallback);     //disable interrupt
-            button1.mode(PullUp); //float pin to save battery
-            
-            //button2.disable_irq() //don't know if disables IRQ on port or pin
-            button2.fall(buttonReleasedCallback);     //disable interrupt
-            button2.rise(buttonReleasedCallback);     //disable interrupt
-            button2.mode(PullUp); //float pin to save battery
-        }         
-        
-        
-        if (flag_update_io) {
-            /* Do blocking calls or whatever hardware-specific action is
-             * necessary to poll the sensor. */
-
-            //analog reading consumes 940uA if not disabled
-            bat_reading = (float)my_analogin_read_u16();    
-            bat_reading = (bat_reading * 3.6) / 1024.0;
-#if MyDebugEnb
-            device.printf("bat reading: %f \r\n", bat_reading);
-#endif
-
-            //memset(&buffer[0], 0, sizeof(buffer));      //clear out buffer
-            //sprintf (buffer, "%f.2", bat_reading);    //don't know what i'm doing
-            //sprintf (buffer, "%.2f", bat_reading);
-            //AdvData[8] = buffer[0]; //"3"=0x33
-            //AdvData[9] = buffer[1]; //"."=0x2E
-            //AdvData[10] = buffer[2];//"3"=0x33
-            //AdvData[11] = buffer[3];//"2"=0x32
-            
-            //disable ADC
-            NRF_ADC->TASKS_STOP = 1;
-            NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled;    //disable to shutdown ADC & lower bat consumption
-
-            //***********************************
-            //form JSON string in ADV_DATA
-            //1)  volts starts at AdvData[8]
-            
-
-            memset(&AdvData[0], 0, sizeof(AdvData));
-            uint8_t JSON_loc=0; //DEC"vo": <---
-
-            AdvData[JSON_loc] = 0x44;          //D
-            JSON_loc++;
-            AdvData[JSON_loc] = 0x45;          //E
-            JSON_loc++;
-            AdvData[JSON_loc] = 0x43;          //C
-            JSON_loc++;
-            AdvData[JSON_loc] = mySeconds & 0xFF;           //reserved for timer
-            JSON_loc++;
-            AdvData[JSON_loc] = (mySeconds >> 8) & 0xFF;;           //reserved for timer
-            JSON_loc++;
-            AdvData[JSON_loc] = 0x22;          //"
-            JSON_loc++;
-            AdvData[JSON_loc] = 0x76;          //V volt
-            JSON_loc++;
-            AdvData[JSON_loc] = 0x6f;          //o
-            JSON_loc++;
-            AdvData[JSON_loc] = 0x6C;          //l
-            JSON_loc++;
-            AdvData[JSON_loc] = 0x74;          //t
-            JSON_loc++;
-            AdvData[JSON_loc] = 0x22;          //"
-            JSON_loc++;
-            AdvData[JSON_loc] = 0x3a;          //:
-            JSON_loc++;
-    
-    
-            
-            //write battery voltage
-            uint8_t total_chars;
-            memset(&buffer[0], 0, sizeof(buffer));      //clear out buffer
-            total_chars = sprintf (buffer, "%.2f", bat_reading);    //returns total number of characters
-
-#if MyDebugEnb
-            device.printf("char buff: %c%c%c%c \r\n", buffer[0], buffer[1], buffer[2], buffer[3]);
-            device.printf("num chars: %d \r\n", total_chars);
-#endif
-
-            for (int i=0; i < total_chars; i++)
-            {
-                AdvData[JSON_loc] = buffer[i];
-                JSON_loc++;
-#if MyDebugEnb
-                device.printf("JSON_loc: %d     buf[]:%c \r\n", JSON_loc, buffer[i]);
-#endif
-            } //JSON_loc left at location of next character
-            
-            //DEC"vo":3.11,"
-            AdvData[JSON_loc] = 0x2c;       //,
-            JSON_loc++;
-            
-            AdvData[JSON_loc] = 0x22;       //" start mag
-            JSON_loc++;
-            
-            AdvData[JSON_loc] = 0x6d;       //m
-            JSON_loc++;
-            
-            AdvData[JSON_loc] = 0x61;       //a
-            JSON_loc++;
-            
-            AdvData[JSON_loc] = 0x67;       //g
-            JSON_loc++;
-            
-            if (flag_periodic_call)
-            {
-                //AdvData[JSON_loc] = 0x2f;       // "/"
-                //JSON_loc++;
-                AdvData[JSON_loc] = 0x2f;       // "/"
-                JSON_loc++;
-                AdvData[JSON_loc] = 0x70;       // "p"
-                JSON_loc++;
-            }//end if period call
-            
-            AdvData[JSON_loc] = 0x22;       //"
-            JSON_loc++;
-
-            AdvData[JSON_loc] = 0x3a;       //:
-            JSON_loc++;
-            
-            //prep magnet location (1 or 0) for char[]
-            memset(&buffer[0], 0, sizeof(buffer));      //clear out buffer
-            //magnet_near is an integer
-            total_chars = sprintf (buffer, "%d", magnet_near);    //returns total number of characters
-            for (int i=0; i < total_chars; i++)
-            {
-                AdvData[JSON_loc] = buffer[i];
-                JSON_loc++;
-            } //JSON_loc left at location of next character
-            
-            //MUST null terminate for JSON to read correctly, else get intermittent JSON parse errors at gateway
-            //happens when string is shorter than last string, get trash left overs
-            //not really needed after clearning AdvData at start.
-            
-            
-            //AdvData[JSON_loc] = 0x0;    //null terminate here
-
-            ApplicationData_t appData;
-            setupApplicationData(appData);
-            
-
-            for (int i=0; i<16; i++)
-            {
-                src_buf[i] = AdvData[i+3];
-            }
-
-            //nrf_ecb_set_key(key_buf);
-            nrf_ecb_init();
-            nrf_ecb_set_key(key_buf);
-            bool successful_ecb = nrf_ecb_crypt(des_buf, src_buf);
-#if MyDebugEnb
-            device.printf("success ecb = %d \r\n", successful_ecb);
-            device.printf("src_buf: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x \r\n", src_buf[0], src_buf[1], src_buf[2], src_buf[3], src_buf[4], src_buf[5], src_buf[6], src_buf[7], src_buf[8], src_buf[9], src_buf[10], src_buf[11], src_buf[12], src_buf[13], src_buf[14], src_buf[15]);
-            device.printf("des_buf: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x \r\n", des_buf[0], des_buf[1], des_buf[2], des_buf[3], des_buf[4], des_buf[5], des_buf[6], des_buf[7], des_buf[8], des_buf[9], des_buf[10], des_buf[11], des_buf[12], des_buf[13], des_buf[14], des_buf[15]);
-#endif
-            for (int i=0; i<16; i++)
-            {
-                AdvData[i+3] = des_buf[i];
-            }
-            
-            //ble.gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *) &appData, sizeof(ApplicationData_t));
-            ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, AdvData, sizeof(AdvData));
-            
-            flag_update_io = false;
-            flag_periodic_call = false;
-            
-            //GAP::AddressType_t *myType;
-            //GAP::Address_t myAddress
-            //ble_error_t getAddress(Gap::AddressType_t *typeP, Gap::Address_t address)
-            //ble.gap().getAddress(myType, myAddress);
-            //ble.gap().getAddress(Gap::AddressType_t *typeP, Gap::Address_t address);
-            uint8_t mac[6] = {0x0,0x0,0x0,0x0,0x0,0x0};
-            ble.getAddress(0,mac);  //NOTE:  last byte of MAC (as shown on phone app) is at mac[0], not mac[6];
-#if MyDebugEnb
-            device.printf("mac = ");
-            for (int i=0; i<6; i++)
-            {
-                device.printf("%x:", mac[i]);
-            }
-            device.printf("\r\n");
-#endif
-            ble.gap().startAdvertising();
-            tic_adv.attach(stop_adv_Callback, 2); /* trigger turn off advertisement after X seconds */
-
-            /*
-            Timer myTimer;  //timed advertising
-            myTimer.start();
-            uint32_t duration = myTimer.read_ms();
-            
-            //do this as a ticker instead of keeping processor on
-            while (duration < 15000)            //advertise for 1000 ms
-            {
-                duration = myTimer.read_ms();   //read miliseconds
-            }
-            myTimer.stop();
-            ble.gap().stopAdvertising();
-            */
-        
-        }//end flag_update_io
-        
-        
-        /*
-        if (flag_set_debounce_tic == true)
-        {
-            tic_debounce.attach();
-            //flag_set_debounce_tic = false;
-            
-        }
-        */
-        
-        //if (trigger_Detach_ADV_Tick == false)
-        //{  
-        //}
-        if (flag_detach_adv_tic == true)    //Stop Advertising
-        {
-            ble.gap().stopAdvertising();    //may be safer to execute BLE operations in main
-            tic_adv.detach();
-            flag_detach_adv_tic = false;
-        }
-        //device.printf("Input Voltage: %f\n\r",bat_reading);
-        
-        ble.waitForEvent(); //sleeps until interrupt
-        
-
-    }//end forever while
-}//end main
+        ble.waitForEvent();
+    }
+}