A test framework that advertises periodically and can advertise on individual channels or all three

Dependencies:   BLE_API mbed nRF51822

Fork of BasicTag by Mobius IoT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "BLE.h"
00003 #include "config.h"
00004 
00005 // Compile time options
00006 #define IS_SMART_BEACON     1 // Whether targeting nRF51822 Smart Beacon
00007 #define BLINK_LED           1 // Whether to blink the LED
00008 #define CYCLE_CHANNELS      0 // Whether to advertise cycling between
00009                               // single channels or normally
00010 #define ADVERTISE_NAME      0 // Whether to advertise a name
00011                               // (increases packet size)
00012 #define BAUD_RATE           115200 // baud
00013 
00014 // Experiment parameters
00015 #define DONGLE_NUM          1       // last byte of address, for identification
00016 #define CYCLE_INTERVAL      5000    // ms; see CYCLE_CHANNELS
00017 #define ADV_INTERVAL        100     // ms
00018 #define BLINK_INTERVAL      1000    // ms
00019 #define TX_POWER            -4      // dBm; see mbed API for valid values
00020 #define PAYLOAD_SIZE        2       // bytes
00021 #define TAG_NAME            "MobiusTag" // see ADVERTISE_NAME
00022 
00023 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
00024 
00025 unsigned char CH_37_OFF = 0;
00026 unsigned char CH_38_OFF = 0;
00027 unsigned char CH_39_OFF = 0;
00028 uint8_t channel = 0;
00029 
00030 const uint8_t TAG_ADDR[BLEProtocol::ADDR_LEN] =
00031     {DONGLE_NUM, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
00032 
00033 Serial pc(p9, p11);
00034 
00035 #if IS_SMART_BEACON
00036 #undef LED1
00037 #define LED1 p12
00038 #endif
00039 
00040 #if BLINK_LED
00041 void blinkCallback(void)
00042 {
00043     static DigitalOut led(LED1, 1);
00044     led = !led;
00045 }
00046 #endif
00047 
00048 void setupAdvertising(uint8_t channel, uint16_t interval)
00049 {
00050     ble.gap().stopAdvertising();
00051     switch (channel) {
00052         case 0:
00053             CH_37_OFF = 0;
00054             CH_38_OFF = 0;
00055             CH_39_OFF = 0;
00056             break;
00057         case 37:
00058             CH_37_OFF = 0;
00059             CH_38_OFF = 1;
00060             CH_39_OFF = 1;
00061             break;
00062         case 38:
00063             CH_37_OFF = 1;
00064             CH_38_OFF = 0;
00065             CH_39_OFF = 1;
00066             break;
00067         case 39:
00068             CH_37_OFF = 1;
00069             CH_38_OFF = 1;
00070             CH_39_OFF = 0;
00071             break;
00072         default:
00073             CH_37_OFF = 1;
00074             CH_38_OFF = 1;
00075             CH_39_OFF = 1;
00076             break;
00077     }
00078     
00079     ble.gap().setAdvertisingInterval(interval);
00080     ble.gap().startAdvertising();
00081 }
00082 
00083 #if CYCLE_CHANNELS
00084 void cycleChannelCallback(void)
00085 {
00086     switch (channel) {
00087         case 0:
00088             channel = 37;
00089             break;
00090         case 37:
00091             channel = 38;
00092             break;
00093         case 38:
00094             channel = 39;
00095             break;
00096         case 39:
00097             channel = 0;
00098             break;
00099         default:
00100             channel = 99;
00101             break;
00102     }
00103     
00104     setupAdvertising(channel, ADV_INTERVAL);
00105 }
00106 #endif
00107 
00108 void incSeqNumCallback(void)
00109 {
00110     static uint8_t packet_no = 0;
00111     static uint8_t payload[PAYLOAD_SIZE] = {0};
00112     
00113     ble.gap().stopAdvertising();
00114     ble.gap().clearAdvertisingPayload();
00115 
00116     payload[0] = packet_no;
00117     payload[1] = channel;
00118     ble.gap().accumulateAdvertisingPayload(
00119         GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, payload, PAYLOAD_SIZE);
00120 //    ble.gap().accumulateAdvertisingPayload(
00121 //        GapAdvertisingData::BREDR_NOT_SUPPORTED);
00122 #if ADVERTISE_NAME
00123     ble.gap().accumulateAdvertisingPayload(
00124         GapAdvertisingData::SHORTENED_LOCAL_NAME,
00125         (const uint8_t*)TAG_NAME, sizeof(TAG_NAME));
00126 #endif
00127     
00128     ble.gap().startAdvertising();
00129     
00130     packet_no++;
00131 }
00132 
00133 void bleInitCallback(BLE::InitializationCompleteCallbackContext *params)
00134 {
00135     static Ticker cycleChannelTicker;
00136     
00137     if (params->error != BLE_ERROR_NONE ||
00138         params->ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
00139         return;
00140     }
00141     
00142     ble.gap().setAdvertisingType(
00143         GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
00144     ble.gap().setAddress(BLEProtocol::AddressType::PUBLIC, TAG_ADDR);
00145     ble.gap().setTxPower(TX_POWER);
00146 
00147 #if CYCLE_CHANNELS
00148     cycleChannelTicker.attach(cycleChannelCallback, CYCLE_INTERVAL/1000.0);
00149 #else
00150     setupAdvertising(0, ADV_INTERVAL);
00151 #endif
00152 }
00153 
00154 int main(void)
00155 {   
00156     static Ticker ledTicker, incSeqNumTicker;
00157     
00158     pc.baud(BAUD_RATE);
00159 
00160 #if BLINK_LED
00161     ledTicker.attach(blinkCallback, BLINK_INTERVAL/1000.0);
00162 #endif
00163 
00164     ble.init(bleInitCallback);
00165     while (!ble.hasInitialized()) { }
00166 
00167     incSeqNumTicker.attach(incSeqNumCallback, ADV_INTERVAL/1000.0);
00168 
00169     while (true) {
00170         ble.waitForEvent();
00171     }
00172 }