Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:27:58 2016 +0000
Revision:
0:6c56fb4bc5f0
Moving to library for sharing updates

Who changed what in which revision?

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