test

Committer:
mbed_official
Date:
Thu Aug 23 14:00:15 2018 +0100
Revision:
9:674ab70e0f36
Parent:
1:916188eae2bb
Child:
17:6bf7972c4d0e
Delete .project
.
Commit copied from https://github.com/ARMmbed/mbed-os-example-ble

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"
Donatien Garnier 1:916188eae2bb 21
mbed_official 9:674ab70e0f36 22 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 23 #include "LittleFileSystem.h"
mbed_official 9:674ab70e0f36 24 #include "HeapBlockDevice.h"
mbed_official 9:674ab70e0f36 25 #endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 26
Donatien Garnier 1:916188eae2bb 27 /** This example demonstrates all the basic setup required
Donatien Garnier 1:916188eae2bb 28 * for pairing and setting up link security both as a central and peripheral
Donatien Garnier 1:916188eae2bb 29 *
Donatien Garnier 1:916188eae2bb 30 * The example is implemented as two classes, one for the peripheral and one
Donatien Garnier 1:916188eae2bb 31 * for central inheriting from a common base. They are run in sequence and
Donatien Garnier 1:916188eae2bb 32 * require a peer device to connect to. During the peripheral device demonstration
Donatien Garnier 1:916188eae2bb 33 * a peer device is required to connect. In the central device demonstration
Donatien Garnier 1:916188eae2bb 34 * this peer device will be scanned for and connected to - therefore it should
Donatien Garnier 1:916188eae2bb 35 * be advertising with the same address as when it connected.
Donatien Garnier 1:916188eae2bb 36 *
Donatien Garnier 1:916188eae2bb 37 * During the test output is written on the serial connection to monitor its
Donatien Garnier 1:916188eae2bb 38 * progress.
Donatien Garnier 1:916188eae2bb 39 */
Donatien Garnier 1:916188eae2bb 40
Donatien Garnier 1:916188eae2bb 41 static const uint8_t DEVICE_NAME[] = "SM_device";
Donatien Garnier 1:916188eae2bb 42
Donatien Garnier 1:916188eae2bb 43 /* for demonstration purposes we will store the peer device address
Donatien Garnier 1:916188eae2bb 44 * of the device that connects to us in the first demonstration
Donatien Garnier 1:916188eae2bb 45 * so we can use its address to reconnect to it later */
Donatien Garnier 1:916188eae2bb 46 static BLEProtocol::AddressBytes_t peer_address;
Donatien Garnier 1:916188eae2bb 47
Donatien Garnier 1:916188eae2bb 48 /** Base class for both peripheral and central. The same class that provides
Donatien Garnier 1:916188eae2bb 49 * the logic for the application also implements the SecurityManagerEventHandler
Donatien Garnier 1:916188eae2bb 50 * which is the interface used by the Security Manager to communicate events
Donatien Garnier 1:916188eae2bb 51 * back to the applications. You can provide overrides for a selection of events
Donatien Garnier 1:916188eae2bb 52 * your application is interested in.
Donatien Garnier 1:916188eae2bb 53 */
Donatien Garnier 1:916188eae2bb 54 class SMDevice : private mbed::NonCopyable<SMDevice>,
Donatien Garnier 1:916188eae2bb 55 public SecurityManager::EventHandler
Donatien Garnier 1:916188eae2bb 56 {
Donatien Garnier 1:916188eae2bb 57 public:
Donatien Garnier 1:916188eae2bb 58 SMDevice(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address) :
Donatien Garnier 1:916188eae2bb 59 _led1(LED1, 0),
Donatien Garnier 1:916188eae2bb 60 _ble(ble),
Donatien Garnier 1:916188eae2bb 61 _event_queue(event_queue),
Donatien Garnier 1:916188eae2bb 62 _peer_address(peer_address),
Donatien Garnier 1:916188eae2bb 63 _handle(0),
Donatien Garnier 1:916188eae2bb 64 _is_connecting(false) { };
Donatien Garnier 1:916188eae2bb 65
Donatien Garnier 1:916188eae2bb 66 virtual ~SMDevice()
Donatien Garnier 1:916188eae2bb 67 {
Donatien Garnier 1:916188eae2bb 68 if (_ble.hasInitialized()) {
Donatien Garnier 1:916188eae2bb 69 _ble.shutdown();
Donatien Garnier 1:916188eae2bb 70 }
Donatien Garnier 1:916188eae2bb 71 };
Donatien Garnier 1:916188eae2bb 72
Donatien Garnier 1:916188eae2bb 73 /** Start BLE interface initialisation */
Donatien Garnier 1:916188eae2bb 74 void run()
Donatien Garnier 1:916188eae2bb 75 {
Donatien Garnier 1:916188eae2bb 76 ble_error_t error;
Donatien Garnier 1:916188eae2bb 77
Donatien Garnier 1:916188eae2bb 78 /* to show we're running we'll blink every 500ms */
Donatien Garnier 1:916188eae2bb 79 _event_queue.call_every(500, this, &SMDevice::blink);
Donatien Garnier 1:916188eae2bb 80
Donatien Garnier 1:916188eae2bb 81 if (_ble.hasInitialized()) {
Donatien Garnier 1:916188eae2bb 82 printf("Ble instance already initialised.\r\n");
Donatien Garnier 1:916188eae2bb 83 return;
Donatien Garnier 1:916188eae2bb 84 }
Donatien Garnier 1:916188eae2bb 85
Donatien Garnier 1:916188eae2bb 86 /* this will inform us off all events so we can schedule their handling
Donatien Garnier 1:916188eae2bb 87 * using our event queue */
Donatien Garnier 1:916188eae2bb 88 _ble.onEventsToProcess(
Donatien Garnier 1:916188eae2bb 89 makeFunctionPointer(this, &SMDevice::schedule_ble_events)
Donatien Garnier 1:916188eae2bb 90 );
Donatien Garnier 1:916188eae2bb 91
Donatien Garnier 1:916188eae2bb 92 /* handle timeouts, for example when connection attempts fail */
Donatien Garnier 1:916188eae2bb 93 _ble.gap().onTimeout(
Donatien Garnier 1:916188eae2bb 94 makeFunctionPointer(this, &SMDevice::on_timeout)
Donatien Garnier 1:916188eae2bb 95 );
Donatien Garnier 1:916188eae2bb 96
Donatien Garnier 1:916188eae2bb 97 error = _ble.init(this, &SMDevice::on_init_complete);
Donatien Garnier 1:916188eae2bb 98
Donatien Garnier 1:916188eae2bb 99 if (error) {
Donatien Garnier 1:916188eae2bb 100 printf("Error returned by BLE::init.\r\n");
Donatien Garnier 1:916188eae2bb 101 return;
Donatien Garnier 1:916188eae2bb 102 }
Donatien Garnier 1:916188eae2bb 103
Donatien Garnier 1:916188eae2bb 104 /* this will not return until shutdown */
Donatien Garnier 1:916188eae2bb 105 _event_queue.dispatch_forever();
Donatien Garnier 1:916188eae2bb 106 };
Donatien Garnier 1:916188eae2bb 107
Donatien Garnier 1:916188eae2bb 108 /* event handler functions */
Donatien Garnier 1:916188eae2bb 109
Donatien Garnier 1:916188eae2bb 110 /** Respond to a pairing request. This will be called by the stack
Donatien Garnier 1:916188eae2bb 111 * when a pairing request arrives and expects the application to
Donatien Garnier 1:916188eae2bb 112 * call acceptPairingRequest or cancelPairingRequest */
Donatien Garnier 1:916188eae2bb 113 virtual void pairingRequest(
Donatien Garnier 1:916188eae2bb 114 ble::connection_handle_t connectionHandle
Donatien Garnier 1:916188eae2bb 115 ) {
mbed_official 9:674ab70e0f36 116 printf("Pairing requested - authorising\r\n");
Donatien Garnier 1:916188eae2bb 117 _ble.securityManager().acceptPairingRequest(connectionHandle);
Donatien Garnier 1:916188eae2bb 118 }
Donatien Garnier 1:916188eae2bb 119
Donatien Garnier 1:916188eae2bb 120 /** Inform the application of a successful pairing. Terminate the demonstration. */
Donatien Garnier 1:916188eae2bb 121 virtual void pairingResult(
Donatien Garnier 1:916188eae2bb 122 ble::connection_handle_t connectionHandle,
Donatien Garnier 1:916188eae2bb 123 SecurityManager::SecurityCompletionStatus_t result
Donatien Garnier 1:916188eae2bb 124 ) {
Donatien Garnier 1:916188eae2bb 125 if (result == SecurityManager::SEC_STATUS_SUCCESS) {
Donatien Garnier 1:916188eae2bb 126 printf("Pairing successful\r\n");
Donatien Garnier 1:916188eae2bb 127 } else {
Donatien Garnier 1:916188eae2bb 128 printf("Pairing failed\r\n");
Donatien Garnier 1:916188eae2bb 129 }
Donatien Garnier 1:916188eae2bb 130 }
Donatien Garnier 1:916188eae2bb 131
Donatien Garnier 1:916188eae2bb 132 /** Inform the application of change in encryption status. This will be
Donatien Garnier 1:916188eae2bb 133 * communicated through the serial port */
Donatien Garnier 1:916188eae2bb 134 virtual void linkEncryptionResult(
Donatien Garnier 1:916188eae2bb 135 ble::connection_handle_t connectionHandle,
Donatien Garnier 1:916188eae2bb 136 ble::link_encryption_t result
Donatien Garnier 1:916188eae2bb 137 ) {
Donatien Garnier 1:916188eae2bb 138 if (result == ble::link_encryption_t::ENCRYPTED) {
Donatien Garnier 1:916188eae2bb 139 printf("Link ENCRYPTED\r\n");
Donatien Garnier 1:916188eae2bb 140 } else if (result == ble::link_encryption_t::ENCRYPTED_WITH_MITM) {
Donatien Garnier 1:916188eae2bb 141 printf("Link ENCRYPTED_WITH_MITM\r\n");
Donatien Garnier 1:916188eae2bb 142 } else if (result == ble::link_encryption_t::NOT_ENCRYPTED) {
Donatien Garnier 1:916188eae2bb 143 printf("Link NOT_ENCRYPTED\r\n");
Donatien Garnier 1:916188eae2bb 144 }
mbed_official 9:674ab70e0f36 145
mbed_official 9:674ab70e0f36 146 /* disconnect in 2 s */
mbed_official 9:674ab70e0f36 147 _event_queue.call_in(
mbed_official 9:674ab70e0f36 148 2000, &_ble.gap(),
mbed_official 9:674ab70e0f36 149 &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION
mbed_official 9:674ab70e0f36 150 );
Donatien Garnier 1:916188eae2bb 151 }
Donatien Garnier 1:916188eae2bb 152
Donatien Garnier 1:916188eae2bb 153 private:
Donatien Garnier 1:916188eae2bb 154 /** Override to start chosen activity when initialisation completes */
Donatien Garnier 1:916188eae2bb 155 virtual void start() = 0;
Donatien Garnier 1:916188eae2bb 156
Donatien Garnier 1:916188eae2bb 157 /** This is called when BLE interface is initialised and starts the demonstration */
Donatien Garnier 1:916188eae2bb 158 void on_init_complete(BLE::InitializationCompleteCallbackContext *event)
Donatien Garnier 1:916188eae2bb 159 {
Donatien Garnier 1:916188eae2bb 160 ble_error_t error;
Donatien Garnier 1:916188eae2bb 161
Donatien Garnier 1:916188eae2bb 162 if (event->error) {
Donatien Garnier 1:916188eae2bb 163 printf("Error during the initialisation\r\n");
Donatien Garnier 1:916188eae2bb 164 return;
Donatien Garnier 1:916188eae2bb 165 }
Donatien Garnier 1:916188eae2bb 166
mbed_official 9:674ab70e0f36 167 /* This path will be used to store bonding information but will fallback
mbed_official 9:674ab70e0f36 168 * to storing in memory if file access fails (for example due to lack of a filesystem) */
mbed_official 9:674ab70e0f36 169 const char* db_path = "/fs/bt_sec_db";
Donatien Garnier 1:916188eae2bb 170 /* If the security manager is required this needs to be called before any
Donatien Garnier 1:916188eae2bb 171 * calls to the Security manager happen. */
mbed_official 9:674ab70e0f36 172 error = _ble.securityManager().init(
mbed_official 9:674ab70e0f36 173 true,
mbed_official 9:674ab70e0f36 174 false,
mbed_official 9:674ab70e0f36 175 SecurityManager::IO_CAPS_NONE,
mbed_official 9:674ab70e0f36 176 NULL,
mbed_official 9:674ab70e0f36 177 false,
mbed_official 9:674ab70e0f36 178 db_path
mbed_official 9:674ab70e0f36 179 );
Donatien Garnier 1:916188eae2bb 180
Donatien Garnier 1:916188eae2bb 181 if (error) {
Donatien Garnier 1:916188eae2bb 182 printf("Error during init %d\r\n", error);
Donatien Garnier 1:916188eae2bb 183 return;
Donatien Garnier 1:916188eae2bb 184 }
Donatien Garnier 1:916188eae2bb 185
mbed_official 9:674ab70e0f36 186 error = _ble.securityManager().preserveBondingStateOnReset(true);
mbed_official 9:674ab70e0f36 187
mbed_official 9:674ab70e0f36 188 if (error) {
mbed_official 9:674ab70e0f36 189 printf("Error during preserveBondingStateOnReset %d\r\n", error);
mbed_official 9:674ab70e0f36 190 }
mbed_official 9:674ab70e0f36 191
mbed_official 9:674ab70e0f36 192 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 193 /* Enable privacy so we can find the keys */
mbed_official 9:674ab70e0f36 194 error = _ble.gap().enablePrivacy(true);
mbed_official 9:674ab70e0f36 195
mbed_official 9:674ab70e0f36 196 if (error) {
mbed_official 9:674ab70e0f36 197 printf("Error enabling privacy\r\n");
mbed_official 9:674ab70e0f36 198 }
mbed_official 9:674ab70e0f36 199
mbed_official 9:674ab70e0f36 200 Gap::PeripheralPrivacyConfiguration_t configuration_p = {
mbed_official 9:674ab70e0f36 201 /* use_non_resolvable_random_address */ false,
mbed_official 9:674ab70e0f36 202 Gap::PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS
mbed_official 9:674ab70e0f36 203 };
mbed_official 9:674ab70e0f36 204 _ble.gap().setPeripheralPrivacyConfiguration(&configuration_p);
mbed_official 9:674ab70e0f36 205
mbed_official 9:674ab70e0f36 206 Gap::CentralPrivacyConfiguration_t configuration_c = {
mbed_official 9:674ab70e0f36 207 /* use_non_resolvable_random_address */ false,
mbed_official 9:674ab70e0f36 208 Gap::CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD
mbed_official 9:674ab70e0f36 209 };
mbed_official 9:674ab70e0f36 210 _ble.gap().setCentralPrivacyConfiguration(&configuration_c);
mbed_official 9:674ab70e0f36 211
mbed_official 9:674ab70e0f36 212 /* this demo switches between being master and slave */
mbed_official 9:674ab70e0f36 213 _ble.securityManager().setHintFutureRoleReversal(true);
mbed_official 9:674ab70e0f36 214 #endif
mbed_official 9:674ab70e0f36 215
Donatien Garnier 1:916188eae2bb 216 /* Tell the security manager to use methods in this class to inform us
Donatien Garnier 1:916188eae2bb 217 * of any events. Class needs to implement SecurityManagerEventHandler. */
Donatien Garnier 1:916188eae2bb 218 _ble.securityManager().setSecurityManagerEventHandler(this);
Donatien Garnier 1:916188eae2bb 219
Donatien Garnier 1:916188eae2bb 220 /* print device address */
Donatien Garnier 1:916188eae2bb 221 Gap::AddressType_t addr_type;
Donatien Garnier 1:916188eae2bb 222 Gap::Address_t addr;
Donatien Garnier 1:916188eae2bb 223 _ble.gap().getAddress(&addr_type, addr);
Donatien Garnier 1:916188eae2bb 224 printf("Device address: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
Donatien Garnier 1:916188eae2bb 225 addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
Donatien Garnier 1:916188eae2bb 226
Donatien Garnier 1:916188eae2bb 227 /* when scanning we want to connect to a peer device so we need to
Donatien Garnier 1:916188eae2bb 228 * attach callbacks that are used by Gap to notify us of events */
Donatien Garnier 1:916188eae2bb 229 _ble.gap().onConnection(this, &SMDevice::on_connect);
Donatien Garnier 1:916188eae2bb 230 _ble.gap().onDisconnection(this, &SMDevice::on_disconnect);
Donatien Garnier 1:916188eae2bb 231
Donatien Garnier 1:916188eae2bb 232 /* start test in 500 ms */
Donatien Garnier 1:916188eae2bb 233 _event_queue.call_in(500, this, &SMDevice::start);
Donatien Garnier 1:916188eae2bb 234 };
Donatien Garnier 1:916188eae2bb 235
Donatien Garnier 1:916188eae2bb 236 /** This is called by Gap to notify the application we connected */
Donatien Garnier 1:916188eae2bb 237 virtual void on_connect(const Gap::ConnectionCallbackParams_t *connection_event) = 0;
Donatien Garnier 1:916188eae2bb 238
Donatien Garnier 1:916188eae2bb 239 /** This is called by Gap to notify the application we disconnected,
Donatien Garnier 1:916188eae2bb 240 * in our case it ends the demonstration. */
Donatien Garnier 1:916188eae2bb 241 void on_disconnect(const Gap::DisconnectionCallbackParams_t *event)
Donatien Garnier 1:916188eae2bb 242 {
mbed_official 9:674ab70e0f36 243 printf("Diconnected\r\n");
Donatien Garnier 1:916188eae2bb 244 _event_queue.break_dispatch();
Donatien Garnier 1:916188eae2bb 245 };
Donatien Garnier 1:916188eae2bb 246
Donatien Garnier 1:916188eae2bb 247 /** End demonstration unexpectedly. Called if timeout is reached during advertising,
Donatien Garnier 1:916188eae2bb 248 * scanning or connection initiation */
Donatien Garnier 1:916188eae2bb 249 void on_timeout(const Gap::TimeoutSource_t source)
Donatien Garnier 1:916188eae2bb 250 {
mbed_official 9:674ab70e0f36 251 printf("Unexpected timeout - aborting\r\n");
Donatien Garnier 1:916188eae2bb 252 _event_queue.break_dispatch();
Donatien Garnier 1:916188eae2bb 253 };
Donatien Garnier 1:916188eae2bb 254
Donatien Garnier 1:916188eae2bb 255 /** Schedule processing of events from the BLE in the event queue. */
Donatien Garnier 1:916188eae2bb 256 void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context)
Donatien Garnier 1:916188eae2bb 257 {
Donatien Garnier 1:916188eae2bb 258 _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents));
Donatien Garnier 1:916188eae2bb 259 };
Donatien Garnier 1:916188eae2bb 260
Donatien Garnier 1:916188eae2bb 261 /** Blink LED to show we're running */
Donatien Garnier 1:916188eae2bb 262 void blink(void)
Donatien Garnier 1:916188eae2bb 263 {
Donatien Garnier 1:916188eae2bb 264 _led1 = !_led1;
Donatien Garnier 1:916188eae2bb 265 };
Donatien Garnier 1:916188eae2bb 266
Donatien Garnier 1:916188eae2bb 267 private:
Donatien Garnier 1:916188eae2bb 268 DigitalOut _led1;
Donatien Garnier 1:916188eae2bb 269
Donatien Garnier 1:916188eae2bb 270 protected:
Donatien Garnier 1:916188eae2bb 271 BLE &_ble;
Donatien Garnier 1:916188eae2bb 272 events::EventQueue &_event_queue;
Donatien Garnier 1:916188eae2bb 273 BLEProtocol::AddressBytes_t &_peer_address;
Donatien Garnier 1:916188eae2bb 274 ble::connection_handle_t _handle;
Donatien Garnier 1:916188eae2bb 275 bool _is_connecting;
Donatien Garnier 1:916188eae2bb 276 };
Donatien Garnier 1:916188eae2bb 277
Donatien Garnier 1:916188eae2bb 278 /** A peripheral device will advertise, accept the connection and request
Donatien Garnier 1:916188eae2bb 279 * a change in link security. */
Donatien Garnier 1:916188eae2bb 280 class SMDevicePeripheral : public SMDevice {
Donatien Garnier 1:916188eae2bb 281 public:
Donatien Garnier 1:916188eae2bb 282 SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address)
Donatien Garnier 1:916188eae2bb 283 : SMDevice(ble, event_queue, peer_address) { }
Donatien Garnier 1:916188eae2bb 284
Donatien Garnier 1:916188eae2bb 285 virtual void start()
Donatien Garnier 1:916188eae2bb 286 {
Donatien Garnier 1:916188eae2bb 287 /* Set up and start advertising */
Donatien Garnier 1:916188eae2bb 288
Donatien Garnier 1:916188eae2bb 289 ble_error_t error;
Donatien Garnier 1:916188eae2bb 290 GapAdvertisingData advertising_data;
Donatien Garnier 1:916188eae2bb 291
Donatien Garnier 1:916188eae2bb 292 /* add advertising flags */
Donatien Garnier 1:916188eae2bb 293 advertising_data.addFlags(GapAdvertisingData::LE_GENERAL_DISCOVERABLE
Donatien Garnier 1:916188eae2bb 294 | GapAdvertisingData::BREDR_NOT_SUPPORTED);
Donatien Garnier 1:916188eae2bb 295
Donatien Garnier 1:916188eae2bb 296 /* add device name */
Donatien Garnier 1:916188eae2bb 297 advertising_data.addData(
Donatien Garnier 1:916188eae2bb 298 GapAdvertisingData::COMPLETE_LOCAL_NAME,
Donatien Garnier 1:916188eae2bb 299 DEVICE_NAME,
Donatien Garnier 1:916188eae2bb 300 sizeof(DEVICE_NAME)
Donatien Garnier 1:916188eae2bb 301 );
Donatien Garnier 1:916188eae2bb 302
Donatien Garnier 1:916188eae2bb 303 error = _ble.gap().setAdvertisingPayload(advertising_data);
Donatien Garnier 1:916188eae2bb 304
Donatien Garnier 1:916188eae2bb 305 if (error) {
Donatien Garnier 1:916188eae2bb 306 printf("Error during Gap::setAdvertisingPayload\r\n");
Donatien Garnier 1:916188eae2bb 307 return;
Donatien Garnier 1:916188eae2bb 308 }
Donatien Garnier 1:916188eae2bb 309
Donatien Garnier 1:916188eae2bb 310 /* advertise to everyone */
Donatien Garnier 1:916188eae2bb 311 _ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
Donatien Garnier 1:916188eae2bb 312 /* how many milliseconds between advertisements, lower interval
Donatien Garnier 1:916188eae2bb 313 * increases the chances of being seen at the cost of more power */
Donatien Garnier 1:916188eae2bb 314 _ble.gap().setAdvertisingInterval(20);
Donatien Garnier 1:916188eae2bb 315 _ble.gap().setAdvertisingTimeout(0);
Donatien Garnier 1:916188eae2bb 316
Donatien Garnier 1:916188eae2bb 317 error = _ble.gap().startAdvertising();
Donatien Garnier 1:916188eae2bb 318
Donatien Garnier 1:916188eae2bb 319 if (error) {
Donatien Garnier 1:916188eae2bb 320 printf("Error during Gap::startAdvertising.\r\n");
Donatien Garnier 1:916188eae2bb 321 return;
Donatien Garnier 1:916188eae2bb 322 }
Donatien Garnier 1:916188eae2bb 323
mbed_official 9:674ab70e0f36 324 printf("Please connect to device\r\n");
mbed_official 9:674ab70e0f36 325
Donatien Garnier 1:916188eae2bb 326 /** This tells the stack to generate a pairingRequest event
Donatien Garnier 1:916188eae2bb 327 * which will require this application to respond before pairing
Donatien Garnier 1:916188eae2bb 328 * can proceed. Setting it to false will automatically accept
Donatien Garnier 1:916188eae2bb 329 * pairing. */
Donatien Garnier 1:916188eae2bb 330 _ble.securityManager().setPairingRequestAuthorisation(true);
Donatien Garnier 1:916188eae2bb 331 };
Donatien Garnier 1:916188eae2bb 332
Donatien Garnier 1:916188eae2bb 333 /** This is called by Gap to notify the application we connected,
Donatien Garnier 1:916188eae2bb 334 * in our case it immediately requests a change in link security */
Donatien Garnier 1:916188eae2bb 335 virtual void on_connect(const Gap::ConnectionCallbackParams_t *connection_event)
Donatien Garnier 1:916188eae2bb 336 {
Donatien Garnier 1:916188eae2bb 337 ble_error_t error;
Donatien Garnier 1:916188eae2bb 338
Donatien Garnier 1:916188eae2bb 339 /* remember the device that connects to us now so we can connect to it
Donatien Garnier 1:916188eae2bb 340 * during the next demonstration */
Donatien Garnier 1:916188eae2bb 341 memcpy(_peer_address, connection_event->peerAddr, sizeof(_peer_address));
Donatien Garnier 1:916188eae2bb 342
mbed_official 9:674ab70e0f36 343 printf("Connected to: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
mbed_official 9:674ab70e0f36 344 _peer_address[5], _peer_address[4], _peer_address[3],
mbed_official 9:674ab70e0f36 345 _peer_address[2], _peer_address[1], _peer_address[0]);
mbed_official 9:674ab70e0f36 346
Donatien Garnier 1:916188eae2bb 347 /* store the handle for future Security Manager requests */
Donatien Garnier 1:916188eae2bb 348 _handle = connection_event->handle;
Donatien Garnier 1:916188eae2bb 349
Donatien Garnier 1:916188eae2bb 350 /* Request a change in link security. This will be done
Donatien Garnier 1:916188eae2bb 351 * indirectly by asking the master of the connection to
Donatien Garnier 1:916188eae2bb 352 * change it. Depending on circumstances different actions
Donatien Garnier 1:916188eae2bb 353 * may be taken by the master which will trigger events
Donatien Garnier 1:916188eae2bb 354 * which the applications should deal with. */
Donatien Garnier 1:916188eae2bb 355 error = _ble.securityManager().setLinkSecurity(
Donatien Garnier 1:916188eae2bb 356 _handle,
Donatien Garnier 1:916188eae2bb 357 SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM
Donatien Garnier 1:916188eae2bb 358 );
Donatien Garnier 1:916188eae2bb 359
Donatien Garnier 1:916188eae2bb 360 if (error) {
Donatien Garnier 1:916188eae2bb 361 printf("Error during SM::setLinkSecurity %d\r\n", error);
Donatien Garnier 1:916188eae2bb 362 return;
Donatien Garnier 1:916188eae2bb 363 }
Donatien Garnier 1:916188eae2bb 364 };
Donatien Garnier 1:916188eae2bb 365 };
Donatien Garnier 1:916188eae2bb 366
Donatien Garnier 1:916188eae2bb 367 /** A central device will scan, connect to a peer and request pairing. */
Donatien Garnier 1:916188eae2bb 368 class SMDeviceCentral : public SMDevice {
Donatien Garnier 1:916188eae2bb 369 public:
Donatien Garnier 1:916188eae2bb 370 SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address)
Donatien Garnier 1:916188eae2bb 371 : SMDevice(ble, event_queue, peer_address) { }
Donatien Garnier 1:916188eae2bb 372
Donatien Garnier 1:916188eae2bb 373 virtual void start()
Donatien Garnier 1:916188eae2bb 374 {
Donatien Garnier 1:916188eae2bb 375 /* start scanning and attach a callback that will handle advertisements
Donatien Garnier 1:916188eae2bb 376 * and scan requests responses */
Donatien Garnier 1:916188eae2bb 377 ble_error_t error = _ble.gap().startScan(this, &SMDeviceCentral::on_scan);
Donatien Garnier 1:916188eae2bb 378
mbed_official 9:674ab70e0f36 379 printf("Please advertise\r\n");
mbed_official 9:674ab70e0f36 380
mbed_official 9:674ab70e0f36 381 printf("Scanning for: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
mbed_official 9:674ab70e0f36 382 _peer_address[5], _peer_address[4], _peer_address[3],
mbed_official 9:674ab70e0f36 383 _peer_address[2], _peer_address[1], _peer_address[0]);
mbed_official 9:674ab70e0f36 384
Donatien Garnier 1:916188eae2bb 385 if (error) {
Donatien Garnier 1:916188eae2bb 386 printf("Error during Gap::startScan %d\r\n", error);
Donatien Garnier 1:916188eae2bb 387 return;
Donatien Garnier 1:916188eae2bb 388 }
Donatien Garnier 1:916188eae2bb 389 }
Donatien Garnier 1:916188eae2bb 390
Donatien Garnier 1:916188eae2bb 391 /** Look at scan payload to find a peer device and connect to it */
Donatien Garnier 1:916188eae2bb 392 void on_scan(const Gap::AdvertisementCallbackParams_t *params)
Donatien Garnier 1:916188eae2bb 393 {
Donatien Garnier 1:916188eae2bb 394 /* don't bother with analysing scan result if we're already connecting */
Donatien Garnier 1:916188eae2bb 395 if (_is_connecting) {
Donatien Garnier 1:916188eae2bb 396 return;
Donatien Garnier 1:916188eae2bb 397 }
Donatien Garnier 1:916188eae2bb 398
mbed_official 9:674ab70e0f36 399 /* connect to the same device that connected to us */
mbed_official 9:674ab70e0f36 400 if (memcmp(params->peerAddr, _peer_address, sizeof(_peer_address)) == 0) {
Donatien Garnier 1:916188eae2bb 401
mbed_official 9:674ab70e0f36 402 ble_error_t error = _ble.gap().connect(
mbed_official 9:674ab70e0f36 403 params->peerAddr, params->peerAddrType,
mbed_official 9:674ab70e0f36 404 NULL, NULL
mbed_official 9:674ab70e0f36 405 );
Donatien Garnier 1:916188eae2bb 406
mbed_official 9:674ab70e0f36 407 if (error) {
mbed_official 9:674ab70e0f36 408 printf("Error during Gap::connect %d\r\n", error);
Donatien Garnier 1:916188eae2bb 409 return;
Donatien Garnier 1:916188eae2bb 410 }
Donatien Garnier 1:916188eae2bb 411
mbed_official 9:674ab70e0f36 412 printf("Connecting... ");
mbed_official 9:674ab70e0f36 413
mbed_official 9:674ab70e0f36 414 /* we may have already scan events waiting
mbed_official 9:674ab70e0f36 415 * to be processed so we need to remember
mbed_official 9:674ab70e0f36 416 * that we are already connecting and ignore them */
mbed_official 9:674ab70e0f36 417 _is_connecting = true;
mbed_official 9:674ab70e0f36 418
mbed_official 9:674ab70e0f36 419 return;
Donatien Garnier 1:916188eae2bb 420 }
Donatien Garnier 1:916188eae2bb 421 };
Donatien Garnier 1:916188eae2bb 422
Donatien Garnier 1:916188eae2bb 423 /** This is called by Gap to notify the application we connected,
Donatien Garnier 1:916188eae2bb 424 * in our case it immediately request pairing */
Donatien Garnier 1:916188eae2bb 425 virtual void on_connect(const Gap::ConnectionCallbackParams_t *connection_event)
Donatien Garnier 1:916188eae2bb 426 {
Donatien Garnier 1:916188eae2bb 427 ble_error_t error;
Donatien Garnier 1:916188eae2bb 428
Donatien Garnier 1:916188eae2bb 429 /* store the handle for future Security Manager requests */
Donatien Garnier 1:916188eae2bb 430 _handle = connection_event->handle;
Donatien Garnier 1:916188eae2bb 431
Donatien Garnier 1:916188eae2bb 432 /* in this example the local device is the master so we request pairing */
Donatien Garnier 1:916188eae2bb 433 error = _ble.securityManager().requestPairing(_handle);
Donatien Garnier 1:916188eae2bb 434
mbed_official 9:674ab70e0f36 435 printf("Connected\r\n");
mbed_official 9:674ab70e0f36 436
Donatien Garnier 1:916188eae2bb 437 if (error) {
Donatien Garnier 1:916188eae2bb 438 printf("Error during SM::requestPairing %d\r\n", error);
Donatien Garnier 1:916188eae2bb 439 return;
Donatien Garnier 1:916188eae2bb 440 }
Donatien Garnier 1:916188eae2bb 441
Donatien Garnier 1:916188eae2bb 442 /* upon pairing success the application will disconnect */
Donatien Garnier 1:916188eae2bb 443 };
Donatien Garnier 1:916188eae2bb 444 };
Donatien Garnier 1:916188eae2bb 445
mbed_official 9:674ab70e0f36 446
mbed_official 9:674ab70e0f36 447 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 448 bool create_filesystem()
mbed_official 9:674ab70e0f36 449 {
mbed_official 9:674ab70e0f36 450 static LittleFileSystem fs("fs");
mbed_official 9:674ab70e0f36 451
mbed_official 9:674ab70e0f36 452 /* replace this with any physical block device your board supports (like an SD card) */
mbed_official 9:674ab70e0f36 453 static HeapBlockDevice bd(4096, 256);
mbed_official 9:674ab70e0f36 454
mbed_official 9:674ab70e0f36 455 int err = bd.init();
mbed_official 9:674ab70e0f36 456
mbed_official 9:674ab70e0f36 457 if (err) {
mbed_official 9:674ab70e0f36 458 return false;
mbed_official 9:674ab70e0f36 459 }
mbed_official 9:674ab70e0f36 460
mbed_official 9:674ab70e0f36 461 err = bd.erase(0, bd.size());
mbed_official 9:674ab70e0f36 462
mbed_official 9:674ab70e0f36 463 if (err) {
mbed_official 9:674ab70e0f36 464 return false;
mbed_official 9:674ab70e0f36 465 }
mbed_official 9:674ab70e0f36 466
mbed_official 9:674ab70e0f36 467 err = fs.mount(&bd);
mbed_official 9:674ab70e0f36 468
mbed_official 9:674ab70e0f36 469 if (err) {
mbed_official 9:674ab70e0f36 470 /* Reformat if we can't mount the filesystem */
mbed_official 9:674ab70e0f36 471 printf("No filesystem found, formatting...\r\n");
mbed_official 9:674ab70e0f36 472
mbed_official 9:674ab70e0f36 473 err = fs.reformat(&bd);
mbed_official 9:674ab70e0f36 474
mbed_official 9:674ab70e0f36 475 if (err) {
mbed_official 9:674ab70e0f36 476 return false;
mbed_official 9:674ab70e0f36 477 }
mbed_official 9:674ab70e0f36 478 }
mbed_official 9:674ab70e0f36 479
mbed_official 9:674ab70e0f36 480 return true;
mbed_official 9:674ab70e0f36 481 }
mbed_official 9:674ab70e0f36 482 #endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 483
Donatien Garnier 1:916188eae2bb 484 int main()
Donatien Garnier 1:916188eae2bb 485 {
Donatien Garnier 1:916188eae2bb 486 BLE& ble = BLE::Instance();
Donatien Garnier 1:916188eae2bb 487 events::EventQueue queue;
Donatien Garnier 1:916188eae2bb 488
mbed_official 9:674ab70e0f36 489 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
mbed_official 9:674ab70e0f36 490 /* if filesystem creation fails or there is no filesystem the security manager
mbed_official 9:674ab70e0f36 491 * will fallback to storing the security database in memory */
mbed_official 9:674ab70e0f36 492 if (!create_filesystem()) {
mbed_official 9:674ab70e0f36 493 printf("Filesystem creation failed, will use memory storage\r\n");
Donatien Garnier 1:916188eae2bb 494 }
mbed_official 9:674ab70e0f36 495 #endif
Donatien Garnier 1:916188eae2bb 496
mbed_official 9:674ab70e0f36 497 while(1) {
mbed_official 9:674ab70e0f36 498 {
mbed_official 9:674ab70e0f36 499 printf("\r\n PERIPHERAL \r\n\r\n");
mbed_official 9:674ab70e0f36 500 SMDevicePeripheral peripheral(ble, queue, peer_address);
mbed_official 9:674ab70e0f36 501 peripheral.run();
mbed_official 9:674ab70e0f36 502 }
mbed_official 9:674ab70e0f36 503
mbed_official 9:674ab70e0f36 504 {
mbed_official 9:674ab70e0f36 505 printf("\r\n CENTRAL \r\n\r\n");
mbed_official 9:674ab70e0f36 506 SMDeviceCentral central(ble, queue, peer_address);
mbed_official 9:674ab70e0f36 507 central.run();
mbed_official 9:674ab70e0f36 508 }
Donatien Garnier 1:916188eae2bb 509 }
Donatien Garnier 1:916188eae2bb 510
Donatien Garnier 1:916188eae2bb 511 return 0;
Donatien Garnier 1:916188eae2bb 512 }