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:
- 10:9db2ac7e1eea
- Parent:
- 9:1ea51b2048a8
- Child:
- 11:d5edb6e3edab
File content as of revision 10:9db2ac7e1eea:
/* Eric Tsai BLE Gateway to bridge sensor data. Works. 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(); } }