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