Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BLE.cpp Source File

BLE.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include <stdio.h>
00018 #include "ble/BLE.h"
00019 #include "ble/BLEInstanceBase.h "
00020 #include "platform/mbed_critical.h"
00021 #include "Deprecated.h"
00022 
00023 #if defined(TARGET_OTA_ENABLED)
00024 #include "ble/services/DFUService.h"
00025 #endif
00026 
00027 #ifdef YOTTA_CFG_MBED_OS
00028 #include <minar/minar.h>
00029 #endif
00030 
00031 #if !defined(YOTTA_CFG_MBED_OS)
00032 #include <mbed_error.h>
00033 #include <mbed_toolchain.h>
00034 #endif
00035 
00036 static const char* error_strings[] = {
00037     "BLE_ERROR_NONE: No error",
00038     "BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted",
00039     "BLE_ERROR_NOT_IMPLEMENTED: Requested a feature that isn't yet implement or isn't supported by the target HW",
00040     "BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range",
00041     "BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid",
00042     "BLE_STACK_BUSY: The stack is busy",
00043     "BLE_ERROR_INVALID_STATE: Invalid state",
00044     "BLE_ERROR_NO_MEM: Out of Memory",
00045     "BLE_ERROR_OPERATION_NOT_PERMITTED: The operation requested is not permitted",
00046     "BLE_ERROR_INITIALIZATION_INCOMPLETE: The BLE subsystem has not completed its initialisation",
00047     "BLE_ERROR_ALREADY_INITIALIZED: The BLE system has already been initialised",
00048     "BLE_ERROR_UNSPECIFIED: Unknown error",
00049     "BLE_ERROR_INTERNAL_STACK_FAILURE: The platform-specific stack failed"
00050 };
00051 
00052 const char* BLE::errorToString(ble_error_t error)
00053 {
00054     if (error > BLE_ERROR_INTERNAL_STACK_FAILURE) {
00055         return "Illegal error code";
00056     }
00057     return error_strings[error];
00058 }
00059 
00060 ble_error_t
00061 BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext*> callback)
00062 {
00063     ble_error_t err = transport->init(instanceID, callback);
00064     if (err != BLE_ERROR_NONE) {
00065         return err;
00066     }
00067 
00068     /* Platforms enabled for DFU should introduce the DFU Service into
00069      * applications automatically. */
00070 #if defined(TARGET_OTA_ENABLED)
00071     static DFUService dfu(*this); // defined static so that the object remains alive
00072 #endif // TARGET_OTA_ENABLED
00073 
00074     return BLE_ERROR_NONE;
00075 }
00076 
00077 /**
00078  * BLE::Instance() and BLE constructor rely upon a static array of initializers
00079  * to create actual BLE transport instances. A description of these instances
00080  * and initializers is supposed to be put in some .json file contributing to
00081  * yotta's configuration (typically in the target definition described by
00082  * target.json). Here's a sample:
00083  *
00084  *  "config": {
00085  *    ...
00086  *    "ble_instances": {
00087  *      "count": 1,
00088  *      "0" : {
00089  *        "initializer" : "createBLEInstance"
00090  *      }
00091  *    }
00092  *    ...
00093  *  }
00094  *
00095  * The following macros result in translating the above config into a static
00096  * array: instanceConstructors.
00097  */
00098 #ifdef YOTTA_CFG_BLE_INSTANCES_COUNT
00099 #define CONCATENATE(A, B) A ## B
00100 #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). */
00101 
00102 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER
00103 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER
00104 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER
00105 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER
00106 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER
00107 /* ... add more of the above if ever needed */
00108 
00109 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N))
00110 #elif !defined(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS)
00111 /*
00112  * The following applies when building without yotta. By default BLE_API provides
00113  * a trivial initializer list containing a single constructor: createBLEInstance.
00114  * This may be overridden.
00115  */
00116 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS createBLEInstance
00117 
00118 // yotta unlike mbed-cli has proper dependency mechanisms
00119 // It is not required to defined a stub for createBLEInstance
00120 #if !defined(YOTTA_CFG_MBED_OS)
00121 
00122 // this stub is required by ARMCC otherwise link will systematically fail
00123 MBED_WEAK BLEInstanceBase* createBLEInstance() {
00124     MBED_ASSERT("No BLE instance implementation.");
00125     printf("Please provide an implementation for mbed BLE");
00126     return NULL;
00127 }
00128 
00129 #endif
00130 
00131 
00132 #endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */
00133 
00134 typedef BLEInstanceBase *(*InstanceConstructor_t)(void);
00135 static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = {
00136 #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
00137     INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS
00138 #else
00139     INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT)
00140 #endif
00141 };
00142 
00143 BLE &
00144 BLE::Instance(InstanceID_t id)
00145 {
00146     static BLE *singletons[NUM_INSTANCES];
00147     if (id < NUM_INSTANCES) {
00148         if (singletons[id] == NULL) {
00149 BLE_DEPRECATED_API_USE_BEGIN()
00150             singletons[id] = new BLE(id); /* This object will never be freed. */
00151 BLE_DEPRECATED_API_USE_END()
00152         }
00153 
00154         return *singletons[id];
00155     }
00156 
00157     /* we come here only in the case of a bad interfaceID. */
00158 BLE_DEPRECATED_API_USE_BEGIN()
00159     static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */);
00160 BLE_DEPRECATED_API_USE_END()
00161     return badSingleton;
00162 }
00163 
00164 #ifdef YOTTA_CFG_MBED_OS
00165 void defaultSchedulingCallback(BLE::OnEventsToProcessCallbackContext* params) {
00166     minar::Scheduler::postCallback(&params->ble, &BLE::processEvents);
00167 }
00168 #else
00169 #define defaultSchedulingCallback NULL
00170 #endif
00171 
00172 bool BLE::hasInitialized(void) const
00173 {
00174     if (!transport) {
00175         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00176     }
00177 
00178     return transport->hasInitialized();
00179 }
00180 
00181 ble_error_t BLE::shutdown(void)
00182 {
00183     if (!transport) {
00184         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00185     }
00186 
00187     event_signaled = false;
00188     return transport->shutdown();
00189 }
00190 
00191 const char *BLE::getVersion(void)
00192 {
00193     if (!transport) {
00194         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00195     }
00196 
00197     return transport->getVersion();
00198 }
00199 
00200 const Gap &BLE::gap() const
00201 {
00202     if (!transport) {
00203         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00204     }
00205 
00206     return transport->getGap();
00207 }
00208 
00209 Gap &BLE::gap()
00210 {
00211     if (!transport) {
00212         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00213     }
00214 
00215     return transport->getGap();
00216 }
00217 
00218 #if BLE_FEATURE_GATT_SERVER
00219 
00220 const GattServer& BLE::gattServer() const
00221 {
00222     if (!transport) {
00223         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00224     }
00225 
00226     return transport->getGattServer();
00227 }
00228 
00229 GattServer& BLE::gattServer()
00230 {
00231     if (!transport) {
00232         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00233     }
00234 
00235     return transport->getGattServer();
00236 }
00237 
00238 #endif // BLE_FEATURE_GATT_SERVER
00239 
00240 #if BLE_FEATURE_GATT_CLIENT
00241 
00242 const GattClient& BLE::gattClient() const
00243 {
00244     if (!transport) {
00245         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00246     }
00247 
00248     return transport->getGattClient();
00249 }
00250 
00251 GattClient& BLE::gattClient()
00252 {
00253     if (!transport) {
00254         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00255     }
00256 
00257     return transport->getGattClient();
00258 }
00259 
00260 #endif // BLE_FEATURE_GATT_CLIENT
00261 
00262 #if BLE_FEATURE_SECURITY
00263 
00264 const SecurityManager& BLE::securityManager() const
00265 {
00266     if (!transport) {
00267         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00268     }
00269 
00270     return transport->getSecurityManager();
00271 }
00272 
00273 SecurityManager& BLE::securityManager()
00274 {
00275     if (!transport) {
00276         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00277     }
00278 
00279     return transport->getSecurityManager();
00280 }
00281 
00282 #endif // BLE_FEATURE_SECURITY
00283 
00284 void BLE::waitForEvent(void)
00285 {
00286     if (!transport) {
00287         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00288     }
00289 
00290     transport->waitForEvent();
00291 }
00292 
00293 void BLE::processEvents()
00294 {
00295     core_util_critical_section_enter();
00296     if (event_signaled == false) {
00297         core_util_critical_section_exit();
00298         return;
00299     }
00300 
00301     event_signaled = false;
00302     core_util_critical_section_exit();
00303 
00304     if (!transport) {
00305         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00306     }
00307 
00308     transport->processEvents();
00309 }
00310 
00311 void BLE::onEventsToProcess(const BLE::OnEventsToProcessCallback_t & callback)
00312 {
00313     whenEventsToProcess = callback;
00314 
00315     // If events were previously signaled but the handler was not in place then
00316     // signal immediately events availability
00317     if (event_signaled && whenEventsToProcess) {
00318         OnEventsToProcessCallbackContext params = {
00319             *this
00320         };
00321         whenEventsToProcess(&params);
00322     }
00323 }
00324 
00325 void BLE::signalEventsToProcess()
00326 {
00327     core_util_critical_section_enter();
00328     if (event_signaled == true) {
00329         core_util_critical_section_exit();
00330         return;
00331     }
00332 
00333     event_signaled = true;
00334     core_util_critical_section_exit();
00335 
00336     if (whenEventsToProcess) {
00337         OnEventsToProcessCallbackContext params = {
00338             *this
00339         };
00340         whenEventsToProcess(&params);
00341     }
00342 }
00343 
00344 // start of deprecated functions
00345 
00346 BLE_DEPRECATED_API_USE_BEGIN()
00347 
00348 // NOTE: move and remove deprecation once private
00349 BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport(),
00350     whenEventsToProcess(defaultSchedulingCallback),
00351     event_signaled(false)
00352 {
00353     static BLEInstanceBase *transportInstances[NUM_INSTANCES];
00354 
00355     if (instanceID < NUM_INSTANCES) {
00356         if (!transportInstances[instanceID]) {
00357             transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */
00358         }
00359         transport = transportInstances[instanceID];
00360     } else {
00361         transport = NULL;
00362     }
00363 }
00364 
00365 ble_error_t BLE::setAddress(
00366     BLEProtocol::AddressType_t type,
00367     const BLEProtocol::AddressBytes_t address
00368 ) {
00369     return gap().setAddress(type, address);
00370 }
00371 
00372 #if BLE_ROLE_CENTRAL
00373 ble_error_t BLE::connect(
00374     const BLEProtocol::AddressBytes_t peerAddr,
00375     BLEProtocol::AddressType_t peerAddrType,
00376     const Gap::ConnectionParams_t *connectionParams,
00377     const GapScanningParams *scanParams
00378 ) {
00379     return gap().connect(peerAddr, peerAddrType, connectionParams, scanParams);
00380 }
00381 #endif // BLE_ROLE_CENTRAL
00382 
00383 #if BLE_FEATURE_CONNECTABLE
00384 ble_error_t BLE::disconnect(Gap::DisconnectionReason_t reason) {
00385     return gap().disconnect(reason);
00386 }
00387 #endif // BLE_FEATURE_CONNECTABLE
00388 
00389 Gap::GapState_t BLE::getGapState(void) const {
00390     return gap().getState();
00391 }
00392 
00393 #if BLE_ROLE_BROADCASTER
00394 void BLE::setAdvertisingType(GapAdvertisingParams::AdvertisingType advType) {
00395     gap().setAdvertisingType(advType);
00396 }
00397 
00398 void BLE::setAdvertisingInterval(uint16_t interval) {
00399     gap().setAdvertisingInterval(interval);
00400 }
00401 
00402 void BLE::setAdvertisingTimeout(uint16_t timeout) {
00403     gap().setAdvertisingTimeout(timeout);
00404 }
00405 
00406 void BLE::setAdvertisingParams(const GapAdvertisingParams &advParams) {
00407     gap().setAdvertisingParams(advParams);
00408 }
00409 
00410 const GapAdvertisingParams &BLE::getAdvertisingParams(void) const {
00411     return gap().getAdvertisingParams();
00412 }
00413 
00414 ble_error_t BLE::accumulateAdvertisingPayload(uint8_t flags) {
00415     return gap().accumulateAdvertisingPayload(flags);
00416 }
00417 
00418 ble_error_t BLE::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) {
00419     return gap().accumulateAdvertisingPayload(app);
00420 }
00421 
00422 ble_error_t BLE::accumulateAdvertisingPayloadTxPower(int8_t power) {
00423     return gap().accumulateAdvertisingPayloadTxPower(power);
00424 }
00425 
00426 ble_error_t BLE::accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
00427     return gap().accumulateAdvertisingPayload(type, data, len);
00428 }
00429 
00430 ble_error_t BLE::setAdvertisingData(const GapAdvertisingData &advData) {
00431     return gap().setAdvertisingPayload(advData);
00432 }
00433 
00434 const GapAdvertisingData &BLE::getAdvertisingData(void) const {
00435     return gap().getAdvertisingPayload();
00436 }
00437 
00438 void BLE::clearAdvertisingPayload(void) {
00439     gap().clearAdvertisingPayload();
00440 }
00441 
00442 ble_error_t BLE::setAdvertisingPayload(void) {
00443     return BLE_ERROR_NONE;
00444 }
00445 
00446 ble_error_t BLE::accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
00447     return gap().accumulateScanResponse(type, data, len);
00448 }
00449 
00450 void BLE::clearScanResponse(void) {
00451     gap().clearScanResponse();
00452 }
00453 
00454 ble_error_t BLE::startAdvertising(void) {
00455     return gap().startAdvertising();
00456 }
00457 
00458 ble_error_t BLE::stopAdvertising(void) {
00459     return gap().stopAdvertising();
00460 }
00461 #endif // BLE_ROLE_BROADCASTER
00462 
00463 #if BLE_ROLE_OBSERVER
00464 ble_error_t BLE::setScanParams(uint16_t interval,
00465     uint16_t window,
00466     uint16_t timeout,
00467     bool     activeScanning) {
00468     return gap().setScanParams(interval, window, timeout, activeScanning);
00469 }
00470 
00471 ble_error_t BLE::setScanInterval(uint16_t interval) {
00472     return gap().setScanInterval(interval);
00473 }
00474 
00475 ble_error_t BLE::setScanWindow(uint16_t window) {
00476     return gap().setScanWindow(window);
00477 }
00478 
00479 ble_error_t BLE::setScanTimeout(uint16_t timeout) {
00480     return gap().setScanTimeout(timeout);
00481 }
00482 
00483 void BLE::setActiveScan(bool activeScanning) {
00484     gap().setActiveScanning(activeScanning);
00485 }
00486 
00487 ble_error_t BLE::startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)) {
00488     return gap().startScan(callback);
00489 }
00490 #endif // BLE_ROLE_OBSERVER
00491 
00492 #if BLE_FEATURE_CONNECTABLE
00493 ble_error_t BLE::disconnect(Gap::Handle_t connectionHandle, Gap::DisconnectionReason_t reason) {
00494     return gap().disconnect(connectionHandle, reason);
00495 }
00496 
00497 ble_error_t BLE::updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) {
00498     return gap().updateConnectionParams(handle, params);
00499 }
00500 #endif // BLE_FEATURE_CONNECTABLE
00501 
00502 ble_error_t BLE::setTxPower(int8_t txPower) {
00503     return gap().setTxPower(txPower);
00504 }
00505 
00506 void BLE::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
00507     gap().getPermittedTxPowerValues(valueArrayPP, countP);
00508 }
00509 
00510 void BLE::onTimeout(Gap::TimeoutEventCallback_t timeoutCallback) {
00511     gap().onTimeout(timeoutCallback);
00512 }
00513 
00514 #if BLE_FEATURE_CONNECTABLE
00515 void BLE::onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) {
00516     gap().onDisconnection(disconnectionCallback);
00517 }
00518 #endif // BLE_FEATURE_CONNECTABLE
00519 
00520 void BLE::onRadioNotification(void (*callback)(bool)) {
00521     gap().onRadioNotification(callback);
00522 }
00523 
00524 
00525 BLE_DEPRECATED_API_USE_END()
00526