A scanner framework that receives advertisements, filters them by MAC, and prints out some data as CSV over the serial port

Dependencies:   BLE_API mbed nRF51822

Fork of BasicScanner by Mobius IoT

Committer:
cordonn2
Date:
Tue Mar 28 19:05:45 2017 +0000
Revision:
14:d8f4a49c9fb3
Parent:
13:8999c8b2e18e
Initial commit of scanner framework

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 0:332983584a9c 1 #include "mbed.h"
rgrover1 9:69a2ad0bcdb7 2 #include "ble/BLE.h"
cordonn2 14:d8f4a49c9fb3 3
cordonn2 14:d8f4a49c9fb3 4 // Compile time options
cordonn2 14:d8f4a49c9fb3 5 #define BLINK_LED 1 // Whether to blink the LED
cordonn2 14:d8f4a49c9fb3 6 #define CYCLE_CHANNELS 0 // Whether to scan cycling between
cordonn2 14:d8f4a49c9fb3 7 // single channels or normally
cordonn2 14:d8f4a49c9fb3 8 #define BAUD_RATE 115200 // baud
sunsmile2015 7:91324daa3bfa 9
cordonn2 14:d8f4a49c9fb3 10 // Experiment parameters
cordonn2 14:d8f4a49c9fb3 11 #define CYCLE_INTERVAL 5000 // ms; see CYCLE_CHANNELS
cordonn2 14:d8f4a49c9fb3 12 #define SCAN_INTERVAL 500 // ms
cordonn2 14:d8f4a49c9fb3 13 #define SCAN_WINDOW SCAN_INTERVAL // ms; must be <= SCAN_INTERVAL
cordonn2 14:d8f4a49c9fb3 14 #define BLINK_INTERVAL 1000 // ms
budoguyiii 12:dbbf0ddc9b12 15
cordonn2 14:d8f4a49c9fb3 16 // Constants
cordonn2 14:d8f4a49c9fb3 17 #define NRF_RADIO_FREQUENCY (*(uint32_t*)(0x40001508UL))
cordonn2 14:d8f4a49c9fb3 18
cordonn2 14:d8f4a49c9fb3 19 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
cordonn2 14:d8f4a49c9fb3 20
cordonn2 14:d8f4a49c9fb3 21 uint8_t channel = 37;
cordonn2 14:d8f4a49c9fb3 22
cordonn2 14:d8f4a49c9fb3 23 Serial pc(p9, p11);
cordonn2 14:d8f4a49c9fb3 24 Timer uptime;
budoguyiii 12:dbbf0ddc9b12 25
budoguyiii 12:dbbf0ddc9b12 26
cordonn2 14:d8f4a49c9fb3 27 #if BLINK_LED
cordonn2 14:d8f4a49c9fb3 28 void blinkCallback(void)
rgrover1 0:332983584a9c 29 {
cordonn2 14:d8f4a49c9fb3 30 static DigitalOut led(LED1, 1);
cordonn2 14:d8f4a49c9fb3 31 led = !led;
rgrover1 0:332983584a9c 32 }
cordonn2 14:d8f4a49c9fb3 33 #endif
rgrover1 0:332983584a9c 34
rgrover1 9:69a2ad0bcdb7 35 /*
rgrover1 9:69a2ad0bcdb7 36 * This function is called every time we scan an advertisement.
rgrover1 9:69a2ad0bcdb7 37 */
sunsmile2015 6:850f44146c9f 38 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
sunsmile2015 6:850f44146c9f 39 {
cordonn2 14:d8f4a49c9fb3 40 if (params->peerAddr[1] == 0xAA &&
cordonn2 14:d8f4a49c9fb3 41 params->peerAddr[2] == 0xAA &&
cordonn2 14:d8f4a49c9fb3 42 params->peerAddr[3] == 0xAA &&
cordonn2 14:d8f4a49c9fb3 43 params->peerAddr[4] == 0xAA &&
cordonn2 14:d8f4a49c9fb3 44 params->peerAddr[5] == 0xAA)
budoguyiii 13:8999c8b2e18e 45 {
cordonn2 14:d8f4a49c9fb3 46 printf("%d,%d,%d,%d,%d\n",
cordonn2 14:d8f4a49c9fb3 47 params->peerAddr[0],
cordonn2 14:d8f4a49c9fb3 48 params->advertisingData[2],
cordonn2 14:d8f4a49c9fb3 49 uptime.read_ms(),
cordonn2 14:d8f4a49c9fb3 50 params->rssi,
cordonn2 14:d8f4a49c9fb3 51 //#if CYCLE_CHANNELS
cordonn2 14:d8f4a49c9fb3 52 // channel
cordonn2 14:d8f4a49c9fb3 53 //#else
cordonn2 14:d8f4a49c9fb3 54 NRF_RADIO_FREQUENCY
cordonn2 14:d8f4a49c9fb3 55 // params->advertisingData[3] // Infer channel from packet data
cordonn2 14:d8f4a49c9fb3 56 //#endif
cordonn2 14:d8f4a49c9fb3 57 );
budoguyiii 13:8999c8b2e18e 58 }
rgrover1 0:332983584a9c 59 }
rgrover1 0:332983584a9c 60
cordonn2 14:d8f4a49c9fb3 61 void setupScanning(uint8_t channel, uint16_t scanInterval, uint16_t scanWindow)
andresag 11:16f67d5752e1 62 {
cordonn2 14:d8f4a49c9fb3 63 #if CYCLE_CHANNELS
cordonn2 14:d8f4a49c9fb3 64 // TODO: make the frequency stick instead of letting softdevice overwrite it
cordonn2 14:d8f4a49c9fb3 65 switch (channel) {
cordonn2 14:d8f4a49c9fb3 66 case 37:
cordonn2 14:d8f4a49c9fb3 67 NRF_RADIO_FREQUENCY = 2; // 2402 MHz
cordonn2 14:d8f4a49c9fb3 68 break;
cordonn2 14:d8f4a49c9fb3 69 case 38:
cordonn2 14:d8f4a49c9fb3 70 NRF_RADIO_FREQUENCY = 26; // 2426 MHz
cordonn2 14:d8f4a49c9fb3 71 break;
cordonn2 14:d8f4a49c9fb3 72 case 39:
cordonn2 14:d8f4a49c9fb3 73 NRF_RADIO_FREQUENCY = 80; // 2480 MHz
cordonn2 14:d8f4a49c9fb3 74 break;
cordonn2 14:d8f4a49c9fb3 75 default:
cordonn2 14:d8f4a49c9fb3 76 break;
cordonn2 14:d8f4a49c9fb3 77 }
cordonn2 14:d8f4a49c9fb3 78 #endif
cordonn2 14:d8f4a49c9fb3 79 ble.gap().setScanParams(scanInterval, scanWindow);
cordonn2 14:d8f4a49c9fb3 80 ble.gap().startScan(advertisementCallback);
andresag 11:16f67d5752e1 81 }
andresag 11:16f67d5752e1 82
cordonn2 14:d8f4a49c9fb3 83 #if CYCLE_CHANNELS
cordonn2 14:d8f4a49c9fb3 84 void cycleChannelCallback(void)
andresag 11:16f67d5752e1 85 {
cordonn2 14:d8f4a49c9fb3 86 switch (channel) {
cordonn2 14:d8f4a49c9fb3 87 case 37:
cordonn2 14:d8f4a49c9fb3 88 channel = 38;
cordonn2 14:d8f4a49c9fb3 89 break;
cordonn2 14:d8f4a49c9fb3 90 case 38:
cordonn2 14:d8f4a49c9fb3 91 channel = 39;
cordonn2 14:d8f4a49c9fb3 92 break;
cordonn2 14:d8f4a49c9fb3 93 case 39:
cordonn2 14:d8f4a49c9fb3 94 channel = 37;
cordonn2 14:d8f4a49c9fb3 95 break;
cordonn2 14:d8f4a49c9fb3 96 default:
cordonn2 14:d8f4a49c9fb3 97 channel = 0;
cordonn2 14:d8f4a49c9fb3 98 break;
cordonn2 14:d8f4a49c9fb3 99 }
cordonn2 14:d8f4a49c9fb3 100 setupScanning(channel, SCAN_INTERVAL, SCAN_WINDOW);
cordonn2 14:d8f4a49c9fb3 101 }
cordonn2 14:d8f4a49c9fb3 102 #endif
andresag 11:16f67d5752e1 103
cordonn2 14:d8f4a49c9fb3 104 void bleInitCallback(BLE::InitializationCompleteCallbackContext *params)
cordonn2 14:d8f4a49c9fb3 105 {
cordonn2 14:d8f4a49c9fb3 106 static Ticker cycleChannelTicker;
cordonn2 14:d8f4a49c9fb3 107
cordonn2 14:d8f4a49c9fb3 108 if (params->error != BLE_ERROR_NONE ||
cordonn2 14:d8f4a49c9fb3 109 params->ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
andresag 11:16f67d5752e1 110 return;
andresag 11:16f67d5752e1 111 }
andresag 11:16f67d5752e1 112
cordonn2 14:d8f4a49c9fb3 113 #if CYCLE_CHANNELS
cordonn2 14:d8f4a49c9fb3 114 setupScanning(channel, SCAN_INTERVAL, SCAN_WINDOW);
cordonn2 14:d8f4a49c9fb3 115 cycleChannelTicker.attach(cycleChannelCallback, CYCLE_INTERVAL/1000.0);
cordonn2 14:d8f4a49c9fb3 116 #else
cordonn2 14:d8f4a49c9fb3 117 setupScanning(channel, SCAN_INTERVAL, SCAN_WINDOW);
cordonn2 14:d8f4a49c9fb3 118 #endif
andresag 11:16f67d5752e1 119 }
andresag 11:16f67d5752e1 120
rgrover1 0:332983584a9c 121 int main(void)
rgrover1 0:332983584a9c 122 {
cordonn2 14:d8f4a49c9fb3 123 static Ticker ledTicker, incSeqNumTicker;
cordonn2 14:d8f4a49c9fb3 124 uptime.start();
budoguyiii 12:dbbf0ddc9b12 125
cordonn2 14:d8f4a49c9fb3 126 pc.baud(BAUD_RATE);
rgrover1 0:332983584a9c 127
cordonn2 14:d8f4a49c9fb3 128 #if BLINK_LED
cordonn2 14:d8f4a49c9fb3 129 ledTicker.attach(blinkCallback, BLINK_INTERVAL/1000.0);
cordonn2 14:d8f4a49c9fb3 130 #endif
rgrover1 0:332983584a9c 131
cordonn2 14:d8f4a49c9fb3 132 printf("\nID,Sequence Number,Timestamp,RSSI,Channel\n");
cordonn2 14:d8f4a49c9fb3 133 BLE &ble = BLE::Instance();
cordonn2 14:d8f4a49c9fb3 134 ble.init(bleInitCallback);
budoguyiii 12:dbbf0ddc9b12 135
rgrover1 0:332983584a9c 136 while (true) {
rgrover1 0:332983584a9c 137 ble.waitForEvent();
rgrover1 0:332983584a9c 138 }
rgrover1 0:332983584a9c 139 }