Lancaster University's fork of the mbed BLE API. Lives on github, https://github.com/lancaster-university/BLE_API

Dependents:   microbit-dal microbit-dal microbit-ble-open microbit-dal ... more

Fork of BLE_API by Bluetooth Low Energy

Committer:
LancasterUniversity
Date:
Wed Apr 06 18:40:26 2016 +0100
Revision:
1131:73c11a85c6d6
Parent:
1082:127667021827
Child:
1135:0f5db03e0325
Synchronized with git rev 13bf70b6
Author: Rohit Grover
Release 2.1.5
=============

A minor release to separate the concept of minlen and len in
GattCharacteristic. Also contains some improvements to documentation.

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 {
LancasterUniversity 1131:73c11a85c6d6 134 clearAdvertisingPayload();
rgrover1 912:f728aa46e7df 135 if (!transport) {
rgrover1 912:f728aa46e7df 136 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 137 }
rgrover1 912:f728aa46e7df 138
rgrover1 912:f728aa46e7df 139 return transport->shutdown();
rgrover1 912:f728aa46e7df 140 }
rgrover1 912:f728aa46e7df 141
rgrover1 912:f728aa46e7df 142 const char *BLE::getVersion(void)
rgrover1 912:f728aa46e7df 143 {
rgrover1 912:f728aa46e7df 144 if (!transport) {
rgrover1 912:f728aa46e7df 145 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 146 }
rgrover1 912:f728aa46e7df 147
rgrover1 912:f728aa46e7df 148 return transport->getVersion();
rgrover1 912:f728aa46e7df 149 }
rgrover1 912:f728aa46e7df 150
rgrover1 912:f728aa46e7df 151 const Gap &BLE::gap() const
rgrover1 912:f728aa46e7df 152 {
rgrover1 912:f728aa46e7df 153 if (!transport) {
rgrover1 912:f728aa46e7df 154 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 155 }
rgrover1 912:f728aa46e7df 156
rgrover1 912:f728aa46e7df 157 return transport->getGap();
rgrover1 912:f728aa46e7df 158 }
rgrover1 912:f728aa46e7df 159
rgrover1 912:f728aa46e7df 160 Gap &BLE::gap()
rgrover1 912:f728aa46e7df 161 {
rgrover1 912:f728aa46e7df 162 if (!transport) {
rgrover1 912:f728aa46e7df 163 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 164 }
rgrover1 912:f728aa46e7df 165
rgrover1 912:f728aa46e7df 166 return transport->getGap();
rgrover1 912:f728aa46e7df 167 }
rgrover1 912:f728aa46e7df 168
rgrover1 912:f728aa46e7df 169 const GattServer& BLE::gattServer() const
rgrover1 912:f728aa46e7df 170 {
rgrover1 912:f728aa46e7df 171 if (!transport) {
rgrover1 912:f728aa46e7df 172 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 173 }
rgrover1 912:f728aa46e7df 174
rgrover1 912:f728aa46e7df 175 return transport->getGattServer();
rgrover1 912:f728aa46e7df 176 }
rgrover1 912:f728aa46e7df 177
rgrover1 912:f728aa46e7df 178 GattServer& BLE::gattServer()
rgrover1 912:f728aa46e7df 179 {
rgrover1 912:f728aa46e7df 180 if (!transport) {
rgrover1 912:f728aa46e7df 181 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 182 }
rgrover1 912:f728aa46e7df 183
rgrover1 912:f728aa46e7df 184 return transport->getGattServer();
rgrover1 912:f728aa46e7df 185 }
rgrover1 912:f728aa46e7df 186
rgrover1 912:f728aa46e7df 187 const GattClient& BLE::gattClient() const
rgrover1 912:f728aa46e7df 188 {
rgrover1 912:f728aa46e7df 189 if (!transport) {
rgrover1 912:f728aa46e7df 190 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 191 }
rgrover1 912:f728aa46e7df 192
rgrover1 912:f728aa46e7df 193 return transport->getGattClient();
rgrover1 912:f728aa46e7df 194 }
rgrover1 912:f728aa46e7df 195
rgrover1 912:f728aa46e7df 196 GattClient& BLE::gattClient()
rgrover1 912:f728aa46e7df 197 {
rgrover1 912:f728aa46e7df 198 if (!transport) {
rgrover1 912:f728aa46e7df 199 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 200 }
rgrover1 912:f728aa46e7df 201
rgrover1 912:f728aa46e7df 202 return transport->getGattClient();
rgrover1 912:f728aa46e7df 203 }
rgrover1 912:f728aa46e7df 204
rgrover1 912:f728aa46e7df 205 const SecurityManager& BLE::securityManager() const
rgrover1 912:f728aa46e7df 206 {
rgrover1 912:f728aa46e7df 207 if (!transport) {
rgrover1 912:f728aa46e7df 208 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 209 }
rgrover1 912:f728aa46e7df 210
rgrover1 912:f728aa46e7df 211 return transport->getSecurityManager();
rgrover1 912:f728aa46e7df 212 }
rgrover1 912:f728aa46e7df 213
rgrover1 912:f728aa46e7df 214 SecurityManager& BLE::securityManager()
rgrover1 912:f728aa46e7df 215 {
rgrover1 912:f728aa46e7df 216 if (!transport) {
rgrover1 912:f728aa46e7df 217 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 218 }
rgrover1 912:f728aa46e7df 219
rgrover1 912:f728aa46e7df 220 return transport->getSecurityManager();
rgrover1 912:f728aa46e7df 221 }
rgrover1 912:f728aa46e7df 222
rgrover1 912:f728aa46e7df 223 void BLE::waitForEvent(void)
rgrover1 912:f728aa46e7df 224 {
rgrover1 912:f728aa46e7df 225 if (!transport) {
rgrover1 912:f728aa46e7df 226 error("bad handle to underlying transport");
rgrover1 912:f728aa46e7df 227 }
rgrover1 912:f728aa46e7df 228
rgrover1 912:f728aa46e7df 229 transport->waitForEvent();
rgrover1 712:b04b5db36865 230 }