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