BLE ADV Gateway, converts advertisement to proper JSON serial output
Dependencies: BLE_API mbed mbedtls nRF51822
main.cpp
00001 /* 00002 * Copyright (c) Eric Tsai 2017 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 * 00016 * 00017 * Credit: I started with the basic BLE_Observer code from mbed Bluetooth Low Energy team 00018 * https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_Observer/file/88f50499af9a/main.cpp 00019 * 00020 * 00021 * 00022 * This BLE advertisement observer looks for specific advertisements from intended bacons 00023 * and outputs beacon data as json over serial. Compiled and tested for nRF51822 on mbed. 00024 */ 00025 00026 #include "mbed.h" //revision 148 00027 #include "ble/BLE.h" 00028 #include "mbedtls/aes.h" //derived from the standard mbedtls. Modified for smaller build. See project. 00029 00030 00031 #define MyDebugEnb 0 //change to 1 for debug out of the same serial as intended output 00032 00033 00034 Ticker ticker; 00035 00036 //clock periodicity used for spoof checking, should be 1800 seconds for 30minutes 00037 //make sure matches periodicity of beacons for correct operation 00038 const uint16_t Periodicity = 1800; 00039 00040 //aes 00041 uint8_t src_buf[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4}; 00042 uint8_t des_buf[16] = {0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4,0x1,0x2,0x3,0x4}; 00043 mbedtls_aes_context aes; 00044 unsigned char iv[16] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x1, 0x2}; //16-byte aes key 00045 00046 //Serial device(p9, p11); //nRF51822 uart: TX=p9. RX=p11 00047 Serial device(p9, p11); //nRF51822 uart: TX=p9. RX=p11 00048 DigitalIn pinHandShake(p0); //handshake uart to prevent output before bridge MCU is ready. Flow control. 00049 00050 //data structures for tracking wake time of BLE end nodes, for to prevent spoofing 00051 struct MAC_Birth_Record 00052 { 00053 uint8_t MAC_Addr[6]; //mac[0] is low order byte in mac address 00054 uint16_t MAC_Time; //The time of birth for this end node 00055 uint16_t Attempt_MAC_Time; 00056 uint8_t Attempt_Cnt; 00057 uint8_t Xmit_Cnt; 00058 }; 00059 const uint8_t sizeOfSpoof = 50; //translates to the number of unique BLE modules this gateway should receive 00060 MAC_Birth_Record Spoof_Check[sizeOfSpoof]; //array tracking end node birth times 00061 uint8_t Spoof_Ray_Tail = 0; //array index for next record 00062 uint8_t Received_MAC_Addr[6]; //mac[0] is low order byte in mac address 00063 uint16_t Received_MAC_Time; //global var to hold MAC for processing the current ADV 00064 static Timer Gateway_Time; //global for the # seconds within each "Periodicity" cycle, each 30 minute chunk. 00065 static uint16_t Expected_MAC_Time; //holds Gateway Time Zone value for Beacon's birth time indicated by ADV 00066 uint8_t Received_Xmit_Cnt; //global var to hold xmit count for processing the current ADV 00067 const uint8_t Allowance = 5; //number of seconds allowed for MAC Birthtime mismatch 00068 00069 // possible return values for Is_Not_Spoofed() 00070 const uint8_t ADVisUnknown = 0; //Unaccounted for advertisement type, should never happen 00071 const uint8_t ADVisNew = 1; //first time seeing this MAC address 00072 const uint8_t ADVisDuplicate = 2; //packet is one of the duplicate advertisement 00073 const uint8_t ADVisSpoof = 3; //birth times do not match 00074 00075 uint8_t MAC_gateway[6] = {0x0,0x0,0x0,0x0,0x0,0x0}; //mac address of this gateway BLE module 00076 00077 //******************** 00078 // Checks if Beacon's transmitted MAC birth time matches and gateway's recorded MAC birth time. 00079 // Takes into account 30-minute clock, takes care of edge cases for wrap around 00080 // returns: 00081 // TRUE: if sensor's reported time lines up to gateway's recorded time 00082 //******************** 00083 bool Is_Birth_Time_Correct (uint16_t gateway_mac_time, uint16_t sensor_mac_time, uint8_t margin) 00084 { 00085 bool return_val = 0; 00086 uint16_t current_time = (uint16_t)(Gateway_Time.read_ms()/1000); 00087 int16_t gateway_time_zone = current_time - sensor_mac_time; 00088 00089 if (current_time >= sensor_mac_time) //simple time translation 00090 { 00091 Expected_MAC_Time = current_time - sensor_mac_time; 00092 } 00093 else //wrap around time given periodicity 00094 { 00095 Expected_MAC_Time = (Periodicity - sensor_mac_time + current_time); 00096 } 00097 00098 //todo: perhaps return true if count is 0 to avoid 3-transmits needed to confirm devices that were reset? Meh. 00099 if (1) 00100 { 00101 //We can't be too stringent that beacon MAC time precisely matches recorded time, because we're advertising 00102 // the same data over several seconds. Not bothering to update the MAC time of each ADV within same event. 00103 // Pick margin time (in seconds) based on how many seconds the beacon is advertising, to give this alloweance 00104 // For example, you want to be more certain that beacon seen by gateway, and you increase the number of seconds 00105 // you advertise for from 2 to 4 seconds. Then Margin has to be likewise increased to 4 seconds. 00106 // Increasing probably that Beacon is seen results in slightly compromised spoof-detection. 00107 if ( (gateway_mac_time < (Expected_MAC_Time + margin)) && (gateway_mac_time > (Expected_MAC_Time - margin)) ) 00108 { 00109 return_val = 1; 00110 } 00111 else 00112 { 00113 return_val = 0; 00114 00115 } 00116 } 00117 00118 return return_val; 00119 }//end Is_Birth_Time_Correct 00120 00121 00122 00123 /* **************************************** 00124 iterates Beacon adv against all mac birth records to detect spoofing, repeats, and 00125 add device to birth records if new 00126 00127 returns 00128 ADVisNew = 1 First time seeing this MAC address 00129 ADVisDuplicate = 2 Subsequent advertisements for same event 00130 ADVisSpoof = 3 MAC times do not match 00131 ADVisUnknown = 0 Shouldn't encounter this, debug 00132 *******************************************/ 00133 uint8_t Is_Not_Spoofed () 00134 { 00135 uint8_t return_val = ADVisUnknown; 00136 00137 //iterate through all of birth records looking for one that matches MAC address 00138 for (int i=0; i<sizeOfSpoof; i++) 00139 { 00140 //Search for matching MAC address 00141 if (Spoof_Check[i].MAC_Addr[0] == Received_MAC_Addr[0] && 00142 Spoof_Check[i].MAC_Addr[1] == Received_MAC_Addr[1] && 00143 Spoof_Check[i].MAC_Addr[2] == Received_MAC_Addr[2] && 00144 Spoof_Check[i].MAC_Addr[3] == Received_MAC_Addr[3] && 00145 Spoof_Check[i].MAC_Addr[4] == Received_MAC_Addr[4] && 00146 Spoof_Check[i].MAC_Addr[5] == Received_MAC_Addr[5]) 00147 { 00148 #if MyDebugEnb 00149 device.printf("found MAC address in array\r\n"); 00150 device.printf(" Index = %d \r\n", i); 00151 device.printf(" MAC = %02x:%02x:%02x:%02x:%02x:%02x \r\n", Received_MAC_Addr[5],Received_MAC_Addr[4],Received_MAC_Addr[3],Received_MAC_Addr[2],Received_MAC_Addr[1],Received_MAC_Addr[0]); 00152 device.printf(" Received MAC Time = %d \r\n", Received_MAC_Time); 00153 device.printf(" Gateway time = %d \r\n", (uint16_t)(Gateway_Time.read_ms()/1000)); 00154 device.printf(" Array.MAC_Time = %d \r\n", Spoof_Check[i].MAC_Time); 00155 device.printf(" Array.Attempt_MAC_Time = %d \r\n", Spoof_Check[i].Attempt_MAC_Time); 00156 device.printf(" Array.Attempt_Cnt = %d \r\n", Spoof_Check[i].Attempt_Cnt); 00157 device.printf(" Array.Xmit_Cnt = %d \r\n", Spoof_Check[i].Xmit_Cnt); 00158 device.printf(" expected time = %d \r\n", ((uint16_t)(Gateway_Time.read_ms()/1000)) - Received_MAC_Time); 00159 #endif 00160 00161 if 00162 ( 00163 //check primary MAC time 00164 //adjust margin=5 as needed to accomodate Beacon advertisement interval time 00165 // if advertising for 3 seconds, then make margin 4. 4->5, etc... 00166 Is_Birth_Time_Correct(Spoof_Check[i].MAC_Time, Received_MAC_Time, Allowance) 00167 ) 00168 { 00169 if (Spoof_Check[i].Xmit_Cnt != Received_Xmit_Cnt) //check if this is duplicate 00170 { 00171 return_val = ADVisNew; //MAC Time checks out and not duplicate 00172 Spoof_Check[i].MAC_Time = Expected_MAC_Time; //update birth time for this device. 00173 Spoof_Check[i].Xmit_Cnt = Received_Xmit_Cnt; 00174 //i = sizeOfSpoof; //exit for loop, we've found the MAC address. But can't do it this way. 00175 //ToDo: hey, what happens if the array holds entries w/ same MAC? Is that possible? 00176 #if MyDebugEnb 00177 device.printf("Pirmary MAC Time as expected...expected=%d...Spoof_mac_tmr=%d \r\n", Expected_MAC_Time, Spoof_Check[i].MAC_Time); 00178 #endif 00179 } 00180 else 00181 { 00182 return_val = ADVisDuplicate; //MAC Time checks out and is duplicate 00183 } 00184 }//if primary MAC_time match 00185 else 00186 { 00187 00188 // check secondary Mac_Time 00189 // allows for device to become registered if secondary matches multiple times 00190 #if MyDebugEnb 00191 device.printf(" MAC Time No Match!!...expected=%d...Spoof_mac_tmr=%d \r\n", Expected_MAC_Time, Spoof_Check[i].MAC_Time); 00192 #endif 00193 00194 //increment count if matches secondary 00195 if (Is_Birth_Time_Correct(Spoof_Check[i].Attempt_MAC_Time, Received_MAC_Time, Allowance)) 00196 { 00197 if (Spoof_Check[i].Xmit_Cnt != Received_Xmit_Cnt) //not a duplicate ADV 00198 { 00199 Spoof_Check[i].Attempt_Cnt++; 00200 Spoof_Check[i].Xmit_Cnt = Received_Xmit_Cnt; 00201 #if MyDebugEnb 00202 device.printf(" Match on secondary, Attempt_Cnt= %d, Attempt_MAC_Time = %d, Expected_MAC_Time=%d \r\n", Spoof_Check[i].Attempt_Cnt, Spoof_Check[i].Attempt_MAC_Time, Expected_MAC_Time); 00203 #endif 00204 //this takes care of usecase where a module is reset after it's already been seen by gateway 00205 //after 3 consecutive correlated MAC_Time attempts we assume is our long lost friend and not a spoof. 00206 if (Spoof_Check[i].Attempt_Cnt >= 3) 00207 { 00208 return_val = ADVisNew; 00209 00210 //promote this MAC_Time to primary and start accepting data @ this MAC_Time 00211 Spoof_Check[i].MAC_Time = Expected_MAC_Time; 00212 Spoof_Check[i].Xmit_Cnt = Received_Xmit_Cnt; 00213 Spoof_Check[i].Attempt_Cnt = 0; 00214 } 00215 else //Received_MAC_Time matches Attempt, but not enough times to be considered as valid. 00216 { 00217 return_val = ADVisSpoof; 00218 } 00219 }//is not duplicate, and transmit count matches 00220 else 00221 { 00222 #if MyDebugEnb 00223 device.printf(" is Duplicate , but matches Attempt_MAC_Time matches\r\n"); 00224 #endif 00225 return_val = ADVisDuplicate; 00226 } 00227 } //Recevied MAC_Time matches secondary MAC_Time 00228 else 00229 { 00230 #if MyDebugEnb 00231 device.printf(" No Match on secondary either, ===setting return_val = Spoof ===\r\n"); 00232 #endif 00233 return_val = ADVisSpoof; //it should still be zero, so this is just for clarification 00234 //at this point: MAC matches, MAC_Time doesn't match primary nor secondary. 00235 Spoof_Check[i].Attempt_Cnt = 0; //reset secondary count 00236 } 00237 //update second backup regardless whether it matches exptected_mac_time matches secondary or not. 00238 Spoof_Check[i].Attempt_MAC_Time = Expected_MAC_Time; 00239 Spoof_Check[i].Xmit_Cnt = Received_Xmit_Cnt; 00240 }//if Primary MAC_Time doesn't match 00241 00242 break; //return_val tells us if this is a valid or not. Don't need to search through remainder of array 00243 }//if matching MAC address 00244 else //MAC doesn't match 00245 { 00246 //MAC doesn't match and we've searched through entire record 00247 //let's add this MAC as new, and initialze records to match this sensor 00248 if (i >= (sizeOfSpoof - 1)) //we've searched through entire array and didn't find this MAC 00249 { 00250 //we've searched through the entire array and didn't find this MAC address 00251 //add this MAC to array, and report this as valid MAC_Time 00252 #if MyDebugEnb 00253 device.printf("MAC not found, creating new at %d \r\n", Spoof_Ray_Tail); 00254 device.printf(" sizeOfSpoof=%d ... and i=%d \r\n", sizeOfSpoof, i); 00255 #endif 00256 00257 return_val = ADVisNew; 00258 00259 //create new entry for newly seen MAC @ tail of FIFO 00260 Spoof_Check[Spoof_Ray_Tail].MAC_Addr[0] = Received_MAC_Addr[0]; 00261 Spoof_Check[Spoof_Ray_Tail].MAC_Addr[1] = Received_MAC_Addr[1]; 00262 Spoof_Check[Spoof_Ray_Tail].MAC_Addr[2] = Received_MAC_Addr[2]; 00263 Spoof_Check[Spoof_Ray_Tail].MAC_Addr[3] = Received_MAC_Addr[3]; 00264 Spoof_Check[Spoof_Ray_Tail].MAC_Addr[4] = Received_MAC_Addr[4]; 00265 Spoof_Check[Spoof_Ray_Tail].MAC_Addr[5] = Received_MAC_Addr[5]; 00266 Spoof_Check[Spoof_Ray_Tail].Xmit_Cnt = Received_Xmit_Cnt; 00267 00268 //call this just to calculate Expected_MAC_Time...kinda ugly to do this. todo: don't do this 00269 Is_Birth_Time_Correct (0, Received_MAC_Time, Allowance); 00270 #if MyDebugEnb 00271 device.printf("Expected_MAC_Time should be %d \r\n", Expected_MAC_Time); 00272 #endif 00273 Spoof_Check[Spoof_Ray_Tail].MAC_Time = Expected_MAC_Time; //wrong!!! 00274 Spoof_Check[Spoof_Ray_Tail].Xmit_Cnt = Received_Xmit_Cnt; 00275 Spoof_Check[Spoof_Ray_Tail].Attempt_Cnt = 0; 00276 00277 //increment tail pointer to next position or wrap around 00278 if (Spoof_Ray_Tail >= (sizeOfSpoof-1) ) //FIFO at end of array, return to beginning 00279 { 00280 Spoof_Ray_Tail = 0; 00281 } 00282 else 00283 { 00284 Spoof_Ray_Tail++; 00285 } 00286 00287 }//end if loop at end of array 00288 }//end else not maching MAC 00289 }//loop through Spoof_Check array 00290 00291 00292 return return_val; 00293 }//end Is_Not_Spoofed() 00294 00295 00296 void periodicCallback(void) //every Periodicity seconds, reset clock 00297 { 00298 #if MyDebugEnb 00299 device.printf("===== reset timer ===== \r\n"); 00300 #endif 00301 Gateway_Time.reset(); 00302 } 00303 00304 00305 00306 //Scheme for recognizing our beacons and ignoring all other beacons 00307 //idea: could use something like Pearson hash on parts of MAC address to make less obvious 00308 bool is_ours(const uint8_t * adv_data, const uint8_t * adv_address) 00309 { 00310 if ((adv_data[5] == adv_address[3]) && (adv_data[6] == adv_address[2])) 00311 return 1; 00312 else 00313 return 0; 00314 } 00315 00316 00317 // callback when BLE stack scans and finds a BLE ADV packet 00318 // Parse ADV and determine if it's one of ours, output data to serial if it is. 00319 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { 00320 00321 if ( (params->advertisingDataLen) >= 8) 00322 { 00323 if (is_ours(params->advertisingData, params->peerAddr)) 00324 { 00325 #if MyDebugEnb 00326 device.printf("----------- ADV CAll Back -----------------\r\n "); 00327 #endif 00328 00329 //************** 00330 // Decrypt data 00331 //************** 00332 //prep array for deciphering the encrypted portion of advertisement 00333 for (int i = 0; i<16; i++) 00334 { 00335 src_buf[i]=params->advertisingData[i+15]; 00336 #if MyDebugEnb 00337 //device.printf("%x ", src_buf[i]); 00338 #endif 00339 } 00340 mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, src_buf, des_buf ); //execution time not an issue 00341 #if MyDebugEnb 00342 //device.printf("decoded first 16 bytes \r\n"); 00343 for (int i = 0; i<16; i++) 00344 { 00345 //device.printf("%02x", params->advertisingData[index]); 00346 if (i < 2) 00347 { 00348 //device.printf("%x ", des_buf[i]); 00349 } 00350 else 00351 { 00352 //device.printf("%c ", des_buf[i]); 00353 } 00354 } 00355 //device.printf("done----- \r\n"); 00356 #endif 00357 00358 //save MAC address to global 00359 Received_MAC_Addr[0] = params->peerAddr[0]; 00360 Received_MAC_Addr[1] = params->peerAddr[1]; 00361 Received_MAC_Addr[2] = params->peerAddr[2]; 00362 Received_MAC_Addr[3] = params->peerAddr[3]; 00363 Received_MAC_Addr[4] = params->peerAddr[4]; 00364 Received_MAC_Addr[5] = params->peerAddr[5]; 00365 00366 Received_MAC_Time = des_buf[0] | (des_buf[1] << 8); //it's a 2 byte uint little endian 00367 Received_Xmit_Cnt = des_buf[2]; 00368 00369 00370 00371 00372 // punch out the data over serial as json 00373 //--------------------------------------- 00374 // 1. MAC and RSSI 00375 // "mac":xxxxxxxx,rssi:xx, 00376 //--------------------------------------- 00377 uint8_t ADV_Result = Is_Not_Spoofed(); 00378 #if MyDebugEnb 00379 device.printf("--------ADV_Result = %d", ADV_Result); 00380 #endif 00381 00382 //decide wether or not duplicate ADV packets should be output as well. 00383 //if ((ADV_Result == ADVisNew) || (ADV_Result==ADVisDuplicate)) //output both first and duplicates 00384 if (ADV_Result == ADVisNew) //only output first received ADV 00385 { 00386 device.printf("{\"mac\":\"%02x%02x%02x%02x%02x%02x\",\"rssi\":%d,", 00387 params->peerAddr[5], 00388 params->peerAddr[4], 00389 params->peerAddr[3], 00390 params->peerAddr[2], 00391 params->peerAddr[1], 00392 params->peerAddr[0], 00393 params->rssi 00394 ); 00395 00396 //--------------------------------------- 00397 // 2. Volt is always X.XX, per Beacon code 00398 // "volt":3.03, 00399 //--------------------------------------- 00400 device.printf("\"volt\":%c%c%c%c,", 00401 params->advertisingData[9], 00402 params->advertisingData[10], 00403 params->advertisingData[11], 00404 params->advertisingData[12]); 00405 00406 00407 //--------------------------------------- 00408 // 3. Beacon time (# seconds since birth, clocked around Periodicity) 0-1800 seconds 00409 // "tmr":xxxx, 00410 //--------------------------------------- 00411 00412 device.printf("\"tmr\":%d,", Received_MAC_Time); 00413 00414 //--------------------------------------- 00415 // 4. Xmit Counter 0-255, incremented by Beacon with each new unique ADV event. 00416 // "tmr":xxxx, 00417 //--------------------------------------- 00418 device.printf("\"xcnt\":%d,", Received_Xmit_Cnt); 00419 00420 //--------------------------------------- 00421 // 5. rest of sensor payload as json 00422 // "tmr":xxx, 00423 //--------------------------------------- 00424 for (int i = 3; i<16; i++) 00425 { 00426 device.printf("%c", des_buf[i]); //print as character 00427 //Note that sensor JSON payload most likely is not exactly 16 bytes long, so there's likely /0 in middle 00428 // of this. But JSON library on gateway handles this gracefully. 00429 } 00430 00431 device.printf("}"); 00432 device.printf("\r\n"); //gateway looking for cariage return to indicate end 00433 wait_ms(140); //needed to give gateway time to assert flow control handshake pin 00434 while (pinHandShake.read() == 1) //normally pulled down, so loop when gateway processing; 00435 { 00436 //uart flow control 00437 //blocking until gateway has processed ADV data from uart 00438 } 00439 } 00440 00441 if (ADV_Result == ADVisSpoof) //If detected spoofed sensor data 00442 { 00443 device.printf("{\"mac\":\"%02x%02x%02x%02x%02x%02x\",\"spoof\": %d}\r\n", 00444 params->peerAddr[5], 00445 params->peerAddr[4], 00446 params->peerAddr[3], 00447 params->peerAddr[2], 00448 params->peerAddr[1], 00449 params->peerAddr[0], 00450 ADV_Result); 00451 } 00452 00453 if (ADV_Result == ADVisUnknown) //catch all, should never occur 00454 { 00455 device.printf("{\"mac\":\"%02x%02x%02x%02x%02x%02x\",\"unknown\": %d}\r\n", 00456 params->peerAddr[5], 00457 params->peerAddr[4], 00458 params->peerAddr[3], 00459 params->peerAddr[2], 00460 params->peerAddr[1], 00461 params->peerAddr[0], 00462 ADV_Result); 00463 } 00464 }//end if it's our adv 00465 }//end if advertisingDataLen 00466 }//end advertisementCallback 00467 00468 00469 00470 /** 00471 * This function is called when the ble initialization process has failed 00472 */ 00473 void onBleInitError(BLE &ble, ble_error_t error) 00474 { 00475 /* Initialization error handling should go here */ 00476 device.printf("periodic callback "); 00477 device.printf("\r\n"); 00478 } 00479 00480 /** 00481 * Callback triggered when the ble initialization process has finished 00482 */ 00483 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00484 { 00485 BLE& ble = params->ble; 00486 ble_error_t error = params->error; 00487 00488 if (error != BLE_ERROR_NONE) { 00489 /* In case of error, forward the error handling to onBleInitError */ 00490 onBleInitError(ble, error); 00491 return; 00492 } 00493 00494 /* Ensure that it is the default instance of BLE */ 00495 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00496 return; 00497 } 00498 00499 //note: defaults to scanning 3 channels. 00500 // Window and Interval in ms. Duty cycle = (interval / window); 200ms/500ms = 40%; Max is 10000 00501 // |---window---| |---window---| |---window---| 00502 // |---------- interval @ ch1 -----| |------- interval @ ch2--------||-----interval @ ch3-------| 00503 // set window equal to interval for full duty cycle scanning 00504 // set interval to hit all 3 channels of beacon advertising over advertising time duration 00505 ble.gap().setScanParams(500 /* scan interval */, 500 /* scan window */); 00506 ble.gap().startScan(advertisementCallback); 00507 } 00508 00509 int main(void) 00510 { 00511 pinHandShake.mode(PullDown); //Expecting gateway to set pin high for flow control 00512 00513 //intialize spoof checking data structure 00514 for (int i=0; i<sizeOfSpoof; i++) 00515 { 00516 Spoof_Check[i].MAC_Addr[0]= 0; 00517 Spoof_Check[i].MAC_Addr[1]= 0; 00518 Spoof_Check[i].MAC_Addr[2]= 0; 00519 Spoof_Check[i].MAC_Time = 0; 00520 Spoof_Check[i].Attempt_MAC_Time = 0; 00521 Spoof_Check[i].Attempt_Cnt = 0; 00522 Spoof_Check[i].Attempt_Cnt = 0; 00523 Spoof_Check[i].Xmit_Cnt = 0; 00524 } 00525 00526 //maintains periodicity for spoof checking scheme 00527 Gateway_Time.start(); 00528 ticker.attach(periodicCallback, Periodicity); 00529 00530 device.baud(9600); //p0.9 tx, p0.11 rx. Use p0.9 to gateway 00531 00532 mbedtls_aes_setkey_dec( &aes, iv, 128 ); //set AES key for decrypt 00533 00534 BLE &ble = BLE::Instance(); 00535 ble.init(bleInitComplete); 00536 00537 ble.getAddress(0,MAC_gateway); //get this gateway module's ble MAC 00538 device.printf("{\"mac\":\"%02x%02x%02x%02x%02x%02x\",\"gatewaystart\":\"now\"},", 00539 MAC_gateway[5], 00540 MAC_gateway[4], 00541 MAC_gateway[3], 00542 MAC_gateway[2], 00543 MAC_gateway[1], 00544 MAC_gateway[0] 00545 ); 00546 device.printf("\r\n"); 00547 00548 while (true) 00549 { 00550 ble.waitForEvent(); //idle here until callback 00551 } 00552 }
Generated on Sun Jul 17 2022 12:19:05 by 1.7.2