init
Embed:
(wiki syntax)
Show/hide line numbers
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 13:24:33 by
1.7.2