BLE ADV Gateway, converts advertisement to proper JSON serial output

Dependencies:   BLE_API mbed mbedtls nRF51822

main.cpp

Committer:
electronichamsters
Date:
2017-07-10
Revision:
9:1ea51b2048a8
Parent:
8:46c5e0bfab05
Child:
10:9db2ac7e1eea

File content as of revision 9:1ea51b2048a8:

/* 

 
 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.



----------------------------------------------


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}

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"


//comment out when done with debug uart, else eats batteries
#define MyDebugEnb 0


//DigitalOut led1(LED1, 1);
Ticker     ticker;

//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)
{
    //led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
    //device.printf("periodic 5...");
    //device.printf("\r\n");
}

void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {


    //BLE MAC Address (6 bytes):
    //      params->peerAddr[5]
    //      params->peerAddr[4]
    //      ...
    //      params->peerAddr[0]
    //RSSI = params->rssi
    //Payload
    //  params->advertisingData[#<advertisingDataLen]
    

    
    //              [<---MY DATA-->]
    //0x02      0x01    0x06    0x06    0xff    D   E   C   ?  ?
    //0         1       2       3       4       5   6   7   8   9

    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

            //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




}//end advertisementCallback

/**
 * 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");
}

/**
 * Callback triggered when the ble initialization process has finished
 */
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
{
    BLE&        ble   = params->ble;
    ble_error_t error = params->error;

    if (error != BLE_ERROR_NONE) {
        /* In case of error, forward the error handling to onBleInitError */
        onBleInitError(ble, error);
        return;
    }

    /* Ensure that it is the default instance of BLE */
    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
        return;
    }
 
    // 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)
{
    device.baud(9600);
    device.printf("started main 04... ");
    device.printf("\r\n");
    ticker.attach(periodicCallback, 5);
    
    //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);

    while (true) {
        ble.waitForEvent();
    }
}