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