Updated

Fork of BLE_API by Bluetooth Low Energy

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 "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 ble_error_t
00025 BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback)
00026 {
00027     ble_error_t err = transport->init(instanceID, callback);
00028     if (err != BLE_ERROR_NONE) {
00029         return err;
00030     }
00031 
00032     /* Platforms enabled for DFU should introduce the DFU Service into
00033      * applications automatically. */
00034 #if defined(TARGET_OTA_ENABLED)
00035     static DFUService dfu(*this); // defined static so that the object remains alive
00036 #endif // TARGET_OTA_ENABLED
00037 
00038     return BLE_ERROR_NONE;
00039 }
00040 
00041 /**
00042  * BLE::Instance() and BLE constructor rely upon a static array of initializers
00043  * to create actual BLE transport instances. A description of these instances
00044  * and initializers is supposed to be put in some .json file contributing to
00045  * yotta's configuration (typically in the target definition described by
00046  * target.json). Here's a sample:
00047  *
00048  *  "config": {
00049  *    ...
00050  *    "ble_instances": {
00051  *      "count": 1,
00052  *      "0" : {
00053  *        "initializer" : "createBLEInstance"
00054  *      }
00055  *    }
00056  *    ...
00057  *  }
00058  *
00059  * The following macros result in translating the above config into a static
00060  * array: instanceConstructors.
00061  */
00062 #ifdef YOTTA_CFG_BLE_INSTANCES_COUNT
00063 #define CONCATENATE(A, B) A ## B
00064 #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). */
00065 
00066 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER
00067 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER
00068 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER
00069 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER
00070 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER
00071 /* ... add more of the above if ever needed */
00072 
00073 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N))
00074 #elif !defined(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS)
00075 /*
00076  * The following applies when building without yotta. By default BLE_API provides
00077  * a trivial initializer list containing a single constructor: createBLEInstance.
00078  * This may be overridden.
00079  */
00080 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS createBLEInstance
00081 #endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */
00082 
00083 typedef BLEInstanceBase *(*InstanceConstructor_t)(void);
00084 static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = {
00085 #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
00086     INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS
00087 #else
00088     INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT)
00089 #endif
00090 };
00091 
00092 BLE &
00093 BLE::Instance(InstanceID_t id)
00094 {
00095     static BLE *singletons[NUM_INSTANCES];
00096     if (id < NUM_INSTANCES) {
00097         if (singletons[id] == NULL) {
00098             singletons[id] = new BLE(id); /* This object will never be freed. */
00099         }
00100 
00101         return *singletons[id];
00102     }
00103 
00104     /* we come here only in the case of a bad interfaceID. */
00105     static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */);
00106     return badSingleton;
00107 }
00108 
00109 BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport()
00110 {
00111     static BLEInstanceBase *transportInstances[NUM_INSTANCES];
00112 
00113     if (instanceID < NUM_INSTANCES) {
00114         if (!transportInstances[instanceID]) {
00115             transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */
00116         }
00117         transport = transportInstances[instanceID];
00118     } else {
00119         transport = NULL;
00120     }
00121 }
00122 
00123 bool BLE::hasInitialized (void) const
00124 {
00125     if (!transport) {
00126         error("bad handle to underlying transport");
00127     }
00128 
00129     return transport->hasInitialized();
00130 }
00131 
00132 ble_error_t BLE::shutdown(void)
00133 {
00134     clearAdvertisingPayload();
00135     if (!transport) {
00136         error("bad handle to underlying transport");
00137     }
00138 
00139     return transport->shutdown();
00140 }
00141 
00142 const char *BLE::getVersion(void)
00143 {
00144     if (!transport) {
00145         error("bad handle to underlying transport");
00146     }
00147 
00148     return transport->getVersion();
00149 }
00150 
00151 const Gap &BLE::gap() const
00152 {
00153     if (!transport) {
00154         error("bad handle to underlying transport");
00155     }
00156 
00157     return transport->getGap();
00158 }
00159 
00160 Gap &BLE::gap()
00161 {
00162     if (!transport) {
00163         error("bad handle to underlying transport");
00164     }
00165 
00166     return transport->getGap();
00167 }
00168 
00169 const GattServer& BLE::gattServer() const
00170 {
00171     if (!transport) {
00172         error("bad handle to underlying transport");
00173     }
00174 
00175     return transport->getGattServer();
00176 }
00177 
00178 GattServer& BLE::gattServer()
00179 {
00180     if (!transport) {
00181         error("bad handle to underlying transport");
00182     }
00183 
00184     return transport->getGattServer();
00185 }
00186 
00187 const GattClient& BLE::gattClient() const
00188 {
00189     if (!transport) {
00190         error("bad handle to underlying transport");
00191     }
00192 
00193     return transport->getGattClient();
00194 }
00195 
00196 GattClient& BLE::gattClient()
00197 {
00198     if (!transport) {
00199         error("bad handle to underlying transport");
00200     }
00201 
00202     return transport->getGattClient();
00203 }
00204 
00205 const SecurityManager& BLE::securityManager() const
00206 {
00207     if (!transport) {
00208         error("bad handle to underlying transport");
00209     }
00210 
00211     return transport->getSecurityManager();
00212 }
00213 
00214 SecurityManager& BLE::securityManager()
00215 {
00216     if (!transport) {
00217         error("bad handle to underlying transport");
00218     }
00219 
00220     return transport->getSecurityManager();
00221 }
00222 
00223 void BLE::waitForEvent(void)
00224 {
00225     if (!transport) {
00226         error("bad handle to underlying transport");
00227     }
00228 
00229     transport->waitForEvent();
00230 }