High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Mon Jan 11 08:51:42 2016 +0000
Revision:
1074:1fedc77d9add
Parent:
912:f728aa46e7df
Child:
1075:0d0dafb54bc9
Synchronized with git rev cd809e2a
Author: Andres Amaya Garcia
Modify shutdown API and functionality

Modify the shutdown API to remove the static shutdown function in Gap,
SecurityManager, GattClient and GattServer. Futhermore, remove the static
references to Gap, SecurityManager, GattClient and GattServer objects inside
their own classes. The cleanup method is renamed to `reset()` and made public.
Finally, additional functionality is added to the reset implementation in
Gap.

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 912:f728aa46e7df 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 912:f728aa46e7df 25 BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback)
rgrover1 712:b04b5db36865 26 {
rgrover1 912:f728aa46e7df 27 ble_error_t err = transport->init(instanceID, callback);
rgrover1 712:b04b5db36865 28 if (err != BLE_ERROR_NONE) {
rgrover1 712:b04b5db36865 29 return err;
rgrover1 712:b04b5db36865 30 }
rgrover1 712:b04b5db36865 31
rgrover1 712:b04b5db36865 32 /* Platforms enabled for DFU should introduce the DFU Service into
rgrover1 712:b04b5db36865 33 * applications automatically. */
rgrover1 712:b04b5db36865 34 #if defined(TARGET_OTA_ENABLED)
rgrover1 712:b04b5db36865 35 static DFUService dfu(*this); // defined static so that the object remains alive
rgrover1 712:b04b5db36865 36 #endif // TARGET_OTA_ENABLED
rgrover1 712:b04b5db36865 37
rgrover1 712:b04b5db36865 38 return BLE_ERROR_NONE;
rgrover1 822:a0f080d1e836 39 }
rgrover1 822:a0f080d1e836 40
rgrover1 822:a0f080d1e836 41 /**
rgrover1 822:a0f080d1e836 42 * BLE::Instance() and BLE constructor rely upon a static array of initializers
rgrover1 822:a0f080d1e836 43 * to create actual BLE transport instances. A description of these instances
rgrover1 822:a0f080d1e836 44 * and initializers is supposed to be put in some .json file contributing to
rgrover1 828:d22ab1419e92 45 * yotta's configuration (typically in the target definition described by
rgrover1 828:d22ab1419e92 46 * target.json). Here's a sample:
rgrover1 822:a0f080d1e836 47 *
rgrover1 822:a0f080d1e836 48 * "config": {
rgrover1 822:a0f080d1e836 49 * ...
rgrover1 822:a0f080d1e836 50 * "ble_instances": {
rgrover1 822:a0f080d1e836 51 * "count": 1,
rgrover1 822:a0f080d1e836 52 * "0" : {
rgrover1 822:a0f080d1e836 53 * "initializer" : "createBLEInstance"
rgrover1 822:a0f080d1e836 54 * }
rgrover1 822:a0f080d1e836 55 * }
rgrover1 828:d22ab1419e92 56 * ...
rgrover1 822:a0f080d1e836 57 * }
rgrover1 822:a0f080d1e836 58 *
rgrover1 822:a0f080d1e836 59 * The following macros result in translating the above config into a static
rgrover1 822:a0f080d1e836 60 * array: instanceConstructors.
rgrover1 822:a0f080d1e836 61 */
rgrover1 822:a0f080d1e836 62 #ifdef YOTTA_CFG_BLE_INSTANCES_COUNT
rgrover1 822:a0f080d1e836 63 #define CONCATENATE(A, B) A ## B
rgrover1 822:a0f080d1e836 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). */
rgrover1 822:a0f080d1e836 65
rgrover1 822:a0f080d1e836 66 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER
rgrover1 822:a0f080d1e836 67 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER
rgrover1 822:a0f080d1e836 68 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER
rgrover1 822:a0f080d1e836 69 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER
rgrover1 822:a0f080d1e836 70 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER
rgrover1 822:a0f080d1e836 71 /* ... add more of the above if ever needed */
rgrover1 822:a0f080d1e836 72
rgrover1 822:a0f080d1e836 73 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N))
rgrover1 827:a63b24d78132 74 #elif !defined(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS)
rgrover1 827:a63b24d78132 75 /*
rgrover1 827:a63b24d78132 76 * The following applies when building without yotta. By default BLE_API provides
rgrover1 827:a63b24d78132 77 * a trivial initializer list containing a single constructor: createBLEInstance.
rgrover1 827:a63b24d78132 78 * This may be overridden.
rgrover1 827:a63b24d78132 79 */
rgrover1 827:a63b24d78132 80 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS createBLEInstance
rgrover1 822:a0f080d1e836 81 #endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */
rgrover1 822:a0f080d1e836 82
rgrover1 822:a0f080d1e836 83 typedef BLEInstanceBase *(*InstanceConstructor_t)(void);
rgrover1 822:a0f080d1e836 84 static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = {
rgrover1 822:a0f080d1e836 85 #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
rgrover1 827:a63b24d78132 86 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS
rgrover1 822:a0f080d1e836 87 #else
rgrover1 822:a0f080d1e836 88 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT)
rgrover1 822:a0f080d1e836 89 #endif
rgrover1 822:a0f080d1e836 90 };
rgrover1 822:a0f080d1e836 91
rgrover1 825:b65c6a222525 92 BLE &
rgrover1 822:a0f080d1e836 93 BLE::Instance(InstanceID_t id)
rgrover1 822:a0f080d1e836 94 {
rgrover1 822:a0f080d1e836 95 static BLE *singletons[NUM_INSTANCES];
rgrover1 822:a0f080d1e836 96 if (id < NUM_INSTANCES) {
rgrover1 822:a0f080d1e836 97 if (singletons[id] == NULL) {
rgrover1 822:a0f080d1e836 98 singletons[id] = new BLE(id); /* This object will never be freed. */
rgrover1 822:a0f080d1e836 99 }
rgrover1 822:a0f080d1e836 100
rgrover1 822:a0f080d1e836 101 return *singletons[id];
rgrover1 822:a0f080d1e836 102 }
rgrover1 822:a0f080d1e836 103
rgrover1 822:a0f080d1e836 104 /* we come here only in the case of a bad interfaceID. */
rgrover1 822:a0f080d1e836 105 static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */);
rgrover1 822:a0f080d1e836 106 return badSingleton;
rgrover1 822:a0f080d1e836 107 }
rgrover1 822:a0f080d1e836 108
rgrover1 912:f728aa46e7df 109 BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport()
rgrover1 822:a0f080d1e836 110 {
rgrover1 822:a0f080d1e836 111 static BLEInstanceBase *transportInstances[NUM_INSTANCES];
rgrover1 822:a0f080d1e836 112
rgrover1 822:a0f080d1e836 113 if (instanceID < NUM_INSTANCES) {
rgrover1 822:a0f080d1e836 114 if (!transportInstances[instanceID]) {
rgrover1 822:a0f080d1e836 115 transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */
rgrover1 822:a0f080d1e836 116 }
rgrover1 822:a0f080d1e836 117 transport = transportInstances[instanceID];
rgrover1 822:a0f080d1e836 118 } else {
rgrover1 822:a0f080d1e836 119 transport = NULL;
rgrover1 822:a0f080d1e836 120 }
rgrover1 912:f728aa46e7df 121 }
rgrover1 912:f728aa46e7df 122
rgrover1 912:f728aa46e7df 123 bool BLE::hasInitialized(void) const
rgrover1 912:f728aa46e7df 124 {
rgrover1 912:f728aa46e7df 125 if (!transport) {
rgrover1 912:f728aa46e7df 126 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 127 }
rgrover1 912:f728aa46e7df 128
rgrover1 912:f728aa46e7df 129 return transport->hasInitialized();
rgrover1 912:f728aa46e7df 130 }
rgrover1 912:f728aa46e7df 131
rgrover1 912:f728aa46e7df 132 ble_error_t BLE::shutdown(void)
rgrover1 912:f728aa46e7df 133 {
rgrover1 912:f728aa46e7df 134 if (!transport) {
rgrover1 912:f728aa46e7df 135 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 136 }
rgrover1 912:f728aa46e7df 137
rgrover1 912:f728aa46e7df 138 return transport->shutdown();
rgrover1 912:f728aa46e7df 139 }
rgrover1 912:f728aa46e7df 140
rgrover1 912:f728aa46e7df 141 const char *BLE::getVersion(void)
rgrover1 912:f728aa46e7df 142 {
rgrover1 912:f728aa46e7df 143 if (!transport) {
rgrover1 912:f728aa46e7df 144 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 145 }
rgrover1 912:f728aa46e7df 146
rgrover1 912:f728aa46e7df 147 return transport->getVersion();
rgrover1 912:f728aa46e7df 148 }
rgrover1 912:f728aa46e7df 149
rgrover1 912:f728aa46e7df 150 const Gap &BLE::gap() const
rgrover1 912:f728aa46e7df 151 {
rgrover1 912:f728aa46e7df 152 if (!transport) {
rgrover1 912:f728aa46e7df 153 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 154 }
rgrover1 912:f728aa46e7df 155
rgrover1 912:f728aa46e7df 156 return transport->getGap();
rgrover1 912:f728aa46e7df 157 }
rgrover1 912:f728aa46e7df 158
rgrover1 912:f728aa46e7df 159 Gap &BLE::gap()
rgrover1 912:f728aa46e7df 160 {
rgrover1 912:f728aa46e7df 161 if (!transport) {
rgrover1 912:f728aa46e7df 162 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 163 }
rgrover1 912:f728aa46e7df 164
rgrover1 912:f728aa46e7df 165 return transport->getGap();
rgrover1 912:f728aa46e7df 166 }
rgrover1 912:f728aa46e7df 167
rgrover1 912:f728aa46e7df 168 const GattServer& BLE::gattServer() const
rgrover1 912:f728aa46e7df 169 {
rgrover1 912:f728aa46e7df 170 if (!transport) {
rgrover1 912:f728aa46e7df 171 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 172 }
rgrover1 912:f728aa46e7df 173
rgrover1 912:f728aa46e7df 174 return transport->getGattServer();
rgrover1 912:f728aa46e7df 175 }
rgrover1 912:f728aa46e7df 176
rgrover1 912:f728aa46e7df 177 GattServer& BLE::gattServer()
rgrover1 912:f728aa46e7df 178 {
rgrover1 912:f728aa46e7df 179 if (!transport) {
rgrover1 912:f728aa46e7df 180 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 181 }
rgrover1 912:f728aa46e7df 182
rgrover1 912:f728aa46e7df 183 return transport->getGattServer();
rgrover1 912:f728aa46e7df 184 }
rgrover1 912:f728aa46e7df 185
rgrover1 912:f728aa46e7df 186 const GattClient& BLE::gattClient() const
rgrover1 912:f728aa46e7df 187 {
rgrover1 912:f728aa46e7df 188 if (!transport) {
rgrover1 912:f728aa46e7df 189 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 190 }
rgrover1 912:f728aa46e7df 191
rgrover1 912:f728aa46e7df 192 return transport->getGattClient();
rgrover1 912:f728aa46e7df 193 }
rgrover1 912:f728aa46e7df 194
rgrover1 912:f728aa46e7df 195 GattClient& BLE::gattClient()
rgrover1 912:f728aa46e7df 196 {
rgrover1 912:f728aa46e7df 197 if (!transport) {
rgrover1 912:f728aa46e7df 198 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 199 }
rgrover1 912:f728aa46e7df 200
rgrover1 912:f728aa46e7df 201 return transport->getGattClient();
rgrover1 912:f728aa46e7df 202 }
rgrover1 912:f728aa46e7df 203
rgrover1 912:f728aa46e7df 204 const SecurityManager& BLE::securityManager() const
rgrover1 912:f728aa46e7df 205 {
rgrover1 912:f728aa46e7df 206 if (!transport) {
rgrover1 912:f728aa46e7df 207 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 208 }
rgrover1 912:f728aa46e7df 209
rgrover1 912:f728aa46e7df 210 return transport->getSecurityManager();
rgrover1 912:f728aa46e7df 211 }
rgrover1 912:f728aa46e7df 212
rgrover1 912:f728aa46e7df 213 SecurityManager& BLE::securityManager()
rgrover1 912:f728aa46e7df 214 {
rgrover1 912:f728aa46e7df 215 if (!transport) {
rgrover1 912:f728aa46e7df 216 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 217 }
rgrover1 912:f728aa46e7df 218
rgrover1 912:f728aa46e7df 219 return transport->getSecurityManager();
rgrover1 912:f728aa46e7df 220 }
rgrover1 912:f728aa46e7df 221
rgrover1 912:f728aa46e7df 222 void BLE::waitForEvent(void)
rgrover1 912:f728aa46e7df 223 {
rgrover1 912:f728aa46e7df 224 if (!transport) {
rgrover1 912:f728aa46e7df 225 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 226 }
rgrover1 912:f728aa46e7df 227
rgrover1 912:f728aa46e7df 228 transport->waitForEvent();
rgrover1 712:b04b5db36865 229 }