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.
Dependencies: nRF51_Vdd TextLCD BME280
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 Jul 12 2022 15:15:40 by
