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.
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 00021 #if defined(TARGET_OTA_ENABLED) 00022 #include "ble/services/DFUService.h" 00023 #endif 00024 00025 #ifdef YOTTA_CFG_MBED_OS 00026 #include <minar/minar.h> 00027 #endif 00028 00029 #if !defined(YOTTA_CFG_MBED_OS) 00030 #include <mbed_error.h> 00031 #include <toolchain.h> 00032 #endif 00033 00034 #if defined(__GNUC__) && !defined(__CC_ARM) 00035 #define BLE_DEPRECATED_API_USE_BEGIN \ 00036 _Pragma("GCC diagnostic push") \ 00037 _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") 00038 #elif defined(__CC_ARM) 00039 #define BLE_DEPRECATED_API_USE_BEGIN \ 00040 _Pragma("push") \ 00041 _Pragma("diag_suppress 1361") 00042 #else 00043 #define BLE_DEPRECATED_API_USE_BEGIN 00044 #endif 00045 00046 #if defined(__GNUC__) && !defined(__CC_ARM) 00047 #define BLE_DEPRECATED_API_USE_END \ 00048 _Pragma("GCC diagnostic pop") 00049 #elif defined(__CC_ARM) 00050 #define BLE_DEPRECATED_API_USE_END \ 00051 _Pragma("pop") 00052 #else 00053 #define BLE_DEPRECATED_API_USE_END 00054 #endif 00055 00056 static const char* error_strings[] = { 00057 "BLE_ERROR_NONE: No error", 00058 "BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted", 00059 "BLE_ERROR_NOT_IMPLEMENTED: Requested a feature that isn't yet implement or isn't supported by the target HW", 00060 "BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range", 00061 "BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid", 00062 "BLE_STACK_BUSY: The stack is busy", 00063 "BLE_ERROR_INVALID_STATE: Invalid state", 00064 "BLE_ERROR_NO_MEM: Out of Memory", 00065 "BLE_ERROR_OPERATION_NOT_PERMITTED: The operation requested is not permitted", 00066 "BLE_ERROR_INITIALIZATION_INCOMPLETE: The BLE subsystem has not completed its initialisation", 00067 "BLE_ERROR_ALREADY_INITIALIZED: The BLE system has already been initialised", 00068 "BLE_ERROR_UNSPECIFIED: Unknown error", 00069 "BLE_ERROR_INTERNAL_STACK_FAILURE: The platform-specific stack failed" 00070 }; 00071 00072 const char* BLE::errorToString(ble_error_t error) 00073 { 00074 if (error > BLE_ERROR_INTERNAL_STACK_FAILURE) { 00075 return "Illegal error code"; 00076 } 00077 return error_strings[error]; 00078 } 00079 00080 ble_error_t 00081 BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext*> callback) 00082 { 00083 ble_error_t err = transport->init(instanceID, callback); 00084 if (err != BLE_ERROR_NONE) { 00085 return err; 00086 } 00087 00088 /* Platforms enabled for DFU should introduce the DFU Service into 00089 * applications automatically. */ 00090 #if defined(TARGET_OTA_ENABLED) 00091 static DFUService dfu(*this); // defined static so that the object remains alive 00092 #endif // TARGET_OTA_ENABLED 00093 00094 return BLE_ERROR_NONE; 00095 } 00096 00097 /** 00098 * BLE::Instance() and BLE constructor rely upon a static array of initializers 00099 * to create actual BLE transport instances. A description of these instances 00100 * and initializers is supposed to be put in some .json file contributing to 00101 * yotta's configuration (typically in the target definition described by 00102 * target.json). Here's a sample: 00103 * 00104 * "config": { 00105 * ... 00106 * "ble_instances": { 00107 * "count": 1, 00108 * "0" : { 00109 * "initializer" : "createBLEInstance" 00110 * } 00111 * } 00112 * ... 00113 * } 00114 * 00115 * The following macros result in translating the above config into a static 00116 * array: instanceConstructors. 00117 */ 00118 #ifdef YOTTA_CFG_BLE_INSTANCES_COUNT 00119 #define CONCATENATE(A, B) A ## B 00120 #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). */ 00121 00122 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER 00123 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER 00124 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER 00125 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER 00126 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER 00127 /* ... add more of the above if ever needed */ 00128 00129 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N)) 00130 #elif !defined(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS) 00131 /* 00132 * The following applies when building without yotta. By default BLE_API provides 00133 * a trivial initializer list containing a single constructor: createBLEInstance. 00134 * This may be overridden. 00135 */ 00136 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS createBLEInstance 00137 00138 // yotta unlike mbed-cli has proper dependency mechanisms 00139 // It is not required to defined a stub for createBLEInstance 00140 #if !defined(YOTTA_CFG_MBED_OS) 00141 00142 // this stub is required by ARMCC otherwise link will systematically fail 00143 MBED_WEAK BLEInstanceBase* createBLEInstance() { 00144 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_CREATION_FAILED), "Please provide an implementation for mbed BLE"); 00145 return NULL; 00146 } 00147 00148 #endif 00149 00150 00151 #endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */ 00152 00153 typedef BLEInstanceBase *(*InstanceConstructor_t)(void); 00154 static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = { 00155 #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT 00156 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS 00157 #else 00158 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT) 00159 #endif 00160 }; 00161 00162 BLE & 00163 BLE::Instance(InstanceID_t id) 00164 { 00165 static BLE *singletons[NUM_INSTANCES]; 00166 if (id < NUM_INSTANCES) { 00167 if (singletons[id] == NULL) { 00168 BLE_DEPRECATED_API_USE_BEGIN 00169 singletons[id] = new BLE(id); /* This object will never be freed. */ 00170 BLE_DEPRECATED_API_USE_END 00171 } 00172 00173 return *singletons[id]; 00174 } 00175 00176 /* we come here only in the case of a bad interfaceID. */ 00177 BLE_DEPRECATED_API_USE_BEGIN 00178 static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */); 00179 BLE_DEPRECATED_API_USE_END 00180 return badSingleton; 00181 } 00182 00183 #ifdef YOTTA_CFG_MBED_OS 00184 void defaultSchedulingCallback(BLE::OnEventsToProcessCallbackContext* params) { 00185 minar::Scheduler::postCallback(¶ms->ble, &BLE::processEvents); 00186 } 00187 #else 00188 #define defaultSchedulingCallback NULL 00189 #endif 00190 00191 bool BLE::hasInitialized(void) const 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->hasInitialized(); 00198 } 00199 00200 ble_error_t BLE::shutdown(void) 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 event_signaled = false; 00207 return transport->shutdown(); 00208 } 00209 00210 const char *BLE::getVersion(void) 00211 { 00212 if (!transport) { 00213 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport"); 00214 } 00215 00216 return transport->getVersion(); 00217 } 00218 00219 const Gap &BLE::gap() const 00220 { 00221 if (!transport) { 00222 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport"); 00223 } 00224 00225 return transport->getGap(); 00226 } 00227 00228 Gap &BLE::gap() 00229 { 00230 if (!transport) { 00231 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport"); 00232 } 00233 00234 return transport->getGap(); 00235 } 00236 00237 const GattServer& BLE::gattServer() const 00238 { 00239 if (!transport) { 00240 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport"); 00241 } 00242 00243 return transport->getGattServer(); 00244 } 00245 00246 GattServer& BLE::gattServer() 00247 { 00248 if (!transport) { 00249 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport"); 00250 } 00251 00252 return transport->getGattServer(); 00253 } 00254 00255 const GattClient& BLE::gattClient() const 00256 { 00257 if (!transport) { 00258 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport"); 00259 } 00260 00261 return transport->getGattClient(); 00262 } 00263 00264 GattClient& BLE::gattClient() 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->getGattClient(); 00271 } 00272 00273 const SecurityManager& BLE::securityManager() const 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 SecurityManager& BLE::securityManager() 00283 { 00284 if (!transport) { 00285 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport"); 00286 } 00287 00288 return transport->getSecurityManager(); 00289 } 00290 00291 void BLE::waitForEvent(void) 00292 { 00293 if (!transport) { 00294 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport"); 00295 } 00296 00297 transport->waitForEvent(); 00298 } 00299 00300 void BLE::processEvents() 00301 { 00302 if (event_signaled == false) { 00303 return; 00304 } 00305 00306 if (!transport) { 00307 MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport"); 00308 } 00309 00310 event_signaled = false; 00311 00312 transport->processEvents(); 00313 } 00314 00315 void BLE::onEventsToProcess(const BLE::OnEventsToProcessCallback_t & callback) 00316 { 00317 whenEventsToProcess = callback; 00318 00319 // If events were previously signaled but the handler was not in place then 00320 // signal immediately events availability 00321 if (event_signaled && whenEventsToProcess) { 00322 OnEventsToProcessCallbackContext params = { 00323 *this 00324 }; 00325 whenEventsToProcess(¶ms); 00326 } 00327 } 00328 00329 void BLE::signalEventsToProcess() 00330 { 00331 if (event_signaled == true) { 00332 return; 00333 } 00334 00335 event_signaled = true; 00336 00337 if (whenEventsToProcess) { 00338 OnEventsToProcessCallbackContext params = { 00339 *this 00340 }; 00341 whenEventsToProcess(¶ms); 00342 } 00343 } 00344 00345 // start of deprecated functions 00346 00347 BLE_DEPRECATED_API_USE_BEGIN 00348 00349 // NOTE: move and remove deprecation once private 00350 BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport(), 00351 whenEventsToProcess(defaultSchedulingCallback), 00352 event_signaled(false) 00353 { 00354 static BLEInstanceBase *transportInstances[NUM_INSTANCES]; 00355 00356 if (instanceID < NUM_INSTANCES) { 00357 if (!transportInstances[instanceID]) { 00358 transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */ 00359 } 00360 transport = transportInstances[instanceID]; 00361 } else { 00362 transport = NULL; 00363 } 00364 } 00365 00366 ble_error_t BLE::setAddress( 00367 BLEProtocol::AddressType_t type, 00368 const BLEProtocol::AddressBytes_t address 00369 ) { 00370 return gap().setAddress(type, address); 00371 } 00372 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 00382 ble_error_t BLE::disconnect(Gap::DisconnectionReason_t reason) { 00383 return gap().disconnect(reason); 00384 } 00385 00386 BLE_DEPRECATED_API_USE_END 00387
Generated on Tue Aug 9 2022 00:37:03 by
