High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Committer:
Vincent Coubard
Date:
Wed Sep 14 14:17:52 2016 +0100
Branch:
2f55eed1fdde06fdabfb66d41ce6cd14e280978f
Revision:
1201:9b71aac42d14
Parent:
1135:22aada733dbd
Child:
1203:d4f1ef46d97b
Sync with 2f55eed1fdde06fdabfb66d41ce6cd14e280978f

2016-06-06 09:36:57+01:00: Vincent Coubard
Add an interface which allows user code to customise the way BLE events
are processed.

The mechanism is quite simple:
* user code can process all events pending in the internal BLE stack by
calling the function BLE::processEvent.
* user code can be notified when an event become available and the event
stack has to be processed. The notification is issued by the port of
mbed BLE.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Vincent Coubard 1201:9b71aac42d14 1 /* mbed Microcontroller Library
Vincent Coubard 1201:9b71aac42d14 2 * Copyright (c) 2006-2013 ARM Limited
Vincent Coubard 1201:9b71aac42d14 3 *
Vincent Coubard 1201:9b71aac42d14 4 * Licensed under the Apache License, Version 2.0 (the "License");
Vincent Coubard 1201:9b71aac42d14 5 * you may not use this file except in compliance with the License.
Vincent Coubard 1201:9b71aac42d14 6 * You may obtain a copy of the License at
Vincent Coubard 1201:9b71aac42d14 7 *
Vincent Coubard 1201:9b71aac42d14 8 * http://www.apache.org/licenses/LICENSE-2.0
Vincent Coubard 1201:9b71aac42d14 9 *
Vincent Coubard 1201:9b71aac42d14 10 * Unless required by applicable law or agreed to in writing, software
Vincent Coubard 1201:9b71aac42d14 11 * distributed under the License is distributed on an "AS IS" BASIS,
Vincent Coubard 1201:9b71aac42d14 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Vincent Coubard 1201:9b71aac42d14 13 * See the License for the specific language governing permissions and
Vincent Coubard 1201:9b71aac42d14 14 * limitations under the License.
Vincent Coubard 1201:9b71aac42d14 15 */
Vincent Coubard 1201:9b71aac42d14 16
Vincent Coubard 1201:9b71aac42d14 17 #include "ble/BLE.h"
Vincent Coubard 1201:9b71aac42d14 18 #include "ble/BLEInstanceBase.h"
Vincent Coubard 1201:9b71aac42d14 19
Vincent Coubard 1201:9b71aac42d14 20 #if defined(TARGET_OTA_ENABLED)
Vincent Coubard 1201:9b71aac42d14 21 #include "ble/services/DFUService.h"
Vincent Coubard 1201:9b71aac42d14 22 #endif
Vincent Coubard 1201:9b71aac42d14 23
Vincent Coubard 1201:9b71aac42d14 24 #ifdef YOTTA_CFG_MBED_OS
Vincent Coubard 1201:9b71aac42d14 25 #include <minar/minar.h>
Vincent Coubard 1201:9b71aac42d14 26 #endif
Vincent Coubard 1201:9b71aac42d14 27
Vincent Coubard 1201:9b71aac42d14 28 ble_error_t
Vincent Coubard 1201:9b71aac42d14 29 BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext*> callback)
Vincent Coubard 1201:9b71aac42d14 30 {
Vincent Coubard 1201:9b71aac42d14 31 ble_error_t err = transport->init(instanceID, callback);
Vincent Coubard 1201:9b71aac42d14 32 if (err != BLE_ERROR_NONE) {
Vincent Coubard 1201:9b71aac42d14 33 return err;
Vincent Coubard 1201:9b71aac42d14 34 }
Vincent Coubard 1201:9b71aac42d14 35
Vincent Coubard 1201:9b71aac42d14 36 /* Platforms enabled for DFU should introduce the DFU Service into
Vincent Coubard 1201:9b71aac42d14 37 * applications automatically. */
Vincent Coubard 1201:9b71aac42d14 38 #if defined(TARGET_OTA_ENABLED)
Vincent Coubard 1201:9b71aac42d14 39 static DFUService dfu(*this); // defined static so that the object remains alive
Vincent Coubard 1201:9b71aac42d14 40 #endif // TARGET_OTA_ENABLED
Vincent Coubard 1201:9b71aac42d14 41
Vincent Coubard 1201:9b71aac42d14 42 return BLE_ERROR_NONE;
Vincent Coubard 1201:9b71aac42d14 43 }
Vincent Coubard 1201:9b71aac42d14 44
Vincent Coubard 1201:9b71aac42d14 45 /**
Vincent Coubard 1201:9b71aac42d14 46 * BLE::Instance() and BLE constructor rely upon a static array of initializers
Vincent Coubard 1201:9b71aac42d14 47 * to create actual BLE transport instances. A description of these instances
Vincent Coubard 1201:9b71aac42d14 48 * and initializers is supposed to be put in some .json file contributing to
Vincent Coubard 1201:9b71aac42d14 49 * yotta's configuration (typically in the target definition described by
Vincent Coubard 1201:9b71aac42d14 50 * target.json). Here's a sample:
Vincent Coubard 1201:9b71aac42d14 51 *
Vincent Coubard 1201:9b71aac42d14 52 * "config": {
Vincent Coubard 1201:9b71aac42d14 53 * ...
Vincent Coubard 1201:9b71aac42d14 54 * "ble_instances": {
Vincent Coubard 1201:9b71aac42d14 55 * "count": 1,
Vincent Coubard 1201:9b71aac42d14 56 * "0" : {
Vincent Coubard 1201:9b71aac42d14 57 * "initializer" : "createBLEInstance"
Vincent Coubard 1201:9b71aac42d14 58 * }
Vincent Coubard 1201:9b71aac42d14 59 * }
Vincent Coubard 1201:9b71aac42d14 60 * ...
Vincent Coubard 1201:9b71aac42d14 61 * }
Vincent Coubard 1201:9b71aac42d14 62 *
Vincent Coubard 1201:9b71aac42d14 63 * The following macros result in translating the above config into a static
Vincent Coubard 1201:9b71aac42d14 64 * array: instanceConstructors.
Vincent Coubard 1201:9b71aac42d14 65 */
Vincent Coubard 1201:9b71aac42d14 66 #ifdef YOTTA_CFG_BLE_INSTANCES_COUNT
Vincent Coubard 1201:9b71aac42d14 67 #define CONCATENATE(A, B) A ## B
Vincent Coubard 1201:9b71aac42d14 68 #define EXPAND(X) X /* this adds a level of indirection needed to allow macro-expansion following a token-paste operation (see use of CONCATENATE() below). */
Vincent Coubard 1201:9b71aac42d14 69
Vincent Coubard 1201:9b71aac42d14 70 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER
Vincent Coubard 1201:9b71aac42d14 71 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER
Vincent Coubard 1201:9b71aac42d14 72 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER
Vincent Coubard 1201:9b71aac42d14 73 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER
Vincent Coubard 1201:9b71aac42d14 74 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER
Vincent Coubard 1201:9b71aac42d14 75 /* ... add more of the above if ever needed */
Vincent Coubard 1201:9b71aac42d14 76
Vincent Coubard 1201:9b71aac42d14 77 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N))
Vincent Coubard 1201:9b71aac42d14 78 #elif !defined(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS)
Vincent Coubard 1201:9b71aac42d14 79 /*
Vincent Coubard 1201:9b71aac42d14 80 * The following applies when building without yotta. By default BLE_API provides
Vincent Coubard 1201:9b71aac42d14 81 * a trivial initializer list containing a single constructor: createBLEInstance.
Vincent Coubard 1201:9b71aac42d14 82 * This may be overridden.
Vincent Coubard 1201:9b71aac42d14 83 */
Vincent Coubard 1201:9b71aac42d14 84 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS createBLEInstance
Vincent Coubard 1201:9b71aac42d14 85 #endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */
Vincent Coubard 1201:9b71aac42d14 86
Vincent Coubard 1201:9b71aac42d14 87 typedef BLEInstanceBase *(*InstanceConstructor_t)(void);
Vincent Coubard 1201:9b71aac42d14 88 static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = {
Vincent Coubard 1201:9b71aac42d14 89 #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
Vincent Coubard 1201:9b71aac42d14 90 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS
Vincent Coubard 1201:9b71aac42d14 91 #else
Vincent Coubard 1201:9b71aac42d14 92 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT)
Vincent Coubard 1201:9b71aac42d14 93 #endif
Vincent Coubard 1201:9b71aac42d14 94 };
Vincent Coubard 1201:9b71aac42d14 95
Vincent Coubard 1201:9b71aac42d14 96 BLE &
Vincent Coubard 1201:9b71aac42d14 97 BLE::Instance(InstanceID_t id)
Vincent Coubard 1201:9b71aac42d14 98 {
Vincent Coubard 1201:9b71aac42d14 99 static BLE *singletons[NUM_INSTANCES];
Vincent Coubard 1201:9b71aac42d14 100 if (id < NUM_INSTANCES) {
Vincent Coubard 1201:9b71aac42d14 101 if (singletons[id] == NULL) {
Vincent Coubard 1201:9b71aac42d14 102 singletons[id] = new BLE(id); /* This object will never be freed. */
Vincent Coubard 1201:9b71aac42d14 103 }
Vincent Coubard 1201:9b71aac42d14 104
Vincent Coubard 1201:9b71aac42d14 105 return *singletons[id];
Vincent Coubard 1201:9b71aac42d14 106 }
Vincent Coubard 1201:9b71aac42d14 107
Vincent Coubard 1201:9b71aac42d14 108 /* we come here only in the case of a bad interfaceID. */
Vincent Coubard 1201:9b71aac42d14 109 static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */);
Vincent Coubard 1201:9b71aac42d14 110 return badSingleton;
Vincent Coubard 1201:9b71aac42d14 111 }
Vincent Coubard 1201:9b71aac42d14 112
Vincent Coubard 1201:9b71aac42d14 113 #ifdef YOTTA_CFG_MBED_OS
Vincent Coubard 1201:9b71aac42d14 114 void defaultSchedulingCallback(BLE::OnEventsToProcessCallbackContext* params) {
Vincent Coubard 1201:9b71aac42d14 115 minar::Scheduler::postCallback(&params->ble, &BLE::processEvents);
Vincent Coubard 1201:9b71aac42d14 116 }
Vincent Coubard 1201:9b71aac42d14 117 #else
Vincent Coubard 1201:9b71aac42d14 118 #define defaultSchedulingCallback NULL
Vincent Coubard 1201:9b71aac42d14 119 #endif
Vincent Coubard 1201:9b71aac42d14 120
Vincent Coubard 1201:9b71aac42d14 121
Vincent Coubard 1201:9b71aac42d14 122 BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport(),
Vincent Coubard 1201:9b71aac42d14 123 whenEventsToProcess(defaultSchedulingCallback)
Vincent Coubard 1201:9b71aac42d14 124 {
Vincent Coubard 1201:9b71aac42d14 125 static BLEInstanceBase *transportInstances[NUM_INSTANCES];
Vincent Coubard 1201:9b71aac42d14 126
Vincent Coubard 1201:9b71aac42d14 127 if (instanceID < NUM_INSTANCES) {
Vincent Coubard 1201:9b71aac42d14 128 if (!transportInstances[instanceID]) {
Vincent Coubard 1201:9b71aac42d14 129 transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */
Vincent Coubard 1201:9b71aac42d14 130 }
Vincent Coubard 1201:9b71aac42d14 131 transport = transportInstances[instanceID];
Vincent Coubard 1201:9b71aac42d14 132 } else {
Vincent Coubard 1201:9b71aac42d14 133 transport = NULL;
Vincent Coubard 1201:9b71aac42d14 134 }
Vincent Coubard 1201:9b71aac42d14 135 }
Vincent Coubard 1201:9b71aac42d14 136
Vincent Coubard 1201:9b71aac42d14 137 bool BLE::hasInitialized(void) const
Vincent Coubard 1201:9b71aac42d14 138 {
Vincent Coubard 1201:9b71aac42d14 139 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 140 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 141 }
Vincent Coubard 1201:9b71aac42d14 142
Vincent Coubard 1201:9b71aac42d14 143 return transport->hasInitialized();
Vincent Coubard 1201:9b71aac42d14 144 }
Vincent Coubard 1201:9b71aac42d14 145
Vincent Coubard 1201:9b71aac42d14 146 ble_error_t BLE::shutdown(void)
Vincent Coubard 1201:9b71aac42d14 147 {
Vincent Coubard 1201:9b71aac42d14 148 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 149 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 150 }
Vincent Coubard 1201:9b71aac42d14 151
Vincent Coubard 1201:9b71aac42d14 152 return transport->shutdown();
Vincent Coubard 1201:9b71aac42d14 153 }
Vincent Coubard 1201:9b71aac42d14 154
Vincent Coubard 1201:9b71aac42d14 155 const char *BLE::getVersion(void)
Vincent Coubard 1201:9b71aac42d14 156 {
Vincent Coubard 1201:9b71aac42d14 157 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 158 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 159 }
Vincent Coubard 1201:9b71aac42d14 160
Vincent Coubard 1201:9b71aac42d14 161 return transport->getVersion();
Vincent Coubard 1201:9b71aac42d14 162 }
Vincent Coubard 1201:9b71aac42d14 163
Vincent Coubard 1201:9b71aac42d14 164 const Gap &BLE::gap() const
Vincent Coubard 1201:9b71aac42d14 165 {
Vincent Coubard 1201:9b71aac42d14 166 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 167 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 168 }
Vincent Coubard 1201:9b71aac42d14 169
Vincent Coubard 1201:9b71aac42d14 170 return transport->getGap();
Vincent Coubard 1201:9b71aac42d14 171 }
Vincent Coubard 1201:9b71aac42d14 172
Vincent Coubard 1201:9b71aac42d14 173 Gap &BLE::gap()
Vincent Coubard 1201:9b71aac42d14 174 {
Vincent Coubard 1201:9b71aac42d14 175 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 176 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 177 }
Vincent Coubard 1201:9b71aac42d14 178
Vincent Coubard 1201:9b71aac42d14 179 return transport->getGap();
Vincent Coubard 1201:9b71aac42d14 180 }
Vincent Coubard 1201:9b71aac42d14 181
Vincent Coubard 1201:9b71aac42d14 182 const GattServer& BLE::gattServer() const
Vincent Coubard 1201:9b71aac42d14 183 {
Vincent Coubard 1201:9b71aac42d14 184 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 185 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 186 }
Vincent Coubard 1201:9b71aac42d14 187
Vincent Coubard 1201:9b71aac42d14 188 return transport->getGattServer();
Vincent Coubard 1201:9b71aac42d14 189 }
Vincent Coubard 1201:9b71aac42d14 190
Vincent Coubard 1201:9b71aac42d14 191 GattServer& BLE::gattServer()
Vincent Coubard 1201:9b71aac42d14 192 {
Vincent Coubard 1201:9b71aac42d14 193 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 194 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 195 }
Vincent Coubard 1201:9b71aac42d14 196
Vincent Coubard 1201:9b71aac42d14 197 return transport->getGattServer();
Vincent Coubard 1201:9b71aac42d14 198 }
Vincent Coubard 1201:9b71aac42d14 199
Vincent Coubard 1201:9b71aac42d14 200 const GattClient& BLE::gattClient() const
Vincent Coubard 1201:9b71aac42d14 201 {
Vincent Coubard 1201:9b71aac42d14 202 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 203 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 204 }
Vincent Coubard 1201:9b71aac42d14 205
Vincent Coubard 1201:9b71aac42d14 206 return transport->getGattClient();
Vincent Coubard 1201:9b71aac42d14 207 }
Vincent Coubard 1201:9b71aac42d14 208
Vincent Coubard 1201:9b71aac42d14 209 GattClient& BLE::gattClient()
Vincent Coubard 1201:9b71aac42d14 210 {
Vincent Coubard 1201:9b71aac42d14 211 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 212 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 213 }
Vincent Coubard 1201:9b71aac42d14 214
Vincent Coubard 1201:9b71aac42d14 215 return transport->getGattClient();
Vincent Coubard 1201:9b71aac42d14 216 }
Vincent Coubard 1201:9b71aac42d14 217
Vincent Coubard 1201:9b71aac42d14 218 const SecurityManager& BLE::securityManager() const
Vincent Coubard 1201:9b71aac42d14 219 {
Vincent Coubard 1201:9b71aac42d14 220 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 221 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 222 }
Vincent Coubard 1201:9b71aac42d14 223
Vincent Coubard 1201:9b71aac42d14 224 return transport->getSecurityManager();
Vincent Coubard 1201:9b71aac42d14 225 }
Vincent Coubard 1201:9b71aac42d14 226
Vincent Coubard 1201:9b71aac42d14 227 SecurityManager& BLE::securityManager()
Vincent Coubard 1201:9b71aac42d14 228 {
Vincent Coubard 1201:9b71aac42d14 229 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 230 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 231 }
Vincent Coubard 1201:9b71aac42d14 232
Vincent Coubard 1201:9b71aac42d14 233 return transport->getSecurityManager();
Vincent Coubard 1201:9b71aac42d14 234 }
Vincent Coubard 1201:9b71aac42d14 235
Vincent Coubard 1201:9b71aac42d14 236 void BLE::waitForEvent(void)
Vincent Coubard 1201:9b71aac42d14 237 {
Vincent Coubard 1201:9b71aac42d14 238 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 239 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 240 }
Vincent Coubard 1201:9b71aac42d14 241
Vincent Coubard 1201:9b71aac42d14 242 transport->waitForEvent();
Vincent Coubard 1201:9b71aac42d14 243 }
Vincent Coubard 1201:9b71aac42d14 244
Vincent Coubard 1201:9b71aac42d14 245 void BLE::processEvents()
Vincent Coubard 1201:9b71aac42d14 246 {
Vincent Coubard 1201:9b71aac42d14 247 if (!transport) {
Vincent Coubard 1201:9b71aac42d14 248 error("bad handle to underlying transport");
Vincent Coubard 1201:9b71aac42d14 249 }
Vincent Coubard 1201:9b71aac42d14 250
Vincent Coubard 1201:9b71aac42d14 251 transport->processEvents();
Vincent Coubard 1201:9b71aac42d14 252 }
Vincent Coubard 1201:9b71aac42d14 253
Vincent Coubard 1201:9b71aac42d14 254 void BLE::onEventsToProcess(const BLE::OnEventsToProcessCallback_t& callback)
Vincent Coubard 1201:9b71aac42d14 255 {
Vincent Coubard 1201:9b71aac42d14 256 whenEventsToProcess = callback;
Vincent Coubard 1201:9b71aac42d14 257 }
Vincent Coubard 1201:9b71aac42d14 258
Vincent Coubard 1201:9b71aac42d14 259 void BLE::signalEventsToProcess()
Vincent Coubard 1201:9b71aac42d14 260 {
Vincent Coubard 1201:9b71aac42d14 261 if (whenEventsToProcess) {
Vincent Coubard 1201:9b71aac42d14 262 OnEventsToProcessCallbackContext params = {
Vincent Coubard 1201:9b71aac42d14 263 *this
Vincent Coubard 1201:9b71aac42d14 264 };
Vincent Coubard 1201:9b71aac42d14 265 whenEventsToProcess(&params);
Vincent Coubard 1201:9b71aac42d14 266 }
rgrover1 712:b04b5db36865 267 }