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(); } }