High level Bluetooth Low Energy API and radio abstraction layer

Dependencies:   nRF51822

Dependents:   LinkNode_LIS3DH

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Wed Apr 06 19:13:54 2016 +0100
Revision:
1135:22aada733dbd
Parent:
1131:692ddf04fc42
Synchronized with git rev 17e37360
Author: Vincent Coubard
Merge pull request #161 from ARMmbed/develop

merge branch develop (v2.4.0)

Who changed what in which revision?

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