mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

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