Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
source/main.cpp@11:37872bf83624, 2018-10-17 (annotated)
- Committer:
- mbed_official
- Date:
- Wed Oct 17 14:45:12 2018 +0100
- Revision:
- 11:37872bf83624
- Parent:
- 10:6f1c573093c1
- Child:
- 16:4dd4ecbc8efb
fix gap example to match GAP fixes
.
Commit copied from https://github.com/ARMmbed/mbed-os-example-ble
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mbed_official | 1:d4bb1e33950e | 1 | /* mbed Microcontroller Library |
mbed_official | 1:d4bb1e33950e | 2 | * Copyright (c) 2006-2013 ARM Limited |
mbed_official | 1:d4bb1e33950e | 3 | * |
mbed_official | 1:d4bb1e33950e | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
mbed_official | 1:d4bb1e33950e | 5 | * you may not use this file except in compliance with the License. |
mbed_official | 1:d4bb1e33950e | 6 | * You may obtain a copy of the License at |
mbed_official | 1:d4bb1e33950e | 7 | * |
mbed_official | 1:d4bb1e33950e | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
mbed_official | 1:d4bb1e33950e | 9 | * |
mbed_official | 1:d4bb1e33950e | 10 | * Unless required by applicable law or agreed to in writing, software |
mbed_official | 1:d4bb1e33950e | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
mbed_official | 1:d4bb1e33950e | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
mbed_official | 1:d4bb1e33950e | 13 | * See the License for the specific language governing permissions and |
mbed_official | 1:d4bb1e33950e | 14 | * limitations under the License. |
mbed_official | 1:d4bb1e33950e | 15 | */ |
mbed_official | 1:d4bb1e33950e | 16 | |
mbed_official | 1:d4bb1e33950e | 17 | #include <events/mbed_events.h> |
mbed_official | 1:d4bb1e33950e | 18 | #include <mbed.h> |
mbed_official | 1:d4bb1e33950e | 19 | #include "ble/BLE.h" |
mbed_official | 1:d4bb1e33950e | 20 | |
mbed_official | 1:d4bb1e33950e | 21 | /** This example demonstrates all the basic setup required |
mbed_official | 1:d4bb1e33950e | 22 | * to advertise, scan and connect to other devices. |
mbed_official | 1:d4bb1e33950e | 23 | * |
mbed_official | 1:d4bb1e33950e | 24 | * It contains a single class that performs both scans and advertisements. |
mbed_official | 1:d4bb1e33950e | 25 | * |
mbed_official | 1:d4bb1e33950e | 26 | * The demonstrations happens in sequence, after each "mode" ends |
mbed_official | 1:d4bb1e33950e | 27 | * the demo jumps to the next mode to continue. There are several modes |
mbed_official | 1:d4bb1e33950e | 28 | * that show scanning and several showing advertising. These are configured |
mbed_official | 1:d4bb1e33950e | 29 | * according to the two arrays containing parameters. During scanning |
mbed_official | 1:d4bb1e33950e | 30 | * a connection will be made to a connectable device upon its discovery. |
mbed_official | 1:d4bb1e33950e | 31 | */ |
mbed_official | 1:d4bb1e33950e | 32 | |
mbed_official | 1:d4bb1e33950e | 33 | static const uint8_t DEVICE_NAME[] = "GAP_device"; |
mbed_official | 1:d4bb1e33950e | 34 | |
mbed_official | 1:d4bb1e33950e | 35 | /* Duration of each mode in milliseconds */ |
mbed_official | 1:d4bb1e33950e | 36 | static const size_t MODE_DURATION_MS = 6000; |
mbed_official | 1:d4bb1e33950e | 37 | |
mbed_official | 1:d4bb1e33950e | 38 | /* Time between each mode in milliseconds */ |
mbed_official | 1:d4bb1e33950e | 39 | static const size_t TIME_BETWEEN_MODES_MS = 2000; |
mbed_official | 1:d4bb1e33950e | 40 | |
mbed_official | 1:d4bb1e33950e | 41 | /* how long to wait before disconnecting in milliseconds */ |
mbed_official | 1:d4bb1e33950e | 42 | static const size_t CONNECTION_DURATION = 3000; |
mbed_official | 1:d4bb1e33950e | 43 | |
mbed_official | 1:d4bb1e33950e | 44 | typedef struct { |
mbed_official | 1:d4bb1e33950e | 45 | GapAdvertisingParams::AdvertisingType_t adv_type; |
mbed_official | 1:d4bb1e33950e | 46 | uint16_t interval; |
mbed_official | 1:d4bb1e33950e | 47 | uint16_t timeout; |
mbed_official | 1:d4bb1e33950e | 48 | } AdvModeParam_t; |
mbed_official | 1:d4bb1e33950e | 49 | |
mbed_official | 1:d4bb1e33950e | 50 | typedef struct { |
mbed_official | 1:d4bb1e33950e | 51 | uint16_t interval; |
mbed_official | 1:d4bb1e33950e | 52 | uint16_t window; |
mbed_official | 1:d4bb1e33950e | 53 | uint16_t timeout; |
mbed_official | 1:d4bb1e33950e | 54 | bool active; |
mbed_official | 1:d4bb1e33950e | 55 | } ScanModeParam_t; |
mbed_official | 1:d4bb1e33950e | 56 | |
mbed_official | 1:d4bb1e33950e | 57 | /** the entries in this array are used to configure our advertising |
mbed_official | 1:d4bb1e33950e | 58 | * parameters for each of the modes we use in our demo */ |
mbed_official | 1:d4bb1e33950e | 59 | static const AdvModeParam_t advertising_params[] = { |
mbed_official | 1:d4bb1e33950e | 60 | /* advertising type interval timeout */ |
mbed_official | 1:d4bb1e33950e | 61 | { GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, 40,/*ms*/ 3/*s*/}, |
mbed_official | 1:d4bb1e33950e | 62 | { GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED, 100, 4 }, |
mbed_official | 1:d4bb1e33950e | 63 | { GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED, 100, 0 } |
mbed_official | 1:d4bb1e33950e | 64 | }; |
mbed_official | 1:d4bb1e33950e | 65 | |
mbed_official | 1:d4bb1e33950e | 66 | /* when we cycle through all our advertising modes we will move to scanning modes */ |
mbed_official | 1:d4bb1e33950e | 67 | |
mbed_official | 1:d4bb1e33950e | 68 | /** the entries in this array are used to configure our scanning |
mbed_official | 1:d4bb1e33950e | 69 | * parameters for each of the modes we use in our demo */ |
mbed_official | 1:d4bb1e33950e | 70 | static const ScanModeParam_t scanning_params[] = { |
mbed_official | 1:d4bb1e33950e | 71 | /* interval window timeout active */ |
mbed_official | 1:d4bb1e33950e | 72 | { 4,/*ms*/ 4,/*ms*/ 0,/*s*/ false }, |
mbed_official | 1:d4bb1e33950e | 73 | { 160, 100, 3, false }, |
mbed_official | 1:d4bb1e33950e | 74 | { 160, 40, 0, true }, |
mbed_official | 1:d4bb1e33950e | 75 | { 500, 10, 0, false } |
mbed_official | 1:d4bb1e33950e | 76 | }; |
mbed_official | 1:d4bb1e33950e | 77 | |
mbed_official | 1:d4bb1e33950e | 78 | /* parameters to use when attempting to connect to maximise speed of connection */ |
mbed_official | 1:d4bb1e33950e | 79 | static const GapScanningParams connection_scan_params( |
mbed_official | 1:d4bb1e33950e | 80 | GapScanningParams::SCAN_INTERVAL_MAX, |
mbed_official | 1:d4bb1e33950e | 81 | GapScanningParams::SCAN_WINDOW_MAX, |
mbed_official | 1:d4bb1e33950e | 82 | 3, |
mbed_official | 1:d4bb1e33950e | 83 | false |
mbed_official | 1:d4bb1e33950e | 84 | ); |
mbed_official | 1:d4bb1e33950e | 85 | |
mbed_official | 1:d4bb1e33950e | 86 | /* get number of items in our arrays */ |
mbed_official | 1:d4bb1e33950e | 87 | static const size_t SCAN_PARAM_SET_MAX = |
mbed_official | 1:d4bb1e33950e | 88 | sizeof(scanning_params) / sizeof(GapScanningParams); |
mbed_official | 1:d4bb1e33950e | 89 | static const size_t ADV_PARAM_SET_MAX = |
mbed_official | 1:d4bb1e33950e | 90 | sizeof(advertising_params) / sizeof(GapAdvertisingParams); |
mbed_official | 1:d4bb1e33950e | 91 | |
mbed_official | 10:6f1c573093c1 | 92 | static const char* to_string(Gap::Phy_t phy) { |
mbed_official | 10:6f1c573093c1 | 93 | switch(phy.value()) { |
mbed_official | 10:6f1c573093c1 | 94 | case Gap::Phy_t::LE_1M: |
mbed_official | 10:6f1c573093c1 | 95 | return "LE 1M"; |
mbed_official | 10:6f1c573093c1 | 96 | case Gap::Phy_t::LE_2M: |
mbed_official | 10:6f1c573093c1 | 97 | return "LE 2M"; |
mbed_official | 10:6f1c573093c1 | 98 | case Gap::Phy_t::LE_CODED: |
mbed_official | 10:6f1c573093c1 | 99 | return "LE coded"; |
mbed_official | 10:6f1c573093c1 | 100 | default: |
mbed_official | 10:6f1c573093c1 | 101 | return "invalid PHY"; |
mbed_official | 10:6f1c573093c1 | 102 | } |
mbed_official | 10:6f1c573093c1 | 103 | } |
mbed_official | 1:d4bb1e33950e | 104 | |
mbed_official | 1:d4bb1e33950e | 105 | /** Demonstrate advertising, scanning and connecting |
mbed_official | 1:d4bb1e33950e | 106 | */ |
mbed_official | 10:6f1c573093c1 | 107 | class GAPDevice : private mbed::NonCopyable<GAPDevice>, public Gap::EventHandler |
mbed_official | 1:d4bb1e33950e | 108 | { |
mbed_official | 1:d4bb1e33950e | 109 | public: |
mbed_official | 1:d4bb1e33950e | 110 | GAPDevice() : |
mbed_official | 1:d4bb1e33950e | 111 | _ble(BLE::Instance()), |
mbed_official | 1:d4bb1e33950e | 112 | _led1(LED1, 0), |
mbed_official | 1:d4bb1e33950e | 113 | _set_index(0), |
mbed_official | 1:d4bb1e33950e | 114 | _is_in_scanning_mode(false), |
mbed_official | 1:d4bb1e33950e | 115 | _is_connecting(false), |
mbed_official | 1:d4bb1e33950e | 116 | _on_duration_end_id(0), |
mbed_official | 1:d4bb1e33950e | 117 | _scan_count(0) { }; |
mbed_official | 1:d4bb1e33950e | 118 | |
mbed_official | 1:d4bb1e33950e | 119 | ~GAPDevice() |
mbed_official | 1:d4bb1e33950e | 120 | { |
mbed_official | 1:d4bb1e33950e | 121 | if (_ble.hasInitialized()) { |
mbed_official | 1:d4bb1e33950e | 122 | _ble.shutdown(); |
mbed_official | 1:d4bb1e33950e | 123 | } |
mbed_official | 1:d4bb1e33950e | 124 | }; |
mbed_official | 1:d4bb1e33950e | 125 | |
mbed_official | 1:d4bb1e33950e | 126 | /** Start BLE interface initialisation */ |
mbed_official | 1:d4bb1e33950e | 127 | void run() |
mbed_official | 1:d4bb1e33950e | 128 | { |
mbed_official | 1:d4bb1e33950e | 129 | ble_error_t error; |
mbed_official | 1:d4bb1e33950e | 130 | |
mbed_official | 1:d4bb1e33950e | 131 | if (_ble.hasInitialized()) { |
mbed_official | 1:d4bb1e33950e | 132 | printf("Ble instance already initialised.\r\n"); |
mbed_official | 1:d4bb1e33950e | 133 | return; |
mbed_official | 1:d4bb1e33950e | 134 | } |
mbed_official | 1:d4bb1e33950e | 135 | |
mbed_official | 1:d4bb1e33950e | 136 | /* this will inform us off all events so we can schedule their handling |
mbed_official | 1:d4bb1e33950e | 137 | * using our event queue */ |
mbed_official | 1:d4bb1e33950e | 138 | _ble.onEventsToProcess( |
mbed_official | 1:d4bb1e33950e | 139 | makeFunctionPointer(this, &GAPDevice::schedule_ble_events) |
mbed_official | 1:d4bb1e33950e | 140 | ); |
mbed_official | 1:d4bb1e33950e | 141 | |
mbed_official | 1:d4bb1e33950e | 142 | /* handle timeouts, for example when connection attempts fail */ |
mbed_official | 1:d4bb1e33950e | 143 | _ble.gap().onTimeout( |
mbed_official | 1:d4bb1e33950e | 144 | makeFunctionPointer(this, &GAPDevice::on_timeout) |
mbed_official | 1:d4bb1e33950e | 145 | ); |
mbed_official | 1:d4bb1e33950e | 146 | |
mbed_official | 10:6f1c573093c1 | 147 | /* handle gap events */ |
mbed_official | 10:6f1c573093c1 | 148 | _ble.gap().setEventHandler(this); |
mbed_official | 10:6f1c573093c1 | 149 | |
mbed_official | 1:d4bb1e33950e | 150 | error = _ble.init(this, &GAPDevice::on_init_complete); |
mbed_official | 1:d4bb1e33950e | 151 | |
mbed_official | 1:d4bb1e33950e | 152 | if (error) { |
mbed_official | 1:d4bb1e33950e | 153 | printf("Error returned by BLE::init.\r\n"); |
mbed_official | 1:d4bb1e33950e | 154 | return; |
mbed_official | 1:d4bb1e33950e | 155 | } |
mbed_official | 1:d4bb1e33950e | 156 | |
mbed_official | 1:d4bb1e33950e | 157 | /* to show we're running we'll blink every 500ms */ |
mbed_official | 1:d4bb1e33950e | 158 | _event_queue.call_every(500, this, &GAPDevice::blink); |
mbed_official | 1:d4bb1e33950e | 159 | |
mbed_official | 1:d4bb1e33950e | 160 | /* this will not return until shutdown */ |
mbed_official | 1:d4bb1e33950e | 161 | _event_queue.dispatch_forever(); |
mbed_official | 1:d4bb1e33950e | 162 | }; |
mbed_official | 1:d4bb1e33950e | 163 | |
mbed_official | 1:d4bb1e33950e | 164 | private: |
mbed_official | 1:d4bb1e33950e | 165 | /** This is called when BLE interface is initialised and starts the first mode */ |
mbed_official | 1:d4bb1e33950e | 166 | void on_init_complete(BLE::InitializationCompleteCallbackContext *event) |
mbed_official | 1:d4bb1e33950e | 167 | { |
mbed_official | 1:d4bb1e33950e | 168 | if (event->error) { |
mbed_official | 1:d4bb1e33950e | 169 | printf("Error during the initialisation\r\n"); |
mbed_official | 1:d4bb1e33950e | 170 | return; |
mbed_official | 1:d4bb1e33950e | 171 | } |
mbed_official | 1:d4bb1e33950e | 172 | |
mbed_official | 1:d4bb1e33950e | 173 | /* print device address */ |
mbed_official | 1:d4bb1e33950e | 174 | Gap::AddressType_t addr_type; |
mbed_official | 1:d4bb1e33950e | 175 | Gap::Address_t addr; |
mbed_official | 1:d4bb1e33950e | 176 | _ble.gap().getAddress(&addr_type, addr); |
mbed_official | 1:d4bb1e33950e | 177 | printf("Device address: %02x:%02x:%02x:%02x:%02x:%02x\r\n", |
mbed_official | 1:d4bb1e33950e | 178 | addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); |
mbed_official | 1:d4bb1e33950e | 179 | |
mbed_official | 10:6f1c573093c1 | 180 | /* setup the default phy used in connection to 2M to reduce power consumption */ |
mbed_official | 11:37872bf83624 | 181 | Gap::PhySet_t tx_phys(/* 1M */ false, /* 2M */ true, /* coded */ false); |
mbed_official | 11:37872bf83624 | 182 | Gap::PhySet_t rx_phys(/* 1M */ false, /* 2M */ true, /* coded */ false); |
mbed_official | 11:37872bf83624 | 183 | ble_error_t err = _ble.gap().setPreferredPhys(&tx_phys, &rx_phys); |
mbed_official | 10:6f1c573093c1 | 184 | if (err) { |
mbed_official | 10:6f1c573093c1 | 185 | printf("INFO: GAP::setPreferedPhys failed with error code %s", BLE::errorToString(err)); |
mbed_official | 10:6f1c573093c1 | 186 | } |
mbed_official | 10:6f1c573093c1 | 187 | |
mbed_official | 1:d4bb1e33950e | 188 | /* all calls are serialised on the user thread through the event queue */ |
mbed_official | 1:d4bb1e33950e | 189 | _event_queue.call(this, &GAPDevice::demo_mode_start); |
mbed_official | 1:d4bb1e33950e | 190 | }; |
mbed_official | 1:d4bb1e33950e | 191 | |
mbed_official | 1:d4bb1e33950e | 192 | /** queue up start of the current demo mode */ |
mbed_official | 1:d4bb1e33950e | 193 | void demo_mode_start() |
mbed_official | 1:d4bb1e33950e | 194 | { |
mbed_official | 1:d4bb1e33950e | 195 | if (_is_in_scanning_mode) { |
mbed_official | 1:d4bb1e33950e | 196 | /* when scanning we want to connect to a peer device so we need to |
mbed_official | 1:d4bb1e33950e | 197 | * attach callbacks that are used by Gap to notify us of events */ |
mbed_official | 1:d4bb1e33950e | 198 | _ble.gap().onConnection(this, &GAPDevice::on_connect); |
mbed_official | 1:d4bb1e33950e | 199 | _ble.gap().onDisconnection(this, &GAPDevice::on_disconnect); |
mbed_official | 1:d4bb1e33950e | 200 | |
mbed_official | 1:d4bb1e33950e | 201 | _event_queue.call(this, &GAPDevice::scan); |
mbed_official | 1:d4bb1e33950e | 202 | } else { |
mbed_official | 1:d4bb1e33950e | 203 | _event_queue.call(this, &GAPDevice::advertise); |
mbed_official | 1:d4bb1e33950e | 204 | } |
mbed_official | 1:d4bb1e33950e | 205 | |
mbed_official | 1:d4bb1e33950e | 206 | /* for performance measurement keep track of duration of the demo mode */ |
mbed_official | 1:d4bb1e33950e | 207 | _demo_duration.start(); |
mbed_official | 1:d4bb1e33950e | 208 | /* keep track of our state */ |
mbed_official | 1:d4bb1e33950e | 209 | _is_connecting = false; |
mbed_official | 1:d4bb1e33950e | 210 | |
mbed_official | 1:d4bb1e33950e | 211 | /* queue up next demo mode */ |
mbed_official | 1:d4bb1e33950e | 212 | _on_duration_end_id = _event_queue.call_in( |
mbed_official | 1:d4bb1e33950e | 213 | MODE_DURATION_MS, this, &GAPDevice::on_duration_end |
mbed_official | 1:d4bb1e33950e | 214 | ); |
mbed_official | 1:d4bb1e33950e | 215 | |
mbed_official | 1:d4bb1e33950e | 216 | printf("\r\n"); |
mbed_official | 1:d4bb1e33950e | 217 | } |
mbed_official | 1:d4bb1e33950e | 218 | |
mbed_official | 1:d4bb1e33950e | 219 | /** Set up and start advertising */ |
mbed_official | 1:d4bb1e33950e | 220 | void advertise() |
mbed_official | 1:d4bb1e33950e | 221 | { |
mbed_official | 1:d4bb1e33950e | 222 | ble_error_t error; |
mbed_official | 1:d4bb1e33950e | 223 | GapAdvertisingData advertising_data; |
mbed_official | 1:d4bb1e33950e | 224 | |
mbed_official | 1:d4bb1e33950e | 225 | /* add advertising flags */ |
mbed_official | 1:d4bb1e33950e | 226 | advertising_data.addFlags(GapAdvertisingData::LE_GENERAL_DISCOVERABLE |
mbed_official | 1:d4bb1e33950e | 227 | | GapAdvertisingData::BREDR_NOT_SUPPORTED); |
mbed_official | 1:d4bb1e33950e | 228 | |
mbed_official | 1:d4bb1e33950e | 229 | /* add device name */ |
mbed_official | 1:d4bb1e33950e | 230 | advertising_data.addData( |
mbed_official | 1:d4bb1e33950e | 231 | GapAdvertisingData::COMPLETE_LOCAL_NAME, |
mbed_official | 1:d4bb1e33950e | 232 | DEVICE_NAME, |
mbed_official | 1:d4bb1e33950e | 233 | sizeof(DEVICE_NAME) |
mbed_official | 1:d4bb1e33950e | 234 | ); |
mbed_official | 1:d4bb1e33950e | 235 | |
mbed_official | 1:d4bb1e33950e | 236 | error = _ble.gap().setAdvertisingPayload(advertising_data); |
mbed_official | 1:d4bb1e33950e | 237 | |
mbed_official | 1:d4bb1e33950e | 238 | if (error) { |
mbed_official | 1:d4bb1e33950e | 239 | printf("Error during Gap::setAdvertisingPayload\r\n"); |
mbed_official | 1:d4bb1e33950e | 240 | return; |
mbed_official | 1:d4bb1e33950e | 241 | } |
mbed_official | 1:d4bb1e33950e | 242 | |
mbed_official | 1:d4bb1e33950e | 243 | /* set the advertising parameters according to currently selected set, |
mbed_official | 1:d4bb1e33950e | 244 | * see @AdvertisingType_t for explanation of modes */ |
mbed_official | 1:d4bb1e33950e | 245 | GapAdvertisingParams::AdvertisingType_t adv_type = |
mbed_official | 1:d4bb1e33950e | 246 | advertising_params[_set_index].adv_type; |
mbed_official | 1:d4bb1e33950e | 247 | |
mbed_official | 1:d4bb1e33950e | 248 | /* how many milliseconds between advertisements, lower interval |
mbed_official | 1:d4bb1e33950e | 249 | * increases the chances of being seen at the cost of more power */ |
mbed_official | 1:d4bb1e33950e | 250 | uint16_t interval = advertising_params[_set_index].interval; |
mbed_official | 1:d4bb1e33950e | 251 | |
mbed_official | 1:d4bb1e33950e | 252 | /* advertising will continue for this many seconds or until connected */ |
mbed_official | 1:d4bb1e33950e | 253 | uint16_t timeout = advertising_params[_set_index].timeout; |
mbed_official | 1:d4bb1e33950e | 254 | |
mbed_official | 1:d4bb1e33950e | 255 | _ble.gap().setAdvertisingType(adv_type); |
mbed_official | 1:d4bb1e33950e | 256 | _ble.gap().setAdvertisingInterval(interval); |
mbed_official | 1:d4bb1e33950e | 257 | _ble.gap().setAdvertisingTimeout(timeout); |
mbed_official | 1:d4bb1e33950e | 258 | |
mbed_official | 1:d4bb1e33950e | 259 | error = _ble.gap().startAdvertising(); |
mbed_official | 1:d4bb1e33950e | 260 | |
mbed_official | 1:d4bb1e33950e | 261 | if (error) { |
mbed_official | 1:d4bb1e33950e | 262 | printf("Error during Gap::startAdvertising.\r\n"); |
mbed_official | 1:d4bb1e33950e | 263 | return; |
mbed_official | 1:d4bb1e33950e | 264 | } |
mbed_official | 1:d4bb1e33950e | 265 | |
mbed_official | 1:d4bb1e33950e | 266 | printf("Advertising started (type: 0x%x, interval: %dms, timeout: %ds)\r\n", |
mbed_official | 1:d4bb1e33950e | 267 | adv_type, interval, timeout); |
mbed_official | 1:d4bb1e33950e | 268 | }; |
mbed_official | 1:d4bb1e33950e | 269 | |
mbed_official | 1:d4bb1e33950e | 270 | /** Set up and start scanning */ |
mbed_official | 1:d4bb1e33950e | 271 | void scan() |
mbed_official | 1:d4bb1e33950e | 272 | { |
mbed_official | 1:d4bb1e33950e | 273 | ble_error_t error; |
mbed_official | 1:d4bb1e33950e | 274 | |
mbed_official | 1:d4bb1e33950e | 275 | /* scanning happens repeatedly, interval is the number of milliseconds |
mbed_official | 1:d4bb1e33950e | 276 | * between each cycle of scanning */ |
mbed_official | 1:d4bb1e33950e | 277 | uint16_t interval = scanning_params[_set_index].interval; |
mbed_official | 1:d4bb1e33950e | 278 | |
mbed_official | 1:d4bb1e33950e | 279 | /* number of milliseconds we scan for each time we enter |
mbed_official | 1:d4bb1e33950e | 280 | * the scanning cycle after the interval set above */ |
mbed_official | 1:d4bb1e33950e | 281 | uint16_t window = scanning_params[_set_index].window; |
mbed_official | 1:d4bb1e33950e | 282 | |
mbed_official | 1:d4bb1e33950e | 283 | /* how long to repeat the cycles of scanning in seconds */ |
mbed_official | 1:d4bb1e33950e | 284 | uint16_t timeout = scanning_params[_set_index].timeout; |
mbed_official | 1:d4bb1e33950e | 285 | |
mbed_official | 1:d4bb1e33950e | 286 | /* active scanning will send a scan request to any scanable devices that |
mbed_official | 1:d4bb1e33950e | 287 | * we see advertising */ |
mbed_official | 1:d4bb1e33950e | 288 | bool active = scanning_params[_set_index].active; |
mbed_official | 1:d4bb1e33950e | 289 | |
mbed_official | 1:d4bb1e33950e | 290 | /* set the scanning parameters according to currently selected set */ |
mbed_official | 1:d4bb1e33950e | 291 | error = _ble.gap().setScanParams(interval, window, timeout, active); |
mbed_official | 1:d4bb1e33950e | 292 | |
mbed_official | 1:d4bb1e33950e | 293 | if (error) { |
mbed_official | 1:d4bb1e33950e | 294 | printf("Error during Gap::setScanParams\r\n"); |
mbed_official | 1:d4bb1e33950e | 295 | return; |
mbed_official | 1:d4bb1e33950e | 296 | } |
mbed_official | 1:d4bb1e33950e | 297 | |
mbed_official | 1:d4bb1e33950e | 298 | /* start scanning and attach a callback that will handle advertisements |
mbed_official | 1:d4bb1e33950e | 299 | * and scan requests responses */ |
mbed_official | 1:d4bb1e33950e | 300 | error = _ble.gap().startScan(this, &GAPDevice::on_scan); |
mbed_official | 1:d4bb1e33950e | 301 | |
mbed_official | 1:d4bb1e33950e | 302 | if (error) { |
mbed_official | 1:d4bb1e33950e | 303 | printf("Error during Gap::startScan\r\n"); |
mbed_official | 1:d4bb1e33950e | 304 | return; |
mbed_official | 1:d4bb1e33950e | 305 | } |
mbed_official | 1:d4bb1e33950e | 306 | |
mbed_official | 1:d4bb1e33950e | 307 | printf("Scanning started (interval: %dms, window: %dms, timeout: %ds).\r\n", |
mbed_official | 1:d4bb1e33950e | 308 | interval, window, timeout); |
mbed_official | 1:d4bb1e33950e | 309 | }; |
mbed_official | 1:d4bb1e33950e | 310 | |
mbed_official | 1:d4bb1e33950e | 311 | /** After a set duration this cycles to the next demo mode |
mbed_official | 1:d4bb1e33950e | 312 | * unless a connection happened first */ |
mbed_official | 1:d4bb1e33950e | 313 | void on_duration_end() |
mbed_official | 1:d4bb1e33950e | 314 | { |
mbed_official | 1:d4bb1e33950e | 315 | print_performance(); |
mbed_official | 1:d4bb1e33950e | 316 | |
mbed_official | 1:d4bb1e33950e | 317 | /* alloted time has elapsed, move to next demo mode */ |
mbed_official | 1:d4bb1e33950e | 318 | _event_queue.call(this, &GAPDevice::demo_mode_end); |
mbed_official | 1:d4bb1e33950e | 319 | }; |
mbed_official | 1:d4bb1e33950e | 320 | |
mbed_official | 1:d4bb1e33950e | 321 | /** Look at scan payload to find a peer device and connect to it */ |
mbed_official | 1:d4bb1e33950e | 322 | void on_scan(const Gap::AdvertisementCallbackParams_t *params) |
mbed_official | 1:d4bb1e33950e | 323 | { |
mbed_official | 1:d4bb1e33950e | 324 | /* keep track of scan events for performance reporting */ |
mbed_official | 1:d4bb1e33950e | 325 | _scan_count++; |
mbed_official | 1:d4bb1e33950e | 326 | |
mbed_official | 1:d4bb1e33950e | 327 | /* don't bother with analysing scan result if we're already connecting */ |
mbed_official | 1:d4bb1e33950e | 328 | if (_is_connecting) { |
mbed_official | 1:d4bb1e33950e | 329 | return; |
mbed_official | 1:d4bb1e33950e | 330 | } |
mbed_official | 1:d4bb1e33950e | 331 | |
mbed_official | 1:d4bb1e33950e | 332 | /* parse the advertising payload, looking for a discoverable device */ |
mbed_official | 1:d4bb1e33950e | 333 | for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { |
mbed_official | 1:d4bb1e33950e | 334 | /* The advertising payload is a collection of key/value records where |
mbed_official | 1:d4bb1e33950e | 335 | * byte 0: length of the record excluding this byte |
mbed_official | 1:d4bb1e33950e | 336 | * byte 1: The key, it is the type of the data |
mbed_official | 1:d4bb1e33950e | 337 | * byte [2..N] The value. N is equal to byte0 - 1 */ |
mbed_official | 1:d4bb1e33950e | 338 | const uint8_t record_length = params->advertisingData[i]; |
mbed_official | 1:d4bb1e33950e | 339 | if (record_length == 0) { |
mbed_official | 1:d4bb1e33950e | 340 | continue; |
mbed_official | 1:d4bb1e33950e | 341 | } |
mbed_official | 1:d4bb1e33950e | 342 | const uint8_t type = params->advertisingData[i + 1]; |
mbed_official | 1:d4bb1e33950e | 343 | const uint8_t *value = params->advertisingData + i + 2; |
mbed_official | 1:d4bb1e33950e | 344 | |
mbed_official | 1:d4bb1e33950e | 345 | /* connect to a discoverable device */ |
mbed_official | 1:d4bb1e33950e | 346 | if ((type == GapAdvertisingData::FLAGS) |
mbed_official | 1:d4bb1e33950e | 347 | && (*value & GapAdvertisingData::LE_GENERAL_DISCOVERABLE)) { |
mbed_official | 1:d4bb1e33950e | 348 | |
mbed_official | 1:d4bb1e33950e | 349 | /* abort timeout as the mode will end on disconnection */ |
mbed_official | 1:d4bb1e33950e | 350 | _event_queue.cancel(_on_duration_end_id); |
mbed_official | 1:d4bb1e33950e | 351 | |
mbed_official | 1:d4bb1e33950e | 352 | printf("We found a connectable device\r\n"); |
mbed_official | 1:d4bb1e33950e | 353 | |
mbed_official | 1:d4bb1e33950e | 354 | ble_error_t error = _ble.gap().connect( |
mbed_official | 1:d4bb1e33950e | 355 | params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, |
mbed_official | 1:d4bb1e33950e | 356 | NULL, &connection_scan_params |
mbed_official | 1:d4bb1e33950e | 357 | ); |
mbed_official | 1:d4bb1e33950e | 358 | |
mbed_official | 1:d4bb1e33950e | 359 | if (error) { |
mbed_official | 1:d4bb1e33950e | 360 | printf("Error during Gap::connect\r\n"); |
mbed_official | 1:d4bb1e33950e | 361 | /* since no connection will be attempted end the mode */ |
mbed_official | 1:d4bb1e33950e | 362 | _event_queue.call(this, &GAPDevice::demo_mode_end); |
mbed_official | 1:d4bb1e33950e | 363 | return; |
mbed_official | 1:d4bb1e33950e | 364 | } |
mbed_official | 1:d4bb1e33950e | 365 | |
mbed_official | 1:d4bb1e33950e | 366 | /* we may have already scan events waiting |
mbed_official | 1:d4bb1e33950e | 367 | * to be processed so we need to remember |
mbed_official | 1:d4bb1e33950e | 368 | * that we are already connecting and ignore them */ |
mbed_official | 1:d4bb1e33950e | 369 | _is_connecting = true; |
mbed_official | 1:d4bb1e33950e | 370 | |
mbed_official | 1:d4bb1e33950e | 371 | return; |
mbed_official | 1:d4bb1e33950e | 372 | } |
mbed_official | 1:d4bb1e33950e | 373 | |
mbed_official | 1:d4bb1e33950e | 374 | i += record_length; |
mbed_official | 1:d4bb1e33950e | 375 | } |
mbed_official | 1:d4bb1e33950e | 376 | }; |
mbed_official | 1:d4bb1e33950e | 377 | |
mbed_official | 1:d4bb1e33950e | 378 | /** This is called by Gap to notify the application we connected, |
mbed_official | 1:d4bb1e33950e | 379 | * in our case it immediately disconnects */ |
mbed_official | 1:d4bb1e33950e | 380 | void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) |
mbed_official | 1:d4bb1e33950e | 381 | { |
mbed_official | 1:d4bb1e33950e | 382 | print_performance(); |
mbed_official | 1:d4bb1e33950e | 383 | |
mbed_official | 1:d4bb1e33950e | 384 | printf("Connected in %dms\r\n", _demo_duration.read_ms()); |
mbed_official | 1:d4bb1e33950e | 385 | |
mbed_official | 1:d4bb1e33950e | 386 | /* cancel the connect timeout since we connected */ |
mbed_official | 1:d4bb1e33950e | 387 | _event_queue.cancel(_on_duration_end_id); |
mbed_official | 1:d4bb1e33950e | 388 | |
mbed_official | 1:d4bb1e33950e | 389 | _event_queue.call_in( |
mbed_official | 1:d4bb1e33950e | 390 | CONNECTION_DURATION, &_ble.gap(), &Gap::disconnect, Gap::REMOTE_USER_TERMINATED_CONNECTION |
mbed_official | 1:d4bb1e33950e | 391 | ); |
mbed_official | 1:d4bb1e33950e | 392 | }; |
mbed_official | 1:d4bb1e33950e | 393 | |
mbed_official | 1:d4bb1e33950e | 394 | /** This is called by Gap to notify the application we disconnected, |
mbed_official | 1:d4bb1e33950e | 395 | * in our case it calls demo_mode_end() to progress the demo */ |
mbed_official | 1:d4bb1e33950e | 396 | void on_disconnect(const Gap::DisconnectionCallbackParams_t *event) |
mbed_official | 1:d4bb1e33950e | 397 | { |
mbed_official | 1:d4bb1e33950e | 398 | printf("Disconnected\r\n"); |
mbed_official | 1:d4bb1e33950e | 399 | |
mbed_official | 1:d4bb1e33950e | 400 | /* we have successfully disconnected ending the demo, move to next mode */ |
mbed_official | 1:d4bb1e33950e | 401 | _event_queue.call(this, &GAPDevice::demo_mode_end); |
mbed_official | 1:d4bb1e33950e | 402 | }; |
mbed_official | 1:d4bb1e33950e | 403 | |
mbed_official | 10:6f1c573093c1 | 404 | /** |
mbed_official | 10:6f1c573093c1 | 405 | * Implementation of Gap::EventHandler::onReadPhy |
mbed_official | 10:6f1c573093c1 | 406 | */ |
mbed_official | 10:6f1c573093c1 | 407 | virtual void onReadPhy( |
mbed_official | 10:6f1c573093c1 | 408 | ble_error_t error, |
mbed_official | 10:6f1c573093c1 | 409 | Gap::Handle_t connectionHandle, |
mbed_official | 10:6f1c573093c1 | 410 | Gap::Phy_t txPhy, |
mbed_official | 10:6f1c573093c1 | 411 | Gap::Phy_t rxPhy |
mbed_official | 10:6f1c573093c1 | 412 | ) { |
mbed_official | 10:6f1c573093c1 | 413 | if (error) { |
mbed_official | 10:6f1c573093c1 | 414 | printf( |
mbed_official | 10:6f1c573093c1 | 415 | "Phy read on connection %d failed with error code %s\r\n", |
mbed_official | 10:6f1c573093c1 | 416 | connectionHandle, |
mbed_official | 10:6f1c573093c1 | 417 | BLE::errorToString(error) |
mbed_official | 10:6f1c573093c1 | 418 | ); |
mbed_official | 10:6f1c573093c1 | 419 | } else { |
mbed_official | 10:6f1c573093c1 | 420 | printf( |
mbed_official | 10:6f1c573093c1 | 421 | "Phy read on connection %d - Tx Phy: %s, Rx Phy: %s\r\n", |
mbed_official | 10:6f1c573093c1 | 422 | connectionHandle, |
mbed_official | 10:6f1c573093c1 | 423 | to_string(txPhy), |
mbed_official | 10:6f1c573093c1 | 424 | to_string(rxPhy) |
mbed_official | 10:6f1c573093c1 | 425 | ); |
mbed_official | 10:6f1c573093c1 | 426 | } |
mbed_official | 10:6f1c573093c1 | 427 | } |
mbed_official | 10:6f1c573093c1 | 428 | |
mbed_official | 10:6f1c573093c1 | 429 | /** |
mbed_official | 10:6f1c573093c1 | 430 | * Implementation of Gap::EventHandler::onPhyUpdateComplete |
mbed_official | 10:6f1c573093c1 | 431 | */ |
mbed_official | 10:6f1c573093c1 | 432 | virtual void onPhyUpdateComplete( |
mbed_official | 10:6f1c573093c1 | 433 | ble_error_t error, |
mbed_official | 10:6f1c573093c1 | 434 | Gap::Handle_t connectionHandle, |
mbed_official | 10:6f1c573093c1 | 435 | Gap::Phy_t txPhy, |
mbed_official | 10:6f1c573093c1 | 436 | Gap::Phy_t rxPhy |
mbed_official | 10:6f1c573093c1 | 437 | ) { |
mbed_official | 10:6f1c573093c1 | 438 | if (error) { |
mbed_official | 10:6f1c573093c1 | 439 | printf( |
mbed_official | 10:6f1c573093c1 | 440 | "Phy update on connection: %d failed with error code %s\r\n", |
mbed_official | 10:6f1c573093c1 | 441 | connectionHandle, |
mbed_official | 10:6f1c573093c1 | 442 | BLE::errorToString(error) |
mbed_official | 10:6f1c573093c1 | 443 | ); |
mbed_official | 10:6f1c573093c1 | 444 | } else { |
mbed_official | 10:6f1c573093c1 | 445 | printf( |
mbed_official | 10:6f1c573093c1 | 446 | "Phy update on connection %d - Tx Phy: %s, Rx Phy: %s\r\n", |
mbed_official | 10:6f1c573093c1 | 447 | connectionHandle, |
mbed_official | 10:6f1c573093c1 | 448 | to_string(txPhy), |
mbed_official | 10:6f1c573093c1 | 449 | to_string(rxPhy) |
mbed_official | 10:6f1c573093c1 | 450 | ); |
mbed_official | 10:6f1c573093c1 | 451 | } |
mbed_official | 10:6f1c573093c1 | 452 | } |
mbed_official | 10:6f1c573093c1 | 453 | |
mbed_official | 1:d4bb1e33950e | 454 | /** called if timeout is reached during advertising, scanning |
mbed_official | 1:d4bb1e33950e | 455 | * or connection initiation */ |
mbed_official | 1:d4bb1e33950e | 456 | void on_timeout(const Gap::TimeoutSource_t source) |
mbed_official | 1:d4bb1e33950e | 457 | { |
mbed_official | 1:d4bb1e33950e | 458 | _demo_duration.stop(); |
mbed_official | 1:d4bb1e33950e | 459 | |
mbed_official | 1:d4bb1e33950e | 460 | switch (source) { |
mbed_official | 1:d4bb1e33950e | 461 | case Gap::TIMEOUT_SRC_ADVERTISING: |
mbed_official | 1:d4bb1e33950e | 462 | printf("Stopped advertising early due to timeout parameter\r\n"); |
mbed_official | 1:d4bb1e33950e | 463 | break; |
mbed_official | 1:d4bb1e33950e | 464 | case Gap::TIMEOUT_SRC_SCAN: |
mbed_official | 1:d4bb1e33950e | 465 | printf("Stopped scanning early due to timeout parameter\r\n"); |
mbed_official | 1:d4bb1e33950e | 466 | break; |
mbed_official | 1:d4bb1e33950e | 467 | case Gap::TIMEOUT_SRC_CONN: |
mbed_official | 1:d4bb1e33950e | 468 | printf("Failed to connect after scanning %d advertisements\r\n", _scan_count); |
mbed_official | 1:d4bb1e33950e | 469 | _event_queue.call(this, &GAPDevice::print_performance); |
mbed_official | 1:d4bb1e33950e | 470 | _event_queue.call(this, &GAPDevice::demo_mode_end); |
mbed_official | 1:d4bb1e33950e | 471 | break; |
mbed_official | 1:d4bb1e33950e | 472 | default: |
mbed_official | 1:d4bb1e33950e | 473 | printf("Unexpected timeout\r\n"); |
mbed_official | 1:d4bb1e33950e | 474 | break; |
mbed_official | 1:d4bb1e33950e | 475 | } |
mbed_official | 1:d4bb1e33950e | 476 | }; |
mbed_official | 1:d4bb1e33950e | 477 | |
mbed_official | 1:d4bb1e33950e | 478 | /** clean up after last run, cycle to the next mode and launch it */ |
mbed_official | 1:d4bb1e33950e | 479 | void demo_mode_end() |
mbed_official | 1:d4bb1e33950e | 480 | { |
mbed_official | 1:d4bb1e33950e | 481 | /* reset the demo ready for the next mode */ |
mbed_official | 1:d4bb1e33950e | 482 | _scan_count = 0; |
mbed_official | 1:d4bb1e33950e | 483 | _demo_duration.stop(); |
mbed_official | 1:d4bb1e33950e | 484 | _demo_duration.reset(); |
mbed_official | 1:d4bb1e33950e | 485 | |
mbed_official | 1:d4bb1e33950e | 486 | /* cycle through all demo modes */ |
mbed_official | 1:d4bb1e33950e | 487 | _set_index++; |
mbed_official | 1:d4bb1e33950e | 488 | |
mbed_official | 1:d4bb1e33950e | 489 | /* switch between advertising and scanning when we go |
mbed_official | 1:d4bb1e33950e | 490 | * through all the params in the array */ |
mbed_official | 1:d4bb1e33950e | 491 | if (_set_index >= (_is_in_scanning_mode? SCAN_PARAM_SET_MAX : ADV_PARAM_SET_MAX)) { |
mbed_official | 1:d4bb1e33950e | 492 | _set_index = 0; |
mbed_official | 1:d4bb1e33950e | 493 | _is_in_scanning_mode = !_is_in_scanning_mode; |
mbed_official | 1:d4bb1e33950e | 494 | } |
mbed_official | 1:d4bb1e33950e | 495 | |
mbed_official | 1:d4bb1e33950e | 496 | _ble.shutdown(); |
mbed_official | 1:d4bb1e33950e | 497 | _event_queue.break_dispatch(); |
mbed_official | 1:d4bb1e33950e | 498 | }; |
mbed_official | 1:d4bb1e33950e | 499 | |
mbed_official | 1:d4bb1e33950e | 500 | /** print some information about our radio activity */ |
mbed_official | 1:d4bb1e33950e | 501 | void print_performance() |
mbed_official | 1:d4bb1e33950e | 502 | { |
mbed_official | 1:d4bb1e33950e | 503 | /* measure time from mode start, may have been stopped by timeout */ |
mbed_official | 1:d4bb1e33950e | 504 | uint16_t duration = _demo_duration.read_ms(); |
mbed_official | 1:d4bb1e33950e | 505 | |
mbed_official | 1:d4bb1e33950e | 506 | if (_is_in_scanning_mode) { |
mbed_official | 1:d4bb1e33950e | 507 | /* convert ms into timeslots for accurate calculation as internally |
mbed_official | 1:d4bb1e33950e | 508 | * all durations are in timeslots (0.625ms) */ |
mbed_official | 1:d4bb1e33950e | 509 | uint16_t interval_ts = GapScanningParams::MSEC_TO_SCAN_DURATION_UNITS( |
mbed_official | 1:d4bb1e33950e | 510 | scanning_params[_set_index].interval |
mbed_official | 1:d4bb1e33950e | 511 | ); |
mbed_official | 1:d4bb1e33950e | 512 | uint16_t window_ts = GapScanningParams::MSEC_TO_SCAN_DURATION_UNITS( |
mbed_official | 1:d4bb1e33950e | 513 | scanning_params[_set_index].window |
mbed_official | 1:d4bb1e33950e | 514 | ); |
mbed_official | 1:d4bb1e33950e | 515 | uint16_t duration_ts = GapScanningParams::MSEC_TO_SCAN_DURATION_UNITS( |
mbed_official | 1:d4bb1e33950e | 516 | duration |
mbed_official | 1:d4bb1e33950e | 517 | ); |
mbed_official | 1:d4bb1e33950e | 518 | /* this is how long we scanned for in timeslots */ |
mbed_official | 1:d4bb1e33950e | 519 | uint16_t rx_ts = (duration_ts / interval_ts) * window_ts; |
mbed_official | 1:d4bb1e33950e | 520 | /* convert to milliseconds */ |
mbed_official | 1:d4bb1e33950e | 521 | uint16_t rx_ms = (rx_ts * GapScanningParams::UNIT_0_625_MS) / 1000; |
mbed_official | 1:d4bb1e33950e | 522 | |
mbed_official | 1:d4bb1e33950e | 523 | printf("We have scanned for %dms with an interval of %d" |
mbed_official | 1:d4bb1e33950e | 524 | " timeslot and a window of %d timeslots\r\n", |
mbed_official | 1:d4bb1e33950e | 525 | duration, interval_ts, window_ts); |
mbed_official | 1:d4bb1e33950e | 526 | |
mbed_official | 1:d4bb1e33950e | 527 | printf("We have been listening on the radio for at least %dms\r\n", rx_ms); |
mbed_official | 1:d4bb1e33950e | 528 | |
mbed_official | 1:d4bb1e33950e | 529 | } else /* advertising */ { |
mbed_official | 1:d4bb1e33950e | 530 | |
mbed_official | 1:d4bb1e33950e | 531 | /* convert ms into timeslots for accurate calculation as internally |
mbed_official | 1:d4bb1e33950e | 532 | * all durations are in timeslots (0.625ms) */ |
mbed_official | 1:d4bb1e33950e | 533 | uint16_t interval_ts = GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS( |
mbed_official | 1:d4bb1e33950e | 534 | advertising_params[_set_index].interval |
mbed_official | 1:d4bb1e33950e | 535 | ); |
mbed_official | 1:d4bb1e33950e | 536 | uint16_t duration_ts = GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS( |
mbed_official | 1:d4bb1e33950e | 537 | duration |
mbed_official | 1:d4bb1e33950e | 538 | ); |
mbed_official | 1:d4bb1e33950e | 539 | /* this is how many times we advertised */ |
mbed_official | 1:d4bb1e33950e | 540 | uint16_t events = duration_ts / interval_ts; |
mbed_official | 1:d4bb1e33950e | 541 | |
mbed_official | 1:d4bb1e33950e | 542 | printf("We have advertised for %dms" |
mbed_official | 1:d4bb1e33950e | 543 | " with an interval of %d timeslots\r\n", |
mbed_official | 1:d4bb1e33950e | 544 | duration, interval_ts); |
mbed_official | 1:d4bb1e33950e | 545 | |
mbed_official | 1:d4bb1e33950e | 546 | /* non-scannable and non-connectable advertising |
mbed_official | 1:d4bb1e33950e | 547 | * skips rx events saving on power consumption */ |
mbed_official | 1:d4bb1e33950e | 548 | if (advertising_params[_set_index].adv_type |
mbed_official | 1:d4bb1e33950e | 549 | == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { |
mbed_official | 1:d4bb1e33950e | 550 | printf("We created at least %d tx events\r\n", events); |
mbed_official | 1:d4bb1e33950e | 551 | } else { |
mbed_official | 1:d4bb1e33950e | 552 | printf("We created at least %d tx and rx events\r\n", events); |
mbed_official | 1:d4bb1e33950e | 553 | } |
mbed_official | 1:d4bb1e33950e | 554 | } |
mbed_official | 1:d4bb1e33950e | 555 | }; |
mbed_official | 1:d4bb1e33950e | 556 | |
mbed_official | 1:d4bb1e33950e | 557 | /** Schedule processing of events from the BLE middleware in the event queue. */ |
mbed_official | 1:d4bb1e33950e | 558 | void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) |
mbed_official | 1:d4bb1e33950e | 559 | { |
mbed_official | 1:d4bb1e33950e | 560 | _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); |
mbed_official | 1:d4bb1e33950e | 561 | }; |
mbed_official | 1:d4bb1e33950e | 562 | |
mbed_official | 1:d4bb1e33950e | 563 | /** Blink LED to show we're running */ |
mbed_official | 1:d4bb1e33950e | 564 | void blink(void) |
mbed_official | 1:d4bb1e33950e | 565 | { |
mbed_official | 1:d4bb1e33950e | 566 | _led1 = !_led1; |
mbed_official | 1:d4bb1e33950e | 567 | }; |
mbed_official | 1:d4bb1e33950e | 568 | |
mbed_official | 1:d4bb1e33950e | 569 | private: |
mbed_official | 1:d4bb1e33950e | 570 | BLE &_ble; |
mbed_official | 1:d4bb1e33950e | 571 | events::EventQueue _event_queue; |
mbed_official | 1:d4bb1e33950e | 572 | DigitalOut _led1; |
mbed_official | 1:d4bb1e33950e | 573 | |
mbed_official | 1:d4bb1e33950e | 574 | /* Keep track of our progress through demo modes */ |
mbed_official | 1:d4bb1e33950e | 575 | size_t _set_index; |
mbed_official | 1:d4bb1e33950e | 576 | bool _is_in_scanning_mode; |
mbed_official | 1:d4bb1e33950e | 577 | bool _is_connecting; |
mbed_official | 1:d4bb1e33950e | 578 | |
mbed_official | 1:d4bb1e33950e | 579 | /* Remember the call id of the function on _event_queue |
mbed_official | 1:d4bb1e33950e | 580 | * so we can cancel it if we need to end the mode early */ |
mbed_official | 1:d4bb1e33950e | 581 | int _on_duration_end_id; |
mbed_official | 1:d4bb1e33950e | 582 | |
mbed_official | 1:d4bb1e33950e | 583 | /* Measure performance of our advertising/scanning */ |
mbed_official | 1:d4bb1e33950e | 584 | Timer _demo_duration; |
mbed_official | 1:d4bb1e33950e | 585 | size_t _scan_count; |
mbed_official | 1:d4bb1e33950e | 586 | }; |
mbed_official | 1:d4bb1e33950e | 587 | |
mbed_official | 1:d4bb1e33950e | 588 | int main() |
mbed_official | 1:d4bb1e33950e | 589 | { |
mbed_official | 1:d4bb1e33950e | 590 | GAPDevice gap_device; |
mbed_official | 1:d4bb1e33950e | 591 | |
mbed_official | 1:d4bb1e33950e | 592 | while (1) { |
mbed_official | 1:d4bb1e33950e | 593 | gap_device.run(); |
mbed_official | 1:d4bb1e33950e | 594 | wait_ms(TIME_BETWEEN_MODES_MS); |
mbed_official | 1:d4bb1e33950e | 595 | printf("\r\nStarting next GAP demo mode\r\n"); |
mbed_official | 1:d4bb1e33950e | 596 | }; |
mbed_official | 1:d4bb1e33950e | 597 | |
mbed_official | 1:d4bb1e33950e | 598 | return 0; |
mbed_official | 1:d4bb1e33950e | 599 | } |