test

Committer:
krissl
Date:
Sat Apr 20 12:37:54 2019 +0000
Revision:
23:3c342cffd585
Parent:
17:6bf7972c4d0e
test;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Donatien Garnier 1:916188eae2bb 1 /* mbed Microcontroller Library
Donatien Garnier 1:916188eae2bb 2 * Copyright (c) 2006-2013 ARM Limited
Donatien Garnier 1:916188eae2bb 3 *
Donatien Garnier 1:916188eae2bb 4 * Licensed under the Apache License, Version 2.0 (the "License");
Donatien Garnier 1:916188eae2bb 5 * you may not use this file except in compliance with the License.
Donatien Garnier 1:916188eae2bb 6 * You may obtain a copy of the License at
Donatien Garnier 1:916188eae2bb 7 *
Donatien Garnier 1:916188eae2bb 8 * http://www.apache.org/licenses/LICENSE-2.0
Donatien Garnier 1:916188eae2bb 9 *
Donatien Garnier 1:916188eae2bb 10 * Unless required by applicable law or agreed to in writing, software
Donatien Garnier 1:916188eae2bb 11 * distributed under the License is distributed on an "AS IS" BASIS,
Donatien Garnier 1:916188eae2bb 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Donatien Garnier 1:916188eae2bb 13 * See the License for the specific language governing permissions and
Donatien Garnier 1:916188eae2bb 14 * limitations under the License.
Donatien Garnier 1:916188eae2bb 15 */
Donatien Garnier 1:916188eae2bb 16
Donatien Garnier 1:916188eae2bb 17 #include <events/mbed_events.h>
Donatien Garnier 1:916188eae2bb 18 #include <mbed.h>
Donatien Garnier 1:916188eae2bb 19 #include "ble/BLE.h"
Donatien Garnier 1:916188eae2bb 20 #include "SecurityManager.h"
mbed_official 17:6bf7972c4d0e 21 #include "pretty_printer.h"
Donatien Garnier 1:916188eae2bb 22
mbed_official 9:674ab70e0f36 23 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 24 #include "LittleFileSystem.h"
mbed_official 9:674ab70e0f36 25 #include "HeapBlockDevice.h"
mbed_official 9:674ab70e0f36 26 #endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 27
Donatien Garnier 1:916188eae2bb 28 /** This example demonstrates all the basic setup required
Donatien Garnier 1:916188eae2bb 29 * for pairing and setting up link security both as a central and peripheral
Donatien Garnier 1:916188eae2bb 30 *
Donatien Garnier 1:916188eae2bb 31 * The example is implemented as two classes, one for the peripheral and one
Donatien Garnier 1:916188eae2bb 32 * for central inheriting from a common base. They are run in sequence and
Donatien Garnier 1:916188eae2bb 33 * require a peer device to connect to. During the peripheral device demonstration
Donatien Garnier 1:916188eae2bb 34 * a peer device is required to connect. In the central device demonstration
Donatien Garnier 1:916188eae2bb 35 * this peer device will be scanned for and connected to - therefore it should
Donatien Garnier 1:916188eae2bb 36 * be advertising with the same address as when it connected.
Donatien Garnier 1:916188eae2bb 37 *
Donatien Garnier 1:916188eae2bb 38 * During the test output is written on the serial connection to monitor its
Donatien Garnier 1:916188eae2bb 39 * progress.
Donatien Garnier 1:916188eae2bb 40 */
Donatien Garnier 1:916188eae2bb 41
mbed_official 17:6bf7972c4d0e 42 static const char DEVICE_NAME[] = "SM_device";
mbed_official 17:6bf7972c4d0e 43
mbed_official 17:6bf7972c4d0e 44 /* we have to specify the disconnect call because of ambiguous overloads */
mbed_official 17:6bf7972c4d0e 45 typedef ble_error_t (Gap::*disconnect_call_t)(ble::connection_handle_t, ble::local_disconnection_reason_t);
mbed_official 17:6bf7972c4d0e 46 const static disconnect_call_t disconnect_call = &Gap::disconnect;
Donatien Garnier 1:916188eae2bb 47
Donatien Garnier 1:916188eae2bb 48 /* for demonstration purposes we will store the peer device address
Donatien Garnier 1:916188eae2bb 49 * of the device that connects to us in the first demonstration
Donatien Garnier 1:916188eae2bb 50 * so we can use its address to reconnect to it later */
Donatien Garnier 1:916188eae2bb 51 static BLEProtocol::AddressBytes_t peer_address;
Donatien Garnier 1:916188eae2bb 52
Donatien Garnier 1:916188eae2bb 53 /** Base class for both peripheral and central. The same class that provides
Donatien Garnier 1:916188eae2bb 54 * the logic for the application also implements the SecurityManagerEventHandler
Donatien Garnier 1:916188eae2bb 55 * which is the interface used by the Security Manager to communicate events
Donatien Garnier 1:916188eae2bb 56 * back to the applications. You can provide overrides for a selection of events
Donatien Garnier 1:916188eae2bb 57 * your application is interested in.
Donatien Garnier 1:916188eae2bb 58 */
Donatien Garnier 1:916188eae2bb 59 class SMDevice : private mbed::NonCopyable<SMDevice>,
mbed_official 17:6bf7972c4d0e 60 public SecurityManager::EventHandler,
mbed_official 17:6bf7972c4d0e 61 public ble::Gap::EventHandler
Donatien Garnier 1:916188eae2bb 62 {
Donatien Garnier 1:916188eae2bb 63 public:
Donatien Garnier 1:916188eae2bb 64 SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) :
Donatien Garnier 1:916188eae2bb 65 _led1(LED1, 0),
Donatien Garnier 1:916188eae2bb 66 _ble(ble),
Donatien Garnier 1:916188eae2bb 67 _event_queue(event_queue),
Donatien Garnier 1:916188eae2bb 68 _peer_address(peer_address),
Donatien Garnier 1:916188eae2bb 69 _handle(0),
Donatien Garnier 1:916188eae2bb 70 _is_connecting(false) { };
Donatien Garnier 1:916188eae2bb 71
Donatien Garnier 1:916188eae2bb 72 virtual ~SMDevice()
Donatien Garnier 1:916188eae2bb 73 {
Donatien Garnier 1:916188eae2bb 74 if (_ble.hasInitialized()) {
Donatien Garnier 1:916188eae2bb 75 _ble.shutdown();
Donatien Garnier 1:916188eae2bb 76 }
Donatien Garnier 1:916188eae2bb 77 };
Donatien Garnier 1:916188eae2bb 78
Donatien Garnier 1:916188eae2bb 79 /** Start BLE interface initialisation */
Donatien Garnier 1:916188eae2bb 80 void run()
Donatien Garnier 1:916188eae2bb 81 {
Donatien Garnier 1:916188eae2bb 82 ble_error_t error;
Donatien Garnier 1:916188eae2bb 83
Donatien Garnier 1:916188eae2bb 84 /* to show we're running we'll blink every 500ms */
Donatien Garnier 1:916188eae2bb 85 _event_queue.call_every(500, this, &SMDevice::blink);
Donatien Garnier 1:916188eae2bb 86
Donatien Garnier 1:916188eae2bb 87 if (_ble.hasInitialized()) {
Donatien Garnier 1:916188eae2bb 88 printf("Ble instance already initialised.\r\n");
Donatien Garnier 1:916188eae2bb 89 return;
Donatien Garnier 1:916188eae2bb 90 }
Donatien Garnier 1:916188eae2bb 91
Donatien Garnier 1:916188eae2bb 92 /* this will inform us off all events so we can schedule their handling
Donatien Garnier 1:916188eae2bb 93 * using our event queue */
Donatien Garnier 1:916188eae2bb 94 _ble.onEventsToProcess(
Donatien Garnier 1:916188eae2bb 95 makeFunctionPointer(this, &SMDevice::schedule_ble_events)
Donatien Garnier 1:916188eae2bb 96 );
Donatien Garnier 1:916188eae2bb 97
mbed_official 17:6bf7972c4d0e 98 /* handle gap events */
mbed_official 17:6bf7972c4d0e 99 _ble.gap().setEventHandler(this);
Donatien Garnier 1:916188eae2bb 100
Donatien Garnier 1:916188eae2bb 101 error = _ble.init(this, &SMDevice::on_init_complete);
Donatien Garnier 1:916188eae2bb 102
Donatien Garnier 1:916188eae2bb 103 if (error) {
Donatien Garnier 1:916188eae2bb 104 printf("Error returned by BLE::init.\r\n");
Donatien Garnier 1:916188eae2bb 105 return;
Donatien Garnier 1:916188eae2bb 106 }
Donatien Garnier 1:916188eae2bb 107
Donatien Garnier 1:916188eae2bb 108 /* this will not return until shutdown */
Donatien Garnier 1:916188eae2bb 109 _event_queue.dispatch_forever();
Donatien Garnier 1:916188eae2bb 110 };
Donatien Garnier 1:916188eae2bb 111
Donatien Garnier 1:916188eae2bb 112 private:
Donatien Garnier 1:916188eae2bb 113 /** Override to start chosen activity when initialisation completes */
Donatien Garnier 1:916188eae2bb 114 virtual void start() = 0;
Donatien Garnier 1:916188eae2bb 115
Donatien Garnier 1:916188eae2bb 116 /** This is called when BLE interface is initialised and starts the demonstration */
Donatien Garnier 1:916188eae2bb 117 void on_init_complete(BLE::InitializationCompleteCallbackContext *event)
Donatien Garnier 1:916188eae2bb 118 {
Donatien Garnier 1:916188eae2bb 119 ble_error_t error;
Donatien Garnier 1:916188eae2bb 120
Donatien Garnier 1:916188eae2bb 121 if (event->error) {
Donatien Garnier 1:916188eae2bb 122 printf("Error during the initialisation\r\n");
Donatien Garnier 1:916188eae2bb 123 return;
Donatien Garnier 1:916188eae2bb 124 }
Donatien Garnier 1:916188eae2bb 125
mbed_official 9:674ab70e0f36 126 /* This path will be used to store bonding information but will fallback
mbed_official 9:674ab70e0f36 127 * to storing in memory if file access fails (for example due to lack of a filesystem) */
mbed_official 9:674ab70e0f36 128 const char* db_path = "/fs/bt_sec_db";
Donatien Garnier 1:916188eae2bb 129 /* If the security manager is required this needs to be called before any
Donatien Garnier 1:916188eae2bb 130 * calls to the Security manager happen. */
mbed_official 9:674ab70e0f36 131 error = _ble.securityManager().init(
mbed_official 9:674ab70e0f36 132 true,
mbed_official 9:674ab70e0f36 133 false,
mbed_official 9:674ab70e0f36 134 SecurityManager::IO_CAPS_NONE,
mbed_official 9:674ab70e0f36 135 NULL,
mbed_official 9:674ab70e0f36 136 false,
mbed_official 9:674ab70e0f36 137 db_path
mbed_official 9:674ab70e0f36 138 );
Donatien Garnier 1:916188eae2bb 139
Donatien Garnier 1:916188eae2bb 140 if (error) {
Donatien Garnier 1:916188eae2bb 141 printf("Error during init %d\r\n", error);
Donatien Garnier 1:916188eae2bb 142 return;
Donatien Garnier 1:916188eae2bb 143 }
Donatien Garnier 1:916188eae2bb 144
mbed_official 9:674ab70e0f36 145 error = _ble.securityManager().preserveBondingStateOnReset(true);
mbed_official 9:674ab70e0f36 146
mbed_official 9:674ab70e0f36 147 if (error) {
mbed_official 9:674ab70e0f36 148 printf("Error during preserveBondingStateOnReset %d\r\n", error);
mbed_official 9:674ab70e0f36 149 }
mbed_official 9:674ab70e0f36 150
mbed_official 9:674ab70e0f36 151 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 152 /* Enable privacy so we can find the keys */
mbed_official 9:674ab70e0f36 153 error = _ble.gap().enablePrivacy(true);
mbed_official 9:674ab70e0f36 154
mbed_official 9:674ab70e0f36 155 if (error) {
mbed_official 9:674ab70e0f36 156 printf("Error enabling privacy\r\n");
mbed_official 9:674ab70e0f36 157 }
mbed_official 9:674ab70e0f36 158
mbed_official 9:674ab70e0f36 159 Gap::PeripheralPrivacyConfiguration_t configuration_p = {
mbed_official 9:674ab70e0f36 160 /* use_non_resolvable_random_address */ false,
mbed_official 9:674ab70e0f36 161 Gap::PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS
mbed_official 9:674ab70e0f36 162 };
mbed_official 9:674ab70e0f36 163 _ble.gap().setPeripheralPrivacyConfiguration(&configuration_p);
mbed_official 9:674ab70e0f36 164
mbed_official 9:674ab70e0f36 165 Gap::CentralPrivacyConfiguration_t configuration_c = {
mbed_official 9:674ab70e0f36 166 /* use_non_resolvable_random_address */ false,
mbed_official 9:674ab70e0f36 167 Gap::CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD
mbed_official 9:674ab70e0f36 168 };
mbed_official 9:674ab70e0f36 169 _ble.gap().setCentralPrivacyConfiguration(&configuration_c);
mbed_official 9:674ab70e0f36 170
mbed_official 9:674ab70e0f36 171 /* this demo switches between being master and slave */
mbed_official 9:674ab70e0f36 172 _ble.securityManager().setHintFutureRoleReversal(true);
mbed_official 9:674ab70e0f36 173 #endif
mbed_official 9:674ab70e0f36 174
Donatien Garnier 1:916188eae2bb 175 /* Tell the security manager to use methods in this class to inform us
Donatien Garnier 1:916188eae2bb 176 * of any events. Class needs to implement SecurityManagerEventHandler. */
Donatien Garnier 1:916188eae2bb 177 _ble.securityManager().setSecurityManagerEventHandler(this);
Donatien Garnier 1:916188eae2bb 178
mbed_official 17:6bf7972c4d0e 179 /* gap events also handled by this class */
mbed_official 17:6bf7972c4d0e 180 _ble.gap().setEventHandler(this);
mbed_official 17:6bf7972c4d0e 181
Donatien Garnier 1:916188eae2bb 182 /* print device address */
Donatien Garnier 1:916188eae2bb 183 Gap::AddressType_t addr_type;
Donatien Garnier 1:916188eae2bb 184 Gap::Address_t addr;
Donatien Garnier 1:916188eae2bb 185 _ble.gap().getAddress(&addr_type, addr);
mbed_official 17:6bf7972c4d0e 186 print_address(addr);
Donatien Garnier 1:916188eae2bb 187
Donatien Garnier 1:916188eae2bb 188 /* start test in 500 ms */
Donatien Garnier 1:916188eae2bb 189 _event_queue.call_in(500, this, &SMDevice::start);
Donatien Garnier 1:916188eae2bb 190 };
Donatien Garnier 1:916188eae2bb 191
Donatien Garnier 1:916188eae2bb 192 /** Schedule processing of events from the BLE in the event queue. */
Donatien Garnier 1:916188eae2bb 193 void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context)
Donatien Garnier 1:916188eae2bb 194 {
Donatien Garnier 1:916188eae2bb 195 _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents));
Donatien Garnier 1:916188eae2bb 196 };
Donatien Garnier 1:916188eae2bb 197
Donatien Garnier 1:916188eae2bb 198 /** Blink LED to show we're running */
Donatien Garnier 1:916188eae2bb 199 void blink(void)
Donatien Garnier 1:916188eae2bb 200 {
Donatien Garnier 1:916188eae2bb 201 _led1 = !_led1;
Donatien Garnier 1:916188eae2bb 202 };
Donatien Garnier 1:916188eae2bb 203
Donatien Garnier 1:916188eae2bb 204 private:
mbed_official 17:6bf7972c4d0e 205 /* Event handler */
mbed_official 17:6bf7972c4d0e 206
mbed_official 17:6bf7972c4d0e 207 /** Respond to a pairing request. This will be called by the stack
mbed_official 17:6bf7972c4d0e 208 * when a pairing request arrives and expects the application to
mbed_official 17:6bf7972c4d0e 209 * call acceptPairingRequest or cancelPairingRequest */
mbed_official 17:6bf7972c4d0e 210 virtual void pairingRequest(
mbed_official 17:6bf7972c4d0e 211 ble::connection_handle_t connectionHandle
mbed_official 17:6bf7972c4d0e 212 ) {
mbed_official 17:6bf7972c4d0e 213 printf("Pairing requested - authorising\r\n");
mbed_official 17:6bf7972c4d0e 214 _ble.securityManager().acceptPairingRequest(connectionHandle);
mbed_official 17:6bf7972c4d0e 215 }
mbed_official 17:6bf7972c4d0e 216
mbed_official 17:6bf7972c4d0e 217 /** Inform the application of a successful pairing. Terminate the demonstration. */
mbed_official 17:6bf7972c4d0e 218 virtual void pairingResult(
mbed_official 17:6bf7972c4d0e 219 ble::connection_handle_t connectionHandle,
mbed_official 17:6bf7972c4d0e 220 SecurityManager::SecurityCompletionStatus_t result
mbed_official 17:6bf7972c4d0e 221 ) {
mbed_official 17:6bf7972c4d0e 222 if (result == SecurityManager::SEC_STATUS_SUCCESS) {
mbed_official 17:6bf7972c4d0e 223 printf("Pairing successful\r\n");
mbed_official 17:6bf7972c4d0e 224 } else {
mbed_official 17:6bf7972c4d0e 225 printf("Pairing failed\r\n");
mbed_official 17:6bf7972c4d0e 226 }
mbed_official 17:6bf7972c4d0e 227 }
mbed_official 17:6bf7972c4d0e 228
mbed_official 17:6bf7972c4d0e 229 /** Inform the application of change in encryption status. This will be
mbed_official 17:6bf7972c4d0e 230 * communicated through the serial port */
mbed_official 17:6bf7972c4d0e 231 virtual void linkEncryptionResult(
mbed_official 17:6bf7972c4d0e 232 ble::connection_handle_t connectionHandle,
mbed_official 17:6bf7972c4d0e 233 ble::link_encryption_t result
mbed_official 17:6bf7972c4d0e 234 ) {
mbed_official 17:6bf7972c4d0e 235 if (result == ble::link_encryption_t::ENCRYPTED) {
mbed_official 17:6bf7972c4d0e 236 printf("Link ENCRYPTED\r\n");
mbed_official 17:6bf7972c4d0e 237 } else if (result == ble::link_encryption_t::ENCRYPTED_WITH_MITM) {
mbed_official 17:6bf7972c4d0e 238 printf("Link ENCRYPTED_WITH_MITM\r\n");
mbed_official 17:6bf7972c4d0e 239 } else if (result == ble::link_encryption_t::NOT_ENCRYPTED) {
mbed_official 17:6bf7972c4d0e 240 printf("Link NOT_ENCRYPTED\r\n");
mbed_official 17:6bf7972c4d0e 241 }
mbed_official 17:6bf7972c4d0e 242
mbed_official 17:6bf7972c4d0e 243 /* disconnect in 2 s */
mbed_official 17:6bf7972c4d0e 244 _event_queue.call_in(
mbed_official 17:6bf7972c4d0e 245 2000,
mbed_official 17:6bf7972c4d0e 246 &_ble.gap(),
mbed_official 17:6bf7972c4d0e 247 disconnect_call,
mbed_official 17:6bf7972c4d0e 248 _handle,
mbed_official 17:6bf7972c4d0e 249 ble::local_disconnection_reason_t(ble::local_disconnection_reason_t::USER_TERMINATION)
mbed_official 17:6bf7972c4d0e 250 );
mbed_official 17:6bf7972c4d0e 251 }
mbed_official 17:6bf7972c4d0e 252
mbed_official 17:6bf7972c4d0e 253 /** This is called by Gap to notify the application we disconnected,
mbed_official 17:6bf7972c4d0e 254 * in our case it ends the demonstration. */
mbed_official 17:6bf7972c4d0e 255 virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &)
mbed_official 17:6bf7972c4d0e 256 {
mbed_official 17:6bf7972c4d0e 257 printf("Diconnected\r\n");
mbed_official 17:6bf7972c4d0e 258 _event_queue.break_dispatch();
mbed_official 17:6bf7972c4d0e 259 };
mbed_official 17:6bf7972c4d0e 260
mbed_official 17:6bf7972c4d0e 261 virtual void onAdvertisingEnd(const ble::AdvertisingEndEvent &)
mbed_official 17:6bf7972c4d0e 262 {
mbed_official 17:6bf7972c4d0e 263 printf("Advertising timed out - aborting\r\n");
mbed_official 17:6bf7972c4d0e 264 _event_queue.break_dispatch();
mbed_official 17:6bf7972c4d0e 265 }
mbed_official 17:6bf7972c4d0e 266
mbed_official 17:6bf7972c4d0e 267 virtual void onScanTimeout(const ble::ScanTimeoutEvent &)
mbed_official 17:6bf7972c4d0e 268 {
mbed_official 17:6bf7972c4d0e 269 printf("Scan timed out - aborting\r\n");
mbed_official 17:6bf7972c4d0e 270 _event_queue.break_dispatch();
mbed_official 17:6bf7972c4d0e 271 }
mbed_official 17:6bf7972c4d0e 272
mbed_official 17:6bf7972c4d0e 273 private:
Donatien Garnier 1:916188eae2bb 274 DigitalOut _led1;
Donatien Garnier 1:916188eae2bb 275
Donatien Garnier 1:916188eae2bb 276 protected:
Donatien Garnier 1:916188eae2bb 277 BLE &_ble;
Donatien Garnier 1:916188eae2bb 278 events::EventQueue &_event_queue;
Donatien Garnier 1:916188eae2bb 279 BLEProtocol::AddressBytes_t &_peer_address;
Donatien Garnier 1:916188eae2bb 280 ble::connection_handle_t _handle;
Donatien Garnier 1:916188eae2bb 281 bool _is_connecting;
Donatien Garnier 1:916188eae2bb 282 };
Donatien Garnier 1:916188eae2bb 283
Donatien Garnier 1:916188eae2bb 284 /** A peripheral device will advertise, accept the connection and request
Donatien Garnier 1:916188eae2bb 285 * a change in link security. */
Donatien Garnier 1:916188eae2bb 286 class SMDevicePeripheral : public SMDevice {
Donatien Garnier 1:916188eae2bb 287 public:
Donatien Garnier 1:916188eae2bb 288 SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address)
Donatien Garnier 1:916188eae2bb 289 : SMDevice(ble, event_queue, peer_address) { }
Donatien Garnier 1:916188eae2bb 290
Donatien Garnier 1:916188eae2bb 291 virtual void start()
Donatien Garnier 1:916188eae2bb 292 {
Donatien Garnier 1:916188eae2bb 293 /* Set up and start advertising */
mbed_official 17:6bf7972c4d0e 294 uint8_t adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
mbed_official 17:6bf7972c4d0e 295 /* use the helper to build the payload */
mbed_official 17:6bf7972c4d0e 296 ble::AdvertisingDataBuilder adv_data_builder(
mbed_official 17:6bf7972c4d0e 297 adv_buffer
Donatien Garnier 1:916188eae2bb 298 );
Donatien Garnier 1:916188eae2bb 299
mbed_official 17:6bf7972c4d0e 300 adv_data_builder.setFlags();
mbed_official 17:6bf7972c4d0e 301 adv_data_builder.setName(DEVICE_NAME);
mbed_official 17:6bf7972c4d0e 302
mbed_official 17:6bf7972c4d0e 303 /* Set payload for the set */
mbed_official 17:6bf7972c4d0e 304 ble_error_t error = _ble.gap().setAdvertisingPayload(
mbed_official 17:6bf7972c4d0e 305 ble::LEGACY_ADVERTISING_HANDLE,
mbed_official 17:6bf7972c4d0e 306 adv_data_builder.getAdvertisingData()
mbed_official 17:6bf7972c4d0e 307 );
Donatien Garnier 1:916188eae2bb 308
Donatien Garnier 1:916188eae2bb 309 if (error) {
mbed_official 17:6bf7972c4d0e 310 print_error(error, "Gap::setAdvertisingPayload() failed");
mbed_official 17:6bf7972c4d0e 311 _event_queue.break_dispatch();
Donatien Garnier 1:916188eae2bb 312 return;
Donatien Garnier 1:916188eae2bb 313 }
Donatien Garnier 1:916188eae2bb 314
mbed_official 17:6bf7972c4d0e 315 ble::AdvertisingParameters adv_parameters(
mbed_official 17:6bf7972c4d0e 316 ble::advertising_type_t::CONNECTABLE_UNDIRECTED
mbed_official 17:6bf7972c4d0e 317 );
Donatien Garnier 1:916188eae2bb 318
mbed_official 17:6bf7972c4d0e 319 error = _ble.gap().setAdvertisingParameters(
mbed_official 17:6bf7972c4d0e 320 ble::LEGACY_ADVERTISING_HANDLE,
mbed_official 17:6bf7972c4d0e 321 adv_parameters
mbed_official 17:6bf7972c4d0e 322 );
Donatien Garnier 1:916188eae2bb 323
Donatien Garnier 1:916188eae2bb 324 if (error) {
mbed_official 17:6bf7972c4d0e 325 print_error(error, "Gap::setAdvertisingParameters() failed");
mbed_official 17:6bf7972c4d0e 326 return;
mbed_official 17:6bf7972c4d0e 327 }
mbed_official 17:6bf7972c4d0e 328
mbed_official 17:6bf7972c4d0e 329 error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
mbed_official 17:6bf7972c4d0e 330
mbed_official 17:6bf7972c4d0e 331 if (error) {
mbed_official 17:6bf7972c4d0e 332 print_error(error, "Gap::startAdvertising() failed");
Donatien Garnier 1:916188eae2bb 333 return;
Donatien Garnier 1:916188eae2bb 334 }
Donatien Garnier 1:916188eae2bb 335
mbed_official 9:674ab70e0f36 336 printf("Please connect to device\r\n");
mbed_official 9:674ab70e0f36 337
Donatien Garnier 1:916188eae2bb 338 /** This tells the stack to generate a pairingRequest event
Donatien Garnier 1:916188eae2bb 339 * which will require this application to respond before pairing
Donatien Garnier 1:916188eae2bb 340 * can proceed. Setting it to false will automatically accept
Donatien Garnier 1:916188eae2bb 341 * pairing. */
Donatien Garnier 1:916188eae2bb 342 _ble.securityManager().setPairingRequestAuthorisation(true);
Donatien Garnier 1:916188eae2bb 343 };
Donatien Garnier 1:916188eae2bb 344
Donatien Garnier 1:916188eae2bb 345 /** This is called by Gap to notify the application we connected,
Donatien Garnier 1:916188eae2bb 346 * in our case it immediately requests a change in link security */
mbed_official 17:6bf7972c4d0e 347 virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event)
Donatien Garnier 1:916188eae2bb 348 {
Donatien Garnier 1:916188eae2bb 349 ble_error_t error;
Donatien Garnier 1:916188eae2bb 350
Donatien Garnier 1:916188eae2bb 351 /* remember the device that connects to us now so we can connect to it
Donatien Garnier 1:916188eae2bb 352 * during the next demonstration */
mbed_official 17:6bf7972c4d0e 353 memcpy(_peer_address, event.getPeerAddress().data(), sizeof(_peer_address));
Donatien Garnier 1:916188eae2bb 354
mbed_official 17:6bf7972c4d0e 355 printf("Connected to peer: ");
mbed_official 17:6bf7972c4d0e 356 print_address(event.getPeerAddress().data());
mbed_official 9:674ab70e0f36 357
mbed_official 17:6bf7972c4d0e 358 _handle = event.getConnectionHandle();
Donatien Garnier 1:916188eae2bb 359
Donatien Garnier 1:916188eae2bb 360 /* Request a change in link security. This will be done
Donatien Garnier 1:916188eae2bb 361 * indirectly by asking the master of the connection to
Donatien Garnier 1:916188eae2bb 362 * change it. Depending on circumstances different actions
Donatien Garnier 1:916188eae2bb 363 * may be taken by the master which will trigger events
Donatien Garnier 1:916188eae2bb 364 * which the applications should deal with. */
Donatien Garnier 1:916188eae2bb 365 error = _ble.securityManager().setLinkSecurity(
Donatien Garnier 1:916188eae2bb 366 _handle,
Donatien Garnier 1:916188eae2bb 367 SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM
Donatien Garnier 1:916188eae2bb 368 );
Donatien Garnier 1:916188eae2bb 369
Donatien Garnier 1:916188eae2bb 370 if (error) {
Donatien Garnier 1:916188eae2bb 371 printf("Error during SM::setLinkSecurity %d\r\n", error);
Donatien Garnier 1:916188eae2bb 372 return;
Donatien Garnier 1:916188eae2bb 373 }
Donatien Garnier 1:916188eae2bb 374 };
Donatien Garnier 1:916188eae2bb 375 };
Donatien Garnier 1:916188eae2bb 376
Donatien Garnier 1:916188eae2bb 377 /** A central device will scan, connect to a peer and request pairing. */
Donatien Garnier 1:916188eae2bb 378 class SMDeviceCentral : public SMDevice {
Donatien Garnier 1:916188eae2bb 379 public:
Donatien Garnier 1:916188eae2bb 380 SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address)
Donatien Garnier 1:916188eae2bb 381 : SMDevice(ble, event_queue, peer_address) { }
Donatien Garnier 1:916188eae2bb 382
Donatien Garnier 1:916188eae2bb 383 virtual void start()
Donatien Garnier 1:916188eae2bb 384 {
mbed_official 17:6bf7972c4d0e 385 ble::ScanParameters params;
mbed_official 17:6bf7972c4d0e 386 ble_error_t error = _ble.gap().setScanParameters(params);
mbed_official 17:6bf7972c4d0e 387
mbed_official 17:6bf7972c4d0e 388 if (error) {
mbed_official 17:6bf7972c4d0e 389 print_error(error, "Error in Gap::startScan %d\r\n");
mbed_official 17:6bf7972c4d0e 390 return;
mbed_official 17:6bf7972c4d0e 391 }
mbed_official 17:6bf7972c4d0e 392
mbed_official 17:6bf7972c4d0e 393 /* start scanning, results will be handled by onAdvertisingReport */
mbed_official 17:6bf7972c4d0e 394 error = _ble.gap().startScan();
mbed_official 17:6bf7972c4d0e 395
mbed_official 17:6bf7972c4d0e 396 if (error) {
mbed_official 17:6bf7972c4d0e 397 print_error(error, "Error in Gap::startScan %d\r\n");
mbed_official 17:6bf7972c4d0e 398 return;
mbed_official 17:6bf7972c4d0e 399 }
Donatien Garnier 1:916188eae2bb 400
mbed_official 9:674ab70e0f36 401 printf("Please advertise\r\n");
mbed_official 9:674ab70e0f36 402
mbed_official 17:6bf7972c4d0e 403 printf("Scanning for: ");
mbed_official 17:6bf7972c4d0e 404 print_address(_peer_address);
Donatien Garnier 1:916188eae2bb 405 }
Donatien Garnier 1:916188eae2bb 406
mbed_official 17:6bf7972c4d0e 407 private:
mbed_official 17:6bf7972c4d0e 408 /* Gap::EventHandler */
mbed_official 17:6bf7972c4d0e 409
Donatien Garnier 1:916188eae2bb 410 /** Look at scan payload to find a peer device and connect to it */
mbed_official 17:6bf7972c4d0e 411 virtual void onAdvertisingReport(const ble::AdvertisingReportEvent &event)
Donatien Garnier 1:916188eae2bb 412 {
Donatien Garnier 1:916188eae2bb 413 /* don't bother with analysing scan result if we're already connecting */
Donatien Garnier 1:916188eae2bb 414 if (_is_connecting) {
Donatien Garnier 1:916188eae2bb 415 return;
Donatien Garnier 1:916188eae2bb 416 }
krissl 23:3c342cffd585 417 printf("found someone ");
krissl 23:3c342cffd585 418 printf("%02x:%02x:%02x:%02x:%02x:%02x\r\n",
krissl 23:3c342cffd585 419 event.getPeerAddress().data()[5], event.getPeerAddress().data()[4], event.getPeerAddress().data()[3], event.getPeerAddress().data()[2], event.getPeerAddress().data()[1], event.getPeerAddress().data()[0]);
mbed_official 17:6bf7972c4d0e 420 /* parse the advertising payload, looking for a discoverable device */
mbed_official 17:6bf7972c4d0e 421 if (memcmp(event.getPeerAddress().data(), _peer_address, sizeof(_peer_address)) == 0) {
mbed_official 17:6bf7972c4d0e 422 ble_error_t error = _ble.gap().stopScan();
mbed_official 17:6bf7972c4d0e 423
mbed_official 17:6bf7972c4d0e 424 if (error) {
mbed_official 17:6bf7972c4d0e 425 print_error(error, "Error caused by Gap::stopScan");
mbed_official 17:6bf7972c4d0e 426 return;
mbed_official 17:6bf7972c4d0e 427 }
Donatien Garnier 1:916188eae2bb 428
mbed_official 17:6bf7972c4d0e 429 ble::ConnectionParameters connection_params(
mbed_official 17:6bf7972c4d0e 430 ble::phy_t::LE_1M,
mbed_official 17:6bf7972c4d0e 431 ble::scan_interval_t(50),
mbed_official 17:6bf7972c4d0e 432 ble::scan_window_t(50),
mbed_official 17:6bf7972c4d0e 433 ble::conn_interval_t(50),
mbed_official 17:6bf7972c4d0e 434 ble::conn_interval_t(100),
mbed_official 17:6bf7972c4d0e 435 ble::slave_latency_t(0),
mbed_official 17:6bf7972c4d0e 436 ble::supervision_timeout_t(100)
mbed_official 17:6bf7972c4d0e 437 );
mbed_official 17:6bf7972c4d0e 438 connection_params.setOwnAddressType(ble::own_address_type_t::RANDOM);
mbed_official 17:6bf7972c4d0e 439
mbed_official 17:6bf7972c4d0e 440 error = _ble.gap().connect(
mbed_official 17:6bf7972c4d0e 441 event.getPeerAddressType(),
mbed_official 17:6bf7972c4d0e 442 event.getPeerAddress(),
mbed_official 17:6bf7972c4d0e 443 connection_params
mbed_official 9:674ab70e0f36 444 );
Donatien Garnier 1:916188eae2bb 445
mbed_official 9:674ab70e0f36 446 if (error) {
mbed_official 17:6bf7972c4d0e 447 print_error(error, "Error caused by Gap::connect");
Donatien Garnier 1:916188eae2bb 448 return;
Donatien Garnier 1:916188eae2bb 449 }
Donatien Garnier 1:916188eae2bb 450
mbed_official 9:674ab70e0f36 451 /* we may have already scan events waiting
mbed_official 9:674ab70e0f36 452 * to be processed so we need to remember
mbed_official 9:674ab70e0f36 453 * that we are already connecting and ignore them */
mbed_official 9:674ab70e0f36 454 _is_connecting = true;
mbed_official 9:674ab70e0f36 455
mbed_official 9:674ab70e0f36 456 return;
Donatien Garnier 1:916188eae2bb 457 }
mbed_official 17:6bf7972c4d0e 458 }
Donatien Garnier 1:916188eae2bb 459
Donatien Garnier 1:916188eae2bb 460 /** This is called by Gap to notify the application we connected,
Donatien Garnier 1:916188eae2bb 461 * in our case it immediately request pairing */
mbed_official 17:6bf7972c4d0e 462 virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event)
Donatien Garnier 1:916188eae2bb 463 {
mbed_official 17:6bf7972c4d0e 464 if (event.getStatus() == BLE_ERROR_NONE) {
mbed_official 17:6bf7972c4d0e 465 /* store the handle for future Security Manager requests */
mbed_official 17:6bf7972c4d0e 466 _handle = event.getConnectionHandle();
mbed_official 17:6bf7972c4d0e 467
mbed_official 17:6bf7972c4d0e 468 printf("Connected\r\n");
mbed_official 17:6bf7972c4d0e 469
mbed_official 17:6bf7972c4d0e 470 /* in this example the local device is the master so we request pairing */
mbed_official 17:6bf7972c4d0e 471 ble_error_t error = _ble.securityManager().requestPairing(_handle);
Donatien Garnier 1:916188eae2bb 472
mbed_official 17:6bf7972c4d0e 473 if (error) {
mbed_official 17:6bf7972c4d0e 474 printf("Error during SM::requestPairing %d\r\n", error);
mbed_official 17:6bf7972c4d0e 475 return;
mbed_official 17:6bf7972c4d0e 476 }
Donatien Garnier 1:916188eae2bb 477
mbed_official 17:6bf7972c4d0e 478 /* upon pairing success the application will disconnect */
mbed_official 17:6bf7972c4d0e 479 }
Donatien Garnier 1:916188eae2bb 480
mbed_official 17:6bf7972c4d0e 481 /* failed to connect - restart scan */
mbed_official 17:6bf7972c4d0e 482 ble_error_t error = _ble.gap().startScan();
mbed_official 9:674ab70e0f36 483
Donatien Garnier 1:916188eae2bb 484 if (error) {
mbed_official 17:6bf7972c4d0e 485 print_error(error, "Error in Gap::startScan %d\r\n");
Donatien Garnier 1:916188eae2bb 486 return;
Donatien Garnier 1:916188eae2bb 487 }
Donatien Garnier 1:916188eae2bb 488 };
Donatien Garnier 1:916188eae2bb 489 };
Donatien Garnier 1:916188eae2bb 490
mbed_official 9:674ab70e0f36 491
mbed_official 9:674ab70e0f36 492 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 493 bool create_filesystem()
mbed_official 9:674ab70e0f36 494 {
mbed_official 9:674ab70e0f36 495 static LittleFileSystem fs("fs");
mbed_official 9:674ab70e0f36 496
mbed_official 9:674ab70e0f36 497 /* replace this with any physical block device your board supports (like an SD card) */
mbed_official 9:674ab70e0f36 498 static HeapBlockDevice bd(4096, 256);
mbed_official 9:674ab70e0f36 499
mbed_official 9:674ab70e0f36 500 int err = bd.init();
mbed_official 9:674ab70e0f36 501
mbed_official 9:674ab70e0f36 502 if (err) {
mbed_official 9:674ab70e0f36 503 return false;
mbed_official 9:674ab70e0f36 504 }
mbed_official 9:674ab70e0f36 505
mbed_official 9:674ab70e0f36 506 err = bd.erase(0, bd.size());
mbed_official 9:674ab70e0f36 507
mbed_official 9:674ab70e0f36 508 if (err) {
mbed_official 9:674ab70e0f36 509 return false;
mbed_official 9:674ab70e0f36 510 }
mbed_official 9:674ab70e0f36 511
mbed_official 9:674ab70e0f36 512 err = fs.mount(&bd);
mbed_official 9:674ab70e0f36 513
mbed_official 9:674ab70e0f36 514 if (err) {
mbed_official 9:674ab70e0f36 515 /* Reformat if we can't mount the filesystem */
mbed_official 9:674ab70e0f36 516 printf("No filesystem found, formatting...\r\n");
mbed_official 9:674ab70e0f36 517
mbed_official 9:674ab70e0f36 518 err = fs.reformat(&bd);
mbed_official 9:674ab70e0f36 519
mbed_official 9:674ab70e0f36 520 if (err) {
mbed_official 9:674ab70e0f36 521 return false;
mbed_official 9:674ab70e0f36 522 }
mbed_official 9:674ab70e0f36 523 }
mbed_official 9:674ab70e0f36 524
mbed_official 9:674ab70e0f36 525 return true;
mbed_official 9:674ab70e0f36 526 }
mbed_official 9:674ab70e0f36 527 #endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 528
Donatien Garnier 1:916188eae2bb 529 int main()
Donatien Garnier 1:916188eae2bb 530 {
Donatien Garnier 1:916188eae2bb 531 BLE& ble = BLE::Instance();
Donatien Garnier 1:916188eae2bb 532 events::EventQueue queue;
Donatien Garnier 1:916188eae2bb 533
mbed_official 9:674ab70e0f36 534 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 535 /* if filesystem creation fails or there is no filesystem the security manager
mbed_official 9:674ab70e0f36 536 * will fallback to storing the security database in memory */
mbed_official 9:674ab70e0f36 537 if (!create_filesystem()) {
mbed_official 9:674ab70e0f36 538 printf("Filesystem creation failed, will use memory storage\r\n");
Donatien Garnier 1:916188eae2bb 539 }
mbed_official 9:674ab70e0f36 540 #endif
Donatien Garnier 1:916188eae2bb 541
mbed_official 9:674ab70e0f36 542 while(1) {
krissl 23:3c342cffd585 543 // {
krissl 23:3c342cffd585 544 // printf("\r\n PERIPHERAL \r\n\r\n");
krissl 23:3c342cffd585 545 // SMDevicePeripheral peripheral(ble, queue, peer_address);
krissl 23:3c342cffd585 546 // peripheral.run();
krissl 23:3c342cffd585 547 // }
mbed_official 9:674ab70e0f36 548
mbed_official 9:674ab70e0f36 549 {
mbed_official 9:674ab70e0f36 550 printf("\r\n CENTRAL \r\n\r\n");
mbed_official 9:674ab70e0f36 551 SMDeviceCentral central(ble, queue, peer_address);
mbed_official 9:674ab70e0f36 552 central.run();
mbed_official 9:674ab70e0f36 553 }
Donatien Garnier 1:916188eae2bb 554 }
Donatien Garnier 1:916188eae2bb 555
Donatien Garnier 1:916188eae2bb 556 return 0;
Donatien Garnier 1:916188eae2bb 557 }