Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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(¶ms->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(¶ms); 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(¶ms); 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
Generated on Tue Jul 12 2022 13:54:03 by
