STM32F7 Ethernet interface for nucleo STM32F767

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BLE.cpp Source File

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(&params->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(&params);
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(&params);
00309     }
00310 }