this is using the mbed os version 5-13-1

Dependencies:   mbed-http

Committer:
ocomeni
Date:
Sat May 25 16:25:42 2019 +0000
Branch:
PassingRegression
Revision:
118:8df0e9c2ee3f
Parent:
116:2296cf274661
Child:
119:8d939a902333
- fixed memory leak bug with ATCMD manager; - added BLE memory pool and queues and connected up to main, BLE manager and ATCMD; - code compiling; - python test passing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ocomeni 74:f26e846adfe9 1 /* mbed Microcontroller Library
ocomeni 74:f26e846adfe9 2 * Copyright (c) 2006-2013 ARM Limited
ocomeni 74:f26e846adfe9 3 *
ocomeni 74:f26e846adfe9 4 * Licensed under the Apache License, Version 2.0 (the "License");
ocomeni 74:f26e846adfe9 5 * you may not use this file except in compliance with the License.
ocomeni 74:f26e846adfe9 6 * You may obtain a copy of the License at
ocomeni 74:f26e846adfe9 7 *
ocomeni 74:f26e846adfe9 8 * http://www.apache.org/licenses/LICENSE-2.0
ocomeni 74:f26e846adfe9 9 *
ocomeni 74:f26e846adfe9 10 * Unless required by applicable law or agreed to in writing, software
ocomeni 74:f26e846adfe9 11 * distributed under the License is distributed on an "AS IS" BASIS,
ocomeni 74:f26e846adfe9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ocomeni 74:f26e846adfe9 13 * See the License for the specific language governing permissions and
ocomeni 74:f26e846adfe9 14 * limitations under the License.
ocomeni 74:f26e846adfe9 15 */
ocomeni 75:08eff6258e1b 16
ocomeni 74:f26e846adfe9 17 #include <events/mbed_events.h>
ocomeni 74:f26e846adfe9 18 #include <mbed.h>
ocomeni 103:7b566b522427 19 #include "debug.h"
ocomeni 76:6afda865fbf8 20 #include "common_config.h"
ocomeni 74:f26e846adfe9 21 #include "ble/BLE.h"
ocomeni 76:6afda865fbf8 22 #include "ble/services/UARTService.h"
ocomeni 74:f26e846adfe9 23 #include "SecurityManager.h"
ocomeni 75:08eff6258e1b 24 #include "BleManager.h"
ocomeni 75:08eff6258e1b 25 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
ocomeni 75:08eff6258e1b 26 #include "LittleFileSystem.h"
ocomeni 75:08eff6258e1b 27 #include "HeapBlockDevice.h"
ocomeni 75:08eff6258e1b 28 #endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
ocomeni 103:7b566b522427 29 #define FILE_CODE "btle"
ocomeni 75:08eff6258e1b 30
ocomeni 75:08eff6258e1b 31
ocomeni 113:888e262ff0a9 32 //static const uint8_t DEVICE_NAME[] = "SM_device";
ocomeni 76:6afda865fbf8 33 //static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID};
ocomeni 76:6afda865fbf8 34 extern UARTService *uart;
ocomeni 76:6afda865fbf8 35 extern char buffer[BUFFER_LEN];
ocomeni 75:08eff6258e1b 36 /** This example demonstrates all the basic setup required
ocomeni 75:08eff6258e1b 37 * for pairing and setting up link security both as a central and peripheral
ocomeni 75:08eff6258e1b 38 *
ocomeni 75:08eff6258e1b 39 * The example is implemented as two classes, one for the peripheral and one
ocomeni 75:08eff6258e1b 40 * for central inheriting from a common base. They are run in sequence and
ocomeni 75:08eff6258e1b 41 * require a peer device to connect to. During the peripheral device demonstration
ocomeni 75:08eff6258e1b 42 * a peer device is required to connect. In the central device demonstration
ocomeni 75:08eff6258e1b 43 * this peer device will be scanned for and connected to - therefore it should
ocomeni 75:08eff6258e1b 44 * be advertising with the same address as when it connected.
ocomeni 75:08eff6258e1b 45 *
ocomeni 75:08eff6258e1b 46 * During the test output is written on the serial connection to monitor its
ocomeni 75:08eff6258e1b 47 * progress.
ocomeni 75:08eff6258e1b 48 */
ocomeni 75:08eff6258e1b 49
ocomeni 75:08eff6258e1b 50 //static const uint8_t DEVICE_NAME[] = "SM_device";
ocomeni 75:08eff6258e1b 51
ocomeni 75:08eff6258e1b 52 /* for demonstration purposes we will store the peer device address
ocomeni 75:08eff6258e1b 53 * of the device that connects to us in the first demonstration
ocomeni 75:08eff6258e1b 54 * so we can use its address to reconnect to it later */
ocomeni 75:08eff6258e1b 55 //static BLEProtocol::AddressBytes_t peer_address;
ocomeni 75:08eff6258e1b 56
ocomeni 75:08eff6258e1b 57 /** Base class for both peripheral and central. The same class that provides
ocomeni 75:08eff6258e1b 58 * the logic for the application also implements the SecurityManagerEventHandler
ocomeni 75:08eff6258e1b 59 * which is the interface used by the Security Manager to communicate events
ocomeni 75:08eff6258e1b 60 * back to the applications. You can provide overrides for a selection of events
ocomeni 75:08eff6258e1b 61 * your application is interested in.
ocomeni 75:08eff6258e1b 62 */
ocomeni 78:07bb86e3ce14 63 SMDevice::SMDevice(BLE &ble, events::EventQueue &event_queue,
ocomeni 118:8df0e9c2ee3f 64 BLEProtocol::AddressBytes_t &peer_address,
ocomeni 118:8df0e9c2ee3f 65 MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool,
ocomeni 118:8df0e9c2ee3f 66 Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue,
ocomeni 118:8df0e9c2ee3f 67 MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool,
ocomeni 118:8df0e9c2ee3f 68 Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue,
ocomeni 118:8df0e9c2ee3f 69 ble_config_t *ble_config) :
ocomeni 75:08eff6258e1b 70 _ble(ble),
ocomeni 75:08eff6258e1b 71 _event_queue(event_queue),
ocomeni 75:08eff6258e1b 72 _peer_address(peer_address),
ocomeni 118:8df0e9c2ee3f 73 _aT2BleDatamPool (aT2BleDatamPool),
ocomeni 118:8df0e9c2ee3f 74 _aT2BleDataQueue (aT2BleDataQueue),
ocomeni 118:8df0e9c2ee3f 75 _ble2ATDatamPool (ble2ATDatamPool),
ocomeni 118:8df0e9c2ee3f 76 _ble2ATDataQueue (ble2ATDataQueue),
ocomeni 78:07bb86e3ce14 77 ble_config(ble_config),
ocomeni 75:08eff6258e1b 78 _handle(0),
ocomeni 113:888e262ff0a9 79 _is_connecting(false),
ocomeni 113:888e262ff0a9 80 _led1(LED1, 0)
ocomeni 113:888e262ff0a9 81 {
ocomeni 113:888e262ff0a9 82 isConnected = false;
ocomeni 113:888e262ff0a9 83 }
ocomeni 75:08eff6258e1b 84
ocomeni 75:08eff6258e1b 85 SMDevice::~SMDevice()
ocomeni 75:08eff6258e1b 86 {
ocomeni 75:08eff6258e1b 87 if (_ble.hasInitialized()) {
ocomeni 75:08eff6258e1b 88 _ble.shutdown();
ocomeni 75:08eff6258e1b 89 }
ocomeni 75:08eff6258e1b 90 }
ocomeni 75:08eff6258e1b 91
ocomeni 75:08eff6258e1b 92 /** Start BLE interface initialisation */
ocomeni 75:08eff6258e1b 93 void SMDevice::run()
ocomeni 75:08eff6258e1b 94 {
ocomeni 103:7b566b522427 95 dbg_printf(LOG, "\r\n [BTLE MAN] Thread Id = %X\r\n", (uint32_t)ThisThread::get_id());
ocomeni 87:99b37d26ff2a 96
ocomeni 75:08eff6258e1b 97 ble_error_t error;
ocomeni 75:08eff6258e1b 98
ocomeni 108:3c8fb2c6e7bf 99 /* to show we're running we'll blink every 10secs */
ocomeni 108:3c8fb2c6e7bf 100 _event_queue.call_every(10000, this, &SMDevice::blink);
ocomeni 75:08eff6258e1b 101
ocomeni 77:0b505d1e15f4 102 /* to show we're advertising we'll print status every minute */
ocomeni 77:0b505d1e15f4 103 _event_queue.call_every(60000, this, &SMDevice::reportGapState);
ocomeni 77:0b505d1e15f4 104
ocomeni 77:0b505d1e15f4 105
ocomeni 77:0b505d1e15f4 106
ocomeni 75:08eff6258e1b 107 if (_ble.hasInitialized()) {
ocomeni 103:7b566b522427 108 dbg_printf(LOG, "Ble instance already initialised.\r\n");
ocomeni 75:08eff6258e1b 109 return;
ocomeni 75:08eff6258e1b 110 }
ocomeni 75:08eff6258e1b 111
ocomeni 75:08eff6258e1b 112 /* this will inform us off all events so we can schedule their handling
ocomeni 75:08eff6258e1b 113 * using our event queue */
ocomeni 75:08eff6258e1b 114 _ble.onEventsToProcess(
ocomeni 75:08eff6258e1b 115 makeFunctionPointer(this, &SMDevice::schedule_ble_events)
ocomeni 75:08eff6258e1b 116 );
ocomeni 75:08eff6258e1b 117
ocomeni 75:08eff6258e1b 118 /* handle timeouts, for example when connection attempts fail */
ocomeni 75:08eff6258e1b 119 _ble.gap().onTimeout(
ocomeni 75:08eff6258e1b 120 makeFunctionPointer(this, &SMDevice::on_timeout)
ocomeni 75:08eff6258e1b 121 );
ocomeni 75:08eff6258e1b 122
ocomeni 75:08eff6258e1b 123 error = _ble.init(this, &SMDevice::on_init_complete);
ocomeni 75:08eff6258e1b 124
ocomeni 75:08eff6258e1b 125 if (error) {
ocomeni 103:7b566b522427 126 dbg_printf(LOG, "Error returned by BLE::init.\r\n");
ocomeni 75:08eff6258e1b 127 return;
ocomeni 75:08eff6258e1b 128 }
ocomeni 75:08eff6258e1b 129
ocomeni 75:08eff6258e1b 130 /* this will not return until shutdown */
ocomeni 77:0b505d1e15f4 131 //_event_queue.dispatch_forever();
ocomeni 75:08eff6258e1b 132 }
ocomeni 75:08eff6258e1b 133
ocomeni 77:0b505d1e15f4 134
ocomeni 77:0b505d1e15f4 135 void SMDevice::shutDown()
ocomeni 77:0b505d1e15f4 136 {
ocomeni 77:0b505d1e15f4 137 if (_ble.hasInitialized()) {
ocomeni 77:0b505d1e15f4 138 _ble.shutdown();
ocomeni 103:7b566b522427 139 dbg_printf(LOG, "Shutting down BLE Instance...\r\n");
ocomeni 77:0b505d1e15f4 140 _event_queue.break_dispatch();
ocomeni 77:0b505d1e15f4 141 }
ocomeni 77:0b505d1e15f4 142 }
ocomeni 77:0b505d1e15f4 143
ocomeni 77:0b505d1e15f4 144
ocomeni 75:08eff6258e1b 145 /* event handler functions */
ocomeni 75:08eff6258e1b 146
ocomeni 75:08eff6258e1b 147 /** Respond to a pairing request. This will be called by the stack
ocomeni 75:08eff6258e1b 148 * when a pairing request arrives and expects the application to
ocomeni 75:08eff6258e1b 149 * call acceptPairingRequest or cancelPairingRequest */
ocomeni 75:08eff6258e1b 150 void SMDevice::pairingRequest(
ocomeni 75:08eff6258e1b 151 ble::connection_handle_t connectionHandle
ocomeni 75:08eff6258e1b 152 ) {
ocomeni 103:7b566b522427 153 dbg_printf(LOG, "Pairing requested - authorising\r\n");
ocomeni 75:08eff6258e1b 154 _ble.securityManager().acceptPairingRequest(connectionHandle);
ocomeni 75:08eff6258e1b 155 }
ocomeni 75:08eff6258e1b 156
ocomeni 75:08eff6258e1b 157 /** Inform the application of a successful pairing. Terminate the demonstration. */
ocomeni 75:08eff6258e1b 158 void SMDevice::pairingResult(
ocomeni 75:08eff6258e1b 159 ble::connection_handle_t connectionHandle,
ocomeni 75:08eff6258e1b 160 SecurityManager::SecurityCompletionStatus_t result
ocomeni 75:08eff6258e1b 161 ) {
ocomeni 75:08eff6258e1b 162 if (result == SecurityManager::SEC_STATUS_SUCCESS) {
ocomeni 103:7b566b522427 163 dbg_printf(LOG, "Pairing successful\r\n");
ocomeni 75:08eff6258e1b 164 } else {
ocomeni 103:7b566b522427 165 dbg_printf(LOG, "Pairing failed\r\n");
ocomeni 75:08eff6258e1b 166 }
ocomeni 75:08eff6258e1b 167 }
ocomeni 75:08eff6258e1b 168
ocomeni 75:08eff6258e1b 169 /** Inform the application of change in encryption status. This will be
ocomeni 75:08eff6258e1b 170 * communicated through the serial port */
ocomeni 75:08eff6258e1b 171 void SMDevice::linkEncryptionResult(
ocomeni 75:08eff6258e1b 172 ble::connection_handle_t connectionHandle,
ocomeni 75:08eff6258e1b 173 ble::link_encryption_t result
ocomeni 75:08eff6258e1b 174 ) {
ocomeni 75:08eff6258e1b 175 if (result == ble::link_encryption_t::ENCRYPTED) {
ocomeni 103:7b566b522427 176 dbg_printf(LOG, "Link ENCRYPTED\r\n");
ocomeni 75:08eff6258e1b 177 } else if (result == ble::link_encryption_t::ENCRYPTED_WITH_MITM) {
ocomeni 103:7b566b522427 178 dbg_printf(LOG, "Link ENCRYPTED_WITH_MITM\r\n");
ocomeni 75:08eff6258e1b 179 } else if (result == ble::link_encryption_t::NOT_ENCRYPTED) {
ocomeni 103:7b566b522427 180 dbg_printf(LOG, "Link NOT_ENCRYPTED\r\n");
ocomeni 75:08eff6258e1b 181 }
ocomeni 75:08eff6258e1b 182
ocomeni 76:6afda865fbf8 183 #ifdef DEMO_BLE_SECURITY
ocomeni 75:08eff6258e1b 184 /* disconnect in 2 s */
ocomeni 75:08eff6258e1b 185 _event_queue.call_in(
ocomeni 75:08eff6258e1b 186 2000, &_ble.gap(),
ocomeni 75:08eff6258e1b 187 &Gap::disconnect, _handle, Gap::REMOTE_USER_TERMINATED_CONNECTION
ocomeni 75:08eff6258e1b 188 );
ocomeni 76:6afda865fbf8 189 #endif
ocomeni 75:08eff6258e1b 190 }
ocomeni 75:08eff6258e1b 191
ocomeni 75:08eff6258e1b 192 /** Override to start chosen activity when initialisation completes */
ocomeni 75:08eff6258e1b 193 //void SMDevice::start() = 0;
ocomeni 75:08eff6258e1b 194
ocomeni 75:08eff6258e1b 195 /** This is called when BLE interface is initialised and starts the demonstration */
ocomeni 75:08eff6258e1b 196 void SMDevice::on_init_complete(BLE::InitializationCompleteCallbackContext *event)
ocomeni 75:08eff6258e1b 197 {
ocomeni 75:08eff6258e1b 198 ble_error_t error;
ocomeni 75:08eff6258e1b 199
ocomeni 75:08eff6258e1b 200 if (event->error) {
ocomeni 103:7b566b522427 201 dbg_printf(LOG, "Error during the initialisation\r\n");
ocomeni 75:08eff6258e1b 202 return;
ocomeni 75:08eff6258e1b 203 }
ocomeni 75:08eff6258e1b 204
ocomeni 75:08eff6258e1b 205 /* This path will be used to store bonding information but will fallback
ocomeni 75:08eff6258e1b 206 * to storing in memory if file access fails (for example due to lack of a filesystem) */
ocomeni 75:08eff6258e1b 207 const char* db_path = "/fs/bt_sec_db";
ocomeni 75:08eff6258e1b 208 /* If the security manager is required this needs to be called before any
ocomeni 75:08eff6258e1b 209 * calls to the Security manager happen. */
ocomeni 75:08eff6258e1b 210 error = _ble.securityManager().init(
ocomeni 75:08eff6258e1b 211 true,
ocomeni 75:08eff6258e1b 212 false,
ocomeni 79:a2187bbfa407 213 SecurityManager::IO_CAPS_DISPLAY_ONLY, // SecurityManager::IO_CAPS_NONE
ocomeni 116:2296cf274661 214 ble_config->pairingKey,
ocomeni 75:08eff6258e1b 215 false,
ocomeni 75:08eff6258e1b 216 db_path
ocomeni 75:08eff6258e1b 217 );
ocomeni 75:08eff6258e1b 218
ocomeni 75:08eff6258e1b 219 if (error) {
ocomeni 103:7b566b522427 220 dbg_printf(LOG, "Error during init %d\r\n", error);
ocomeni 75:08eff6258e1b 221 return;
ocomeni 75:08eff6258e1b 222 }
ocomeni 75:08eff6258e1b 223
ocomeni 75:08eff6258e1b 224 error = _ble.securityManager().preserveBondingStateOnReset(true);
ocomeni 75:08eff6258e1b 225
ocomeni 75:08eff6258e1b 226 if (error) {
ocomeni 103:7b566b522427 227 dbg_printf(LOG, "Error during preserveBondingStateOnReset %d\r\n", error);
ocomeni 75:08eff6258e1b 228 }
ocomeni 75:08eff6258e1b 229
ocomeni 75:08eff6258e1b 230 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
ocomeni 75:08eff6258e1b 231 /* Enable privacy so we can find the keys */
ocomeni 75:08eff6258e1b 232 error = _ble.gap().enablePrivacy(true);
ocomeni 75:08eff6258e1b 233
ocomeni 75:08eff6258e1b 234 if (error) {
ocomeni 103:7b566b522427 235 dbg_printf(LOG, "Error enabling privacy\r\n");
ocomeni 75:08eff6258e1b 236 }
ocomeni 75:08eff6258e1b 237
ocomeni 75:08eff6258e1b 238 Gap::PeripheralPrivacyConfiguration_t configuration_p = {
ocomeni 75:08eff6258e1b 239 /* use_non_resolvable_random_address */ false,
ocomeni 75:08eff6258e1b 240 Gap::PeripheralPrivacyConfiguration_t::REJECT_NON_RESOLVED_ADDRESS
ocomeni 75:08eff6258e1b 241 };
ocomeni 75:08eff6258e1b 242 _ble.gap().setPeripheralPrivacyConfiguration(&configuration_p);
ocomeni 75:08eff6258e1b 243
ocomeni 75:08eff6258e1b 244 Gap::CentralPrivacyConfiguration_t configuration_c = {
ocomeni 75:08eff6258e1b 245 /* use_non_resolvable_random_address */ false,
ocomeni 75:08eff6258e1b 246 Gap::CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD
ocomeni 75:08eff6258e1b 247 };
ocomeni 75:08eff6258e1b 248 _ble.gap().setCentralPrivacyConfiguration(&configuration_c);
ocomeni 75:08eff6258e1b 249
ocomeni 75:08eff6258e1b 250 /* this demo switches between being master and slave */
ocomeni 75:08eff6258e1b 251 _ble.securityManager().setHintFutureRoleReversal(true);
ocomeni 75:08eff6258e1b 252 #endif
ocomeni 75:08eff6258e1b 253
ocomeni 75:08eff6258e1b 254 /* Tell the security manager to use methods in this class to inform us
ocomeni 75:08eff6258e1b 255 * of any events. Class needs to implement SecurityManagerEventHandler. */
ocomeni 75:08eff6258e1b 256 _ble.securityManager().setSecurityManagerEventHandler(this);
ocomeni 75:08eff6258e1b 257
ocomeni 75:08eff6258e1b 258 /* print device address */
ocomeni 75:08eff6258e1b 259 Gap::AddressType_t addr_type;
ocomeni 75:08eff6258e1b 260 Gap::Address_t addr;
ocomeni 75:08eff6258e1b 261 _ble.gap().getAddress(&addr_type, addr);
ocomeni 103:7b566b522427 262 dbg_printf(LOG, "Device address: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
ocomeni 75:08eff6258e1b 263 addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
ocomeni 75:08eff6258e1b 264
ocomeni 75:08eff6258e1b 265 /* when scanning we want to connect to a peer device so we need to
ocomeni 75:08eff6258e1b 266 * attach callbacks that are used by Gap to notify us of events */
ocomeni 75:08eff6258e1b 267 _ble.gap().onConnection(this, &SMDevice::on_connect);
ocomeni 75:08eff6258e1b 268 _ble.gap().onDisconnection(this, &SMDevice::on_disconnect);
ocomeni 76:6afda865fbf8 269 _ble.gattServer().onDataWritten(this, &SMDevice::onDataWrittenCallback);
ocomeni 79:a2187bbfa407 270 //_ble.securityManager().onPasskeyDisplay(this, &SMDevice::passkeyDisplayCallback);
ocomeni 79:a2187bbfa407 271 //_ble.securityManager().onSecuritySetupCompleted(this, &SMDevice::securitySetupCompletedCallback);
ocomeni 75:08eff6258e1b 272
ocomeni 75:08eff6258e1b 273 /* start test in 500 ms */
ocomeni 75:08eff6258e1b 274 _event_queue.call_in(500, this, &SMDevice::start);
ocomeni 75:08eff6258e1b 275 }
ocomeni 75:08eff6258e1b 276
ocomeni 75:08eff6258e1b 277 /** This is called by Gap to notify the application we connected */
ocomeni 75:08eff6258e1b 278 //void SMDevice::on_connect(const Gap::ConnectionCallbackParams_t *connection_event);
ocomeni 75:08eff6258e1b 279
ocomeni 75:08eff6258e1b 280 /** This is called by Gap to notify the application we disconnected,
ocomeni 75:08eff6258e1b 281 * in our case it ends the demonstration. */
ocomeni 75:08eff6258e1b 282 void SMDevice::on_disconnect(const Gap::DisconnectionCallbackParams_t *event)
ocomeni 75:08eff6258e1b 283 {
ocomeni 103:7b566b522427 284 dbg_printf(LOG, "Disconnected\r\n");
ocomeni 77:0b505d1e15f4 285 #ifndef DEMO_BLE_SECURITY
ocomeni 103:7b566b522427 286 dbg_printf(LOG, "Restarting advertising...\r\n");
ocomeni 113:888e262ff0a9 287 _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
ocomeni 77:0b505d1e15f4 288 #else
ocomeni 75:08eff6258e1b 289 _event_queue.break_dispatch();
ocomeni 77:0b505d1e15f4 290 #endif
ocomeni 113:888e262ff0a9 291 isConnected = false;
ocomeni 75:08eff6258e1b 292 }
ocomeni 75:08eff6258e1b 293
ocomeni 75:08eff6258e1b 294 /** End demonstration unexpectedly. Called if timeout is reached during advertising,
ocomeni 75:08eff6258e1b 295 * scanning or connection initiation */
ocomeni 75:08eff6258e1b 296 void SMDevice::on_timeout(const Gap::TimeoutSource_t source)
ocomeni 75:08eff6258e1b 297 {
ocomeni 103:7b566b522427 298 dbg_printf(LOG, "Unexpected timeout - aborting\r\n");
ocomeni 75:08eff6258e1b 299 _event_queue.break_dispatch();
ocomeni 75:08eff6258e1b 300 }
ocomeni 75:08eff6258e1b 301
ocomeni 75:08eff6258e1b 302 /** Schedule processing of events from the BLE in the event queue. */
ocomeni 75:08eff6258e1b 303 void SMDevice::schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context)
ocomeni 75:08eff6258e1b 304 {
ocomeni 75:08eff6258e1b 305 _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents));
ocomeni 75:08eff6258e1b 306 };
ocomeni 75:08eff6258e1b 307
ocomeni 76:6afda865fbf8 308 /** Echo received data back */
ocomeni 76:6afda865fbf8 309 void SMDevice::EchoBleUartReceived()
ocomeni 76:6afda865fbf8 310 {
ocomeni 76:6afda865fbf8 311 uart->writeString(buffer);
ocomeni 76:6afda865fbf8 312 uart->writeString("\n"); //flushes uart output buffer and sends data
ocomeni 76:6afda865fbf8 313 }
ocomeni 76:6afda865fbf8 314
ocomeni 76:6afda865fbf8 315
ocomeni 79:a2187bbfa407 316 /** Send data aynchronously using BLE */
ocomeni 79:a2187bbfa407 317 void SMDevice::sendBLEUartData(char * str)
ocomeni 79:a2187bbfa407 318 {
ocomeni 113:888e262ff0a9 319 //Gap::GapState_t gapState = _ble.gap().getState();
ocomeni 113:888e262ff0a9 320 //Gap::GapState_t gapState = _ble.getGapState();
ocomeni 113:888e262ff0a9 321 //gapState.connected
ocomeni 113:888e262ff0a9 322 if(isConnected){
ocomeni 79:a2187bbfa407 323 uart->writeString(str);
ocomeni 79:a2187bbfa407 324 uart->writeString("\n"); //flushes uart output buffer and sends data
ocomeni 79:a2187bbfa407 325 }
ocomeni 113:888e262ff0a9 326 else
ocomeni 113:888e262ff0a9 327 {
ocomeni 113:888e262ff0a9 328 dbg_printf(LOG, "BLE not connected\r\n");
ocomeni 113:888e262ff0a9 329 }
ocomeni 79:a2187bbfa407 330 }
ocomeni 79:a2187bbfa407 331
ocomeni 79:a2187bbfa407 332
ocomeni 76:6afda865fbf8 333 /**
ocomeni 79:a2187bbfa407 334 * This callback allows the UARTService to receive updates.
ocomeni 76:6afda865fbf8 335 *
ocomeni 76:6afda865fbf8 336 * @param[in] params
ocomeni 76:6afda865fbf8 337 * Information about the characterisitc being updated.
ocomeni 76:6afda865fbf8 338 */
ocomeni 76:6afda865fbf8 339 void SMDevice::onDataWrittenCallback(const GattWriteCallbackParams *params) {
ocomeni 76:6afda865fbf8 340 if ((uart != NULL) && (params->handle == uart->getTXCharacteristicHandle())) {
ocomeni 76:6afda865fbf8 341 uint16_t bytesRead = params->len;
ocomeni 76:6afda865fbf8 342
ocomeni 103:7b566b522427 343 dbg_printf(LOG, "received %u bytes\n\r ", bytesRead);
ocomeni 76:6afda865fbf8 344
ocomeni 76:6afda865fbf8 345 if(bytesRead >= 255){
ocomeni 103:7b566b522427 346 dbg_printf(LOG, "Overflow command %u n\r ", bytesRead);
ocomeni 76:6afda865fbf8 347 bytesRead = 255;
ocomeni 76:6afda865fbf8 348 }
ocomeni 76:6afda865fbf8 349
ocomeni 76:6afda865fbf8 350 unsigned index = 0;
ocomeni 76:6afda865fbf8 351 for (; index < bytesRead; index++) {
ocomeni 76:6afda865fbf8 352 buffer[index] = params->data[index];
ocomeni 76:6afda865fbf8 353 }
ocomeni 76:6afda865fbf8 354
ocomeni 76:6afda865fbf8 355 buffer[index++] = 0;
ocomeni 76:6afda865fbf8 356
ocomeni 103:7b566b522427 357 dbg_printf(LOG, "Data : %s ",buffer);
ocomeni 103:7b566b522427 358 dbg_printf(LOG, "\r\n");
ocomeni 76:6afda865fbf8 359 /* start echo in 50 ms */
ocomeni 76:6afda865fbf8 360 _event_queue.call_in(50, this, &SMDevice::EchoBleUartReceived);
ocomeni 76:6afda865fbf8 361 //_event_queue.call(EchoBleUartReceived);
ocomeni 76:6afda865fbf8 362
ocomeni 76:6afda865fbf8 363 }
ocomeni 76:6afda865fbf8 364 }
ocomeni 79:a2187bbfa407 365
ocomeni 79:a2187bbfa407 366
ocomeni 79:a2187bbfa407 367
ocomeni 79:a2187bbfa407 368
ocomeni 75:08eff6258e1b 369 /** Blink LED to show we're running */
ocomeni 75:08eff6258e1b 370 void SMDevice::blink(void)
ocomeni 75:08eff6258e1b 371 {
ocomeni 75:08eff6258e1b 372 _led1 = !_led1;
ocomeni 75:08eff6258e1b 373 }
ocomeni 75:08eff6258e1b 374
ocomeni 75:08eff6258e1b 375
ocomeni 77:0b505d1e15f4 376 void SMDevice::reportGapState()
ocomeni 77:0b505d1e15f4 377 {
ocomeni 113:888e262ff0a9 378 //Gap::GapState_t gapState = _ble.gap().getState();
ocomeni 77:0b505d1e15f4 379 char connStr[20] = " Not Connected ";
ocomeni 77:0b505d1e15f4 380 char advStr[20] = " Not Advertising ";
ocomeni 113:888e262ff0a9 381 //char devName[20] = "";
ocomeni 113:888e262ff0a9 382 //if(gapState.advertising){
ocomeni 113:888e262ff0a9 383 if(_ble.gap().isAdvertisingActive(ble::LEGACY_ADVERTISING_HANDLE)){
ocomeni 77:0b505d1e15f4 384 strncpy(advStr, " Advertising ", 20);
ocomeni 77:0b505d1e15f4 385 }
ocomeni 113:888e262ff0a9 386 if(isConnected){
ocomeni 77:0b505d1e15f4 387 strncpy(connStr, " Connected ", 20);
ocomeni 77:0b505d1e15f4 388 }
ocomeni 103:7b566b522427 389 dbg_printf(LOG, "\n Advertising Status = %s\n Connection Status = %s\n", advStr, connStr);
ocomeni 77:0b505d1e15f4 390
ocomeni 77:0b505d1e15f4 391 }
ocomeni 77:0b505d1e15f4 392
ocomeni 77:0b505d1e15f4 393
ocomeni 75:08eff6258e1b 394 /** A peripheral device will advertise, accept the connection and request
ocomeni 75:08eff6258e1b 395 * a change in link security. */
ocomeni 118:8df0e9c2ee3f 396 SMDevicePeripheral::SMDevicePeripheral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address,
ocomeni 118:8df0e9c2ee3f 397 MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool,
ocomeni 118:8df0e9c2ee3f 398 Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue,
ocomeni 118:8df0e9c2ee3f 399 MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool,
ocomeni 118:8df0e9c2ee3f 400 Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue,
ocomeni 118:8df0e9c2ee3f 401 ble_config_t *ble_config)
ocomeni 118:8df0e9c2ee3f 402 : SMDevice(ble, event_queue, peer_address,
ocomeni 118:8df0e9c2ee3f 403 aT2BleDatamPool, aT2BleDataQueue,
ocomeni 118:8df0e9c2ee3f 404 ble2ATDatamPool, ble2ATDataQueue,
ocomeni 118:8df0e9c2ee3f 405 ble_config) { }
ocomeni 75:08eff6258e1b 406
ocomeni 75:08eff6258e1b 407 void SMDevicePeripheral::start()
ocomeni 75:08eff6258e1b 408 {
ocomeni 75:08eff6258e1b 409 /* Set up and start advertising */
ocomeni 75:08eff6258e1b 410
ocomeni 75:08eff6258e1b 411 ble_error_t error;
ocomeni 75:08eff6258e1b 412 GapAdvertisingData advertising_data;
ocomeni 75:08eff6258e1b 413
ocomeni 75:08eff6258e1b 414 /* add advertising flags */
ocomeni 75:08eff6258e1b 415 advertising_data.addFlags(GapAdvertisingData::LE_GENERAL_DISCOVERABLE
ocomeni 75:08eff6258e1b 416 | GapAdvertisingData::BREDR_NOT_SUPPORTED);
ocomeni 75:08eff6258e1b 417
ocomeni 75:08eff6258e1b 418 /* add device name */
ocomeni 75:08eff6258e1b 419 advertising_data.addData(
ocomeni 75:08eff6258e1b 420 GapAdvertisingData::COMPLETE_LOCAL_NAME,
ocomeni 116:2296cf274661 421 (const uint8_t *)ble_config->deviceName,
ocomeni 116:2296cf274661 422 strlen(ble_config->deviceName)
ocomeni 76:6afda865fbf8 423 );
ocomeni 76:6afda865fbf8 424 /* Setup primary service */
ocomeni 76:6afda865fbf8 425 uart = new UARTService(_ble);
ocomeni 76:6afda865fbf8 426
ocomeni 75:08eff6258e1b 427
ocomeni 76:6afda865fbf8 428 /* add device name */
ocomeni 76:6afda865fbf8 429 error = advertising_data.addData(
ocomeni 76:6afda865fbf8 430 GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS ,
ocomeni 76:6afda865fbf8 431 (const uint8_t *)UARTServiceUUID_reversed,
ocomeni 76:6afda865fbf8 432 sizeof(sizeof(UARTServiceUUID_reversed))
ocomeni 76:6afda865fbf8 433 );
ocomeni 76:6afda865fbf8 434 /* setup advertising */
ocomeni 76:6afda865fbf8 435 //error = _ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
ocomeni 76:6afda865fbf8 436 //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
ocomeni 76:6afda865fbf8 437 //error = _ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
ocomeni 76:6afda865fbf8 438 /* set up the services that can be discovered */
ocomeni 76:6afda865fbf8 439 //error = _ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
ocomeni 76:6afda865fbf8 440
ocomeni 76:6afda865fbf8 441
ocomeni 76:6afda865fbf8 442 //error = _ble.gap().setAdvertisingPayload(advertising_data);
ocomeni 75:08eff6258e1b 443
ocomeni 75:08eff6258e1b 444 if (error) {
ocomeni 103:7b566b522427 445 dbg_printf(LOG, "Error during Gap::setAdvertisingPayload\r\n");
ocomeni 75:08eff6258e1b 446 return;
ocomeni 75:08eff6258e1b 447 }
ocomeni 75:08eff6258e1b 448
ocomeni 75:08eff6258e1b 449 /* advertise to everyone */
ocomeni 75:08eff6258e1b 450 _ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
ocomeni 75:08eff6258e1b 451 /* how many milliseconds between advertisements, lower interval
ocomeni 75:08eff6258e1b 452 * increases the chances of being seen at the cost of more power */
ocomeni 76:6afda865fbf8 453 //_ble.gap().setAdvertisingInterval(20);
ocomeni 76:6afda865fbf8 454 //_ble.gap().setAdvertisingTimeout(0);
ocomeni 116:2296cf274661 455 _ble.gap().setAdvertisingInterval(ble_config->advInterval); /* setting in ble_config */
ocomeni 116:2296cf274661 456 _ble.gap().setAdvertisingTimeout(ble_config->advTimeout); /* setting in ble_config */
ocomeni 75:08eff6258e1b 457
ocomeni 113:888e262ff0a9 458 error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
ocomeni 75:08eff6258e1b 459
ocomeni 75:08eff6258e1b 460 if (error) {
ocomeni 103:7b566b522427 461 dbg_printf(LOG, "Error during Gap::startAdvertising.\r\n");
ocomeni 75:08eff6258e1b 462 return;
ocomeni 75:08eff6258e1b 463 }
ocomeni 75:08eff6258e1b 464
ocomeni 103:7b566b522427 465 dbg_printf(LOG, "Please connect to device\r\n");
ocomeni 75:08eff6258e1b 466
ocomeni 75:08eff6258e1b 467 /** This tells the stack to generate a pairingRequest event
ocomeni 75:08eff6258e1b 468 * which will require this application to respond before pairing
ocomeni 75:08eff6258e1b 469 * can proceed. Setting it to false will automatically accept
ocomeni 75:08eff6258e1b 470 * pairing. */
ocomeni 75:08eff6258e1b 471 _ble.securityManager().setPairingRequestAuthorisation(true);
ocomeni 75:08eff6258e1b 472 }
ocomeni 75:08eff6258e1b 473
ocomeni 75:08eff6258e1b 474 /** This is called by Gap to notify the application we connected,
ocomeni 75:08eff6258e1b 475 * in our case it immediately requests a change in link security */
ocomeni 75:08eff6258e1b 476 void SMDevicePeripheral::on_connect(const Gap::ConnectionCallbackParams_t *connection_event)
ocomeni 75:08eff6258e1b 477 {
ocomeni 75:08eff6258e1b 478 ble_error_t error;
ocomeni 75:08eff6258e1b 479
ocomeni 75:08eff6258e1b 480 /* remember the device that connects to us now so we can connect to it
ocomeni 75:08eff6258e1b 481 * during the next demonstration */
ocomeni 75:08eff6258e1b 482 memcpy(_peer_address, connection_event->peerAddr, sizeof(_peer_address));
ocomeni 75:08eff6258e1b 483
ocomeni 103:7b566b522427 484 dbg_printf(LOG, "Connected to: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
ocomeni 75:08eff6258e1b 485 _peer_address[5], _peer_address[4], _peer_address[3],
ocomeni 75:08eff6258e1b 486 _peer_address[2], _peer_address[1], _peer_address[0]);
ocomeni 75:08eff6258e1b 487
ocomeni 75:08eff6258e1b 488 /* store the handle for future Security Manager requests */
ocomeni 75:08eff6258e1b 489 _handle = connection_event->handle;
ocomeni 75:08eff6258e1b 490
ocomeni 75:08eff6258e1b 491 /* Request a change in link security. This will be done
ocomeni 75:08eff6258e1b 492 * indirectly by asking the master of the connection to
ocomeni 75:08eff6258e1b 493 * change it. Depending on circumstances different actions
ocomeni 75:08eff6258e1b 494 * may be taken by the master which will trigger events
ocomeni 75:08eff6258e1b 495 * which the applications should deal with. */
ocomeni 75:08eff6258e1b 496 error = _ble.securityManager().setLinkSecurity(
ocomeni 75:08eff6258e1b 497 _handle,
ocomeni 75:08eff6258e1b 498 SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM
ocomeni 75:08eff6258e1b 499 );
ocomeni 75:08eff6258e1b 500
ocomeni 75:08eff6258e1b 501 if (error) {
ocomeni 103:7b566b522427 502 dbg_printf(LOG, "Error during SM::setLinkSecurity %d\r\n", error);
ocomeni 75:08eff6258e1b 503 return;
ocomeni 75:08eff6258e1b 504 }
ocomeni 103:7b566b522427 505 dbg_printf(LOG, "SM::setLinkSecurity setup\r\n");
ocomeni 113:888e262ff0a9 506 isConnected = true;
ocomeni 75:08eff6258e1b 507 }
ocomeni 75:08eff6258e1b 508
ocomeni 77:0b505d1e15f4 509 void SMDevicePeripheral::stopAdvertising()
ocomeni 77:0b505d1e15f4 510 {
ocomeni 77:0b505d1e15f4 511 if (_ble.hasInitialized()) {
ocomeni 77:0b505d1e15f4 512 ble_error_t error;
ocomeni 113:888e262ff0a9 513 error = _ble.gap().stopAdvertising(ble::LEGACY_ADVERTISING_HANDLE);;
ocomeni 77:0b505d1e15f4 514 if(error){
ocomeni 103:7b566b522427 515 dbg_printf(LOG, " Error stopping advertising...\r\n");
ocomeni 77:0b505d1e15f4 516 return;
ocomeni 77:0b505d1e15f4 517 }
ocomeni 103:7b566b522427 518 dbg_printf(LOG, "Stopping advertising...\r\n");
ocomeni 77:0b505d1e15f4 519 //_event_queue.break_dispatch();
ocomeni 77:0b505d1e15f4 520 }
ocomeni 77:0b505d1e15f4 521 }
ocomeni 77:0b505d1e15f4 522 void SMDevicePeripheral::startAdvertising()
ocomeni 77:0b505d1e15f4 523 {
ocomeni 77:0b505d1e15f4 524 if (_ble.hasInitialized()) {
ocomeni 77:0b505d1e15f4 525 ble_error_t error;
ocomeni 113:888e262ff0a9 526 error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
ocomeni 77:0b505d1e15f4 527 if(error){
ocomeni 103:7b566b522427 528 dbg_printf(LOG, " Error Restarting advertising...\r\n");
ocomeni 77:0b505d1e15f4 529 return;
ocomeni 77:0b505d1e15f4 530 }
ocomeni 103:7b566b522427 531 dbg_printf(LOG, "Restarting advertising...\r\n");
ocomeni 77:0b505d1e15f4 532 //_event_queue.break_dispatch();
ocomeni 77:0b505d1e15f4 533 }
ocomeni 77:0b505d1e15f4 534 }
ocomeni 77:0b505d1e15f4 535
ocomeni 77:0b505d1e15f4 536
ocomeni 77:0b505d1e15f4 537
ocomeni 75:08eff6258e1b 538 /** A central device will scan, connect to a peer and request pairing. */
ocomeni 75:08eff6258e1b 539
ocomeni 118:8df0e9c2ee3f 540 SMDeviceCentral::SMDeviceCentral(BLE &ble, events::EventQueue &event_queue, BLEProtocol::AddressBytes_t &peer_address,
ocomeni 118:8df0e9c2ee3f 541 MemoryPool<at_ble_msg_t, PQDSZ_BLE> *aT2BleDatamPool,
ocomeni 118:8df0e9c2ee3f 542 Queue<at_ble_msg_t, PQDSZ_BLE> *aT2BleDataQueue,
ocomeni 118:8df0e9c2ee3f 543 MemoryPool<ble_at_msg_t, PQDSZ_BLE> *ble2ATDatamPool,
ocomeni 118:8df0e9c2ee3f 544 Queue<ble_at_msg_t, PQDSZ_BLE> *ble2ATDataQueue,
ocomeni 118:8df0e9c2ee3f 545 ble_config_t *ble_config)
ocomeni 118:8df0e9c2ee3f 546 : SMDevice(ble, event_queue, peer_address,
ocomeni 118:8df0e9c2ee3f 547 aT2BleDatamPool, aT2BleDataQueue,
ocomeni 118:8df0e9c2ee3f 548 ble2ATDatamPool, ble2ATDataQueue,
ocomeni 118:8df0e9c2ee3f 549 ble_config) { };
ocomeni 75:08eff6258e1b 550
ocomeni 75:08eff6258e1b 551 void SMDeviceCentral::start()
ocomeni 75:08eff6258e1b 552 {
ocomeni 75:08eff6258e1b 553 /* start scanning and attach a callback that will handle advertisements
ocomeni 75:08eff6258e1b 554 * and scan requests responses */
ocomeni 75:08eff6258e1b 555 ble_error_t error = _ble.gap().startScan(this, &SMDeviceCentral::on_scan);
ocomeni 75:08eff6258e1b 556
ocomeni 103:7b566b522427 557 dbg_printf(LOG, "Please advertise\r\n");
ocomeni 75:08eff6258e1b 558
ocomeni 103:7b566b522427 559 dbg_printf(LOG, "Scanning for: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
ocomeni 75:08eff6258e1b 560 _peer_address[5], _peer_address[4], _peer_address[3],
ocomeni 75:08eff6258e1b 561 _peer_address[2], _peer_address[1], _peer_address[0]);
ocomeni 75:08eff6258e1b 562
ocomeni 75:08eff6258e1b 563 if (error) {
ocomeni 103:7b566b522427 564 dbg_printf(LOG, "Error during Gap::startScan %d\r\n", error);
ocomeni 75:08eff6258e1b 565 return;
ocomeni 75:08eff6258e1b 566 }
ocomeni 75:08eff6258e1b 567 }
ocomeni 75:08eff6258e1b 568
ocomeni 75:08eff6258e1b 569 /** Look at scan payload to find a peer device and connect to it */
ocomeni 75:08eff6258e1b 570 void SMDeviceCentral::on_scan(const Gap::AdvertisementCallbackParams_t *params)
ocomeni 75:08eff6258e1b 571 {
ocomeni 75:08eff6258e1b 572 /* don't bother with analysing scan result if we're already connecting */
ocomeni 75:08eff6258e1b 573 if (_is_connecting) {
ocomeni 75:08eff6258e1b 574 return;
ocomeni 75:08eff6258e1b 575 }
ocomeni 75:08eff6258e1b 576
ocomeni 75:08eff6258e1b 577 /* connect to the same device that connected to us */
ocomeni 75:08eff6258e1b 578 if (memcmp(params->peerAddr, _peer_address, sizeof(_peer_address)) == 0) {
ocomeni 75:08eff6258e1b 579
ocomeni 75:08eff6258e1b 580 ble_error_t error = _ble.gap().connect(
ocomeni 75:08eff6258e1b 581 params->peerAddr, params->peerAddrType,
ocomeni 75:08eff6258e1b 582 NULL, NULL
ocomeni 75:08eff6258e1b 583 );
ocomeni 75:08eff6258e1b 584
ocomeni 75:08eff6258e1b 585 if (error) {
ocomeni 103:7b566b522427 586 dbg_printf(LOG, "Error during Gap::connect %d\r\n", error);
ocomeni 75:08eff6258e1b 587 return;
ocomeni 75:08eff6258e1b 588 }
ocomeni 75:08eff6258e1b 589
ocomeni 103:7b566b522427 590 dbg_printf(LOG, "Connecting... ");
ocomeni 75:08eff6258e1b 591
ocomeni 75:08eff6258e1b 592 /* we may have already scan events waiting
ocomeni 75:08eff6258e1b 593 * to be processed so we need to remember
ocomeni 75:08eff6258e1b 594 * that we are already connecting and ignore them */
ocomeni 75:08eff6258e1b 595 _is_connecting = true;
ocomeni 75:08eff6258e1b 596
ocomeni 75:08eff6258e1b 597 return;
ocomeni 75:08eff6258e1b 598 }
ocomeni 75:08eff6258e1b 599 }
ocomeni 75:08eff6258e1b 600
ocomeni 75:08eff6258e1b 601 /** This is called by Gap to notify the application we connected,
ocomeni 75:08eff6258e1b 602 * in our case it immediately request pairing */
ocomeni 75:08eff6258e1b 603 void SMDeviceCentral::on_connect(const Gap::ConnectionCallbackParams_t *connection_event)
ocomeni 75:08eff6258e1b 604 {
ocomeni 75:08eff6258e1b 605 ble_error_t error;
ocomeni 75:08eff6258e1b 606
ocomeni 75:08eff6258e1b 607 /* store the handle for future Security Manager requests */
ocomeni 75:08eff6258e1b 608 _handle = connection_event->handle;
ocomeni 75:08eff6258e1b 609
ocomeni 75:08eff6258e1b 610 /* in this example the local device is the master so we request pairing */
ocomeni 75:08eff6258e1b 611 error = _ble.securityManager().requestPairing(_handle);
ocomeni 75:08eff6258e1b 612
ocomeni 103:7b566b522427 613 dbg_printf(LOG, "Connected\r\n");
ocomeni 75:08eff6258e1b 614
ocomeni 75:08eff6258e1b 615 if (error) {
ocomeni 103:7b566b522427 616 dbg_printf(LOG, "Error during SM::requestPairing %d\r\n", error);
ocomeni 75:08eff6258e1b 617 return;
ocomeni 75:08eff6258e1b 618 }
ocomeni 75:08eff6258e1b 619
ocomeni 75:08eff6258e1b 620 /* upon pairing success the application will disconnect */
ocomeni 75:08eff6258e1b 621 }
ocomeni 75:08eff6258e1b 622
ocomeni 75:08eff6258e1b 623
ocomeni 75:08eff6258e1b 624
ocomeni 75:08eff6258e1b 625 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
ocomeni 75:08eff6258e1b 626 bool create_filesystem()
ocomeni 75:08eff6258e1b 627 {
ocomeni 75:08eff6258e1b 628 static LittleFileSystem fs("fs");
ocomeni 75:08eff6258e1b 629
ocomeni 75:08eff6258e1b 630 /* replace this with any physical block device your board supports (like an SD card) */
ocomeni 75:08eff6258e1b 631 static HeapBlockDevice bd(4096, 256);
ocomeni 75:08eff6258e1b 632
ocomeni 75:08eff6258e1b 633 int err = bd.init();
ocomeni 75:08eff6258e1b 634
ocomeni 75:08eff6258e1b 635 if (err) {
ocomeni 75:08eff6258e1b 636 return false;
ocomeni 75:08eff6258e1b 637 }
ocomeni 75:08eff6258e1b 638
ocomeni 75:08eff6258e1b 639 err = bd.erase(0, bd.size());
ocomeni 75:08eff6258e1b 640
ocomeni 75:08eff6258e1b 641 if (err) {
ocomeni 75:08eff6258e1b 642 return false;
ocomeni 75:08eff6258e1b 643 }
ocomeni 75:08eff6258e1b 644
ocomeni 75:08eff6258e1b 645 err = fs.mount(&bd);
ocomeni 75:08eff6258e1b 646
ocomeni 75:08eff6258e1b 647 if (err) {
ocomeni 75:08eff6258e1b 648 /* Reformat if we can't mount the filesystem */
ocomeni 103:7b566b522427 649 dbg_printf(LOG, "No filesystem found, formatting...\r\n");
ocomeni 75:08eff6258e1b 650
ocomeni 75:08eff6258e1b 651 err = fs.reformat(&bd);
ocomeni 75:08eff6258e1b 652
ocomeni 75:08eff6258e1b 653 if (err) {
ocomeni 75:08eff6258e1b 654 return false;
ocomeni 75:08eff6258e1b 655 }
ocomeni 75:08eff6258e1b 656 }
ocomeni 75:08eff6258e1b 657
ocomeni 75:08eff6258e1b 658 return true;
ocomeni 75:08eff6258e1b 659 }
ocomeni 75:08eff6258e1b 660 #endif //MBED_CONF_APP_FILESYSTEM_SUPPORT
ocomeni 75:08eff6258e1b 661 #ifdef BLE_SECURITY_MAIN
ocomeni 75:08eff6258e1b 662 int main()
ocomeni 75:08eff6258e1b 663 {
ocomeni 75:08eff6258e1b 664 BLE& ble = BLE::Instance();
ocomeni 75:08eff6258e1b 665 events::EventQueue queue;
ocomeni 75:08eff6258e1b 666
ocomeni 75:08eff6258e1b 667 #if MBED_CONF_APP_FILESYSTEM_SUPPORT
ocomeni 75:08eff6258e1b 668 /* if filesystem creation fails or there is no filesystem the security manager
ocomeni 75:08eff6258e1b 669 * will fallback to storing the security database in memory */
ocomeni 75:08eff6258e1b 670 if (!create_filesystem()) {
ocomeni 103:7b566b522427 671 dbg_printf(LOG, "Filesystem creation failed, will use memory storage\r\n");
ocomeni 75:08eff6258e1b 672 }
ocomeni 75:08eff6258e1b 673 #endif
ocomeni 75:08eff6258e1b 674
ocomeni 75:08eff6258e1b 675 while(1) {
ocomeni 75:08eff6258e1b 676 {
ocomeni 103:7b566b522427 677 dbg_printf(LOG, "\r\n PERIPHERAL \r\n\r\n");
ocomeni 75:08eff6258e1b 678 SMDevicePeripheral peripheral(ble, queue, peer_address);
ocomeni 75:08eff6258e1b 679 peripheral.run();
ocomeni 75:08eff6258e1b 680 }
ocomeni 75:08eff6258e1b 681
ocomeni 75:08eff6258e1b 682 {
ocomeni 103:7b566b522427 683 dbg_printf(LOG, "\r\n CENTRAL \r\n\r\n");
ocomeni 75:08eff6258e1b 684 SMDeviceCentral central(ble, queue, peer_address);
ocomeni 75:08eff6258e1b 685 central.run();
ocomeni 75:08eff6258e1b 686 }
ocomeni 75:08eff6258e1b 687 }
ocomeni 75:08eff6258e1b 688
ocomeni 75:08eff6258e1b 689 return 0;
ocomeni 75:08eff6258e1b 690 }
ocomeni 75:08eff6258e1b 691 #endif