Marco Zecchini
/
Example_RTOS
Rtos API example
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 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 Sun Jul 17 2022 08:25:20 by 1.7.2