High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Tue Nov 03 12:51:24 2015 +0000
Revision:
874:0607a58418ce
Parent:
861:2afa79e3ed0a
Child:
875:25480c83e3cc
Synchronized with git rev aa7e4b2d
Author: Rohit Grover
BLE::init() should also be able to take a <object,member> tuple.

Who changed what in which revision?

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