takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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 #if defined(__GNUC__) && !defined(__CC_ARM)
00035 #define BLE_DEPRECATED_API_USE_BEGIN \
00036     _Pragma("GCC diagnostic push") \
00037     _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
00038 #elif defined(__CC_ARM)
00039 #define BLE_DEPRECATED_API_USE_BEGIN \
00040     _Pragma("push") \
00041     _Pragma("diag_suppress 1361")
00042 #else
00043 #define BLE_DEPRECATED_API_USE_BEGIN
00044 #endif
00045 
00046 #if defined(__GNUC__) && !defined(__CC_ARM)
00047 #define BLE_DEPRECATED_API_USE_END \
00048     _Pragma("GCC diagnostic pop")
00049 #elif defined(__CC_ARM)
00050 #define BLE_DEPRECATED_API_USE_END \
00051         _Pragma("pop")
00052 #else
00053 #define BLE_DEPRECATED_API_USE_END
00054 #endif
00055 
00056 static const char* error_strings[] = {
00057     "BLE_ERROR_NONE: No error",
00058     "BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted",
00059     "BLE_ERROR_NOT_IMPLEMENTED: Requested a feature that isn't yet implement or isn't supported by the target HW",
00060     "BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range",
00061     "BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid",
00062     "BLE_STACK_BUSY: The stack is busy",
00063     "BLE_ERROR_INVALID_STATE: Invalid state",
00064     "BLE_ERROR_NO_MEM: Out of Memory",
00065     "BLE_ERROR_OPERATION_NOT_PERMITTED: The operation requested is not permitted",
00066     "BLE_ERROR_INITIALIZATION_INCOMPLETE: The BLE subsystem has not completed its initialisation",
00067     "BLE_ERROR_ALREADY_INITIALIZED: The BLE system has already been initialised",
00068     "BLE_ERROR_UNSPECIFIED: Unknown error",
00069     "BLE_ERROR_INTERNAL_STACK_FAILURE: The platform-specific stack failed"
00070 };
00071 
00072 const char* BLE::errorToString(ble_error_t error)
00073 {
00074     if (error > BLE_ERROR_INTERNAL_STACK_FAILURE) {
00075         return "Illegal error code";
00076     }
00077     return error_strings[error];
00078 }
00079 
00080 ble_error_t
00081 BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext*> callback)
00082 {
00083     ble_error_t err = transport->init(instanceID, callback);
00084     if (err != BLE_ERROR_NONE) {
00085         return err;
00086     }
00087 
00088     /* Platforms enabled for DFU should introduce the DFU Service into
00089      * applications automatically. */
00090 #if defined(TARGET_OTA_ENABLED)
00091     static DFUService dfu(*this); // defined static so that the object remains alive
00092 #endif // TARGET_OTA_ENABLED
00093 
00094     return BLE_ERROR_NONE;
00095 }
00096 
00097 /**
00098  * BLE::Instance() and BLE constructor rely upon a static array of initializers
00099  * to create actual BLE transport instances. A description of these instances
00100  * and initializers is supposed to be put in some .json file contributing to
00101  * yotta's configuration (typically in the target definition described by
00102  * target.json). Here's a sample:
00103  *
00104  *  "config": {
00105  *    ...
00106  *    "ble_instances": {
00107  *      "count": 1,
00108  *      "0" : {
00109  *        "initializer" : "createBLEInstance"
00110  *      }
00111  *    }
00112  *    ...
00113  *  }
00114  *
00115  * The following macros result in translating the above config into a static
00116  * array: instanceConstructors.
00117  */
00118 #ifdef YOTTA_CFG_BLE_INSTANCES_COUNT
00119 #define CONCATENATE(A, B) A ## B
00120 #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). */
00121 
00122 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER
00123 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER
00124 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER
00125 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER
00126 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER
00127 /* ... add more of the above if ever needed */
00128 
00129 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N))
00130 #elif !defined(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS)
00131 /*
00132  * The following applies when building without yotta. By default BLE_API provides
00133  * a trivial initializer list containing a single constructor: createBLEInstance.
00134  * This may be overridden.
00135  */
00136 #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS createBLEInstance
00137 
00138 // yotta unlike mbed-cli has proper dependency mechanisms
00139 // It is not required to defined a stub for createBLEInstance
00140 #if !defined(YOTTA_CFG_MBED_OS)
00141 
00142 // this stub is required by ARMCC otherwise link will systematically fail
00143 MBED_WEAK BLEInstanceBase* createBLEInstance() {
00144     MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_CREATION_FAILED), "Please provide an implementation for mbed BLE");
00145     return NULL;
00146 }
00147 
00148 #endif
00149 
00150 
00151 #endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */
00152 
00153 typedef BLEInstanceBase *(*InstanceConstructor_t)(void);
00154 static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = {
00155 #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
00156     INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS
00157 #else
00158     INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT)
00159 #endif
00160 };
00161 
00162 BLE &
00163 BLE::Instance(InstanceID_t id)
00164 {
00165     static BLE *singletons[NUM_INSTANCES];
00166     if (id < NUM_INSTANCES) {
00167         if (singletons[id] == NULL) {
00168 BLE_DEPRECATED_API_USE_BEGIN
00169             singletons[id] = new BLE(id); /* This object will never be freed. */
00170 BLE_DEPRECATED_API_USE_END
00171         }
00172 
00173         return *singletons[id];
00174     }
00175 
00176     /* we come here only in the case of a bad interfaceID. */
00177 BLE_DEPRECATED_API_USE_BEGIN
00178     static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */);
00179 BLE_DEPRECATED_API_USE_END
00180     return badSingleton;
00181 }
00182 
00183 #ifdef YOTTA_CFG_MBED_OS
00184 void defaultSchedulingCallback(BLE::OnEventsToProcessCallbackContext* params) {
00185     minar::Scheduler::postCallback(&params->ble, &BLE::processEvents);
00186 }
00187 #else
00188 #define defaultSchedulingCallback NULL
00189 #endif
00190 
00191 bool BLE::hasInitialized(void) const
00192 {
00193     if (!transport) {
00194         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00195     }
00196 
00197     return transport->hasInitialized();
00198 }
00199 
00200 ble_error_t BLE::shutdown(void)
00201 {
00202     if (!transport) {
00203         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00204     }
00205 
00206     event_signaled = false;
00207     return transport->shutdown();
00208 }
00209 
00210 const char *BLE::getVersion(void)
00211 {
00212     if (!transport) {
00213         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00214     }
00215 
00216     return transport->getVersion();
00217 }
00218 
00219 const Gap &BLE::gap() const
00220 {
00221     if (!transport) {
00222         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00223     }
00224 
00225     return transport->getGap();
00226 }
00227 
00228 Gap &BLE::gap()
00229 {
00230     if (!transport) {
00231         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00232     }
00233 
00234     return transport->getGap();
00235 }
00236 
00237 const GattServer& BLE::gattServer() const
00238 {
00239     if (!transport) {
00240         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00241     }
00242 
00243     return transport->getGattServer();
00244 }
00245 
00246 GattServer& BLE::gattServer()
00247 {
00248     if (!transport) {
00249         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00250     }
00251 
00252     return transport->getGattServer();
00253 }
00254 
00255 const GattClient& BLE::gattClient() const
00256 {
00257     if (!transport) {
00258         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00259     }
00260 
00261     return transport->getGattClient();
00262 }
00263 
00264 GattClient& BLE::gattClient()
00265 {
00266     if (!transport) {
00267         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00268     }
00269 
00270     return transport->getGattClient();
00271 }
00272 
00273 const SecurityManager& BLE::securityManager() const
00274 {
00275     if (!transport) {
00276         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00277     }
00278 
00279     return transport->getSecurityManager();
00280 }
00281 
00282 SecurityManager& BLE::securityManager()
00283 {
00284     if (!transport) {
00285         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00286     }
00287 
00288     return transport->getSecurityManager();
00289 }
00290 
00291 void BLE::waitForEvent(void)
00292 {
00293     if (!transport) {
00294         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00295     }
00296 
00297     transport->waitForEvent();
00298 }
00299 
00300 void BLE::processEvents()
00301 {
00302     if (event_signaled == false) {
00303         return;
00304     }
00305 
00306     if (!transport) {
00307         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_BLE, MBED_ERROR_CODE_BLE_BACKEND_NOT_INITIALIZED), "bad handle to underlying transport");
00308     }
00309 
00310     event_signaled = false;
00311 
00312     transport->processEvents();
00313 }
00314 
00315 void BLE::onEventsToProcess(const BLE::OnEventsToProcessCallback_t & callback)
00316 {
00317     whenEventsToProcess = callback;
00318 
00319     // If events were previously signaled but the handler was not in place then
00320     // signal immediately events availability
00321     if (event_signaled && whenEventsToProcess) {
00322         OnEventsToProcessCallbackContext params = {
00323             *this
00324         };
00325         whenEventsToProcess(&params);
00326     }
00327 }
00328 
00329 void BLE::signalEventsToProcess()
00330 {
00331     if (event_signaled == true) {
00332         return;
00333     }
00334 
00335     event_signaled = true;
00336 
00337     if (whenEventsToProcess) {
00338         OnEventsToProcessCallbackContext params = {
00339             *this
00340         };
00341         whenEventsToProcess(&params);
00342     }
00343 }
00344 
00345 // start of deprecated functions
00346 
00347 BLE_DEPRECATED_API_USE_BEGIN
00348 
00349 // NOTE: move and remove deprecation once private
00350 BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport(),
00351     whenEventsToProcess(defaultSchedulingCallback),
00352     event_signaled(false)
00353 {
00354     static BLEInstanceBase *transportInstances[NUM_INSTANCES];
00355 
00356     if (instanceID < NUM_INSTANCES) {
00357         if (!transportInstances[instanceID]) {
00358             transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */
00359         }
00360         transport = transportInstances[instanceID];
00361     } else {
00362         transport = NULL;
00363     }
00364 }
00365 
00366 ble_error_t BLE::setAddress(
00367     BLEProtocol::AddressType_t type,
00368     const BLEProtocol::AddressBytes_t address
00369 ) {
00370     return gap().setAddress(type, address);
00371 }
00372 
00373 ble_error_t BLE::connect(
00374     const BLEProtocol::AddressBytes_t peerAddr,
00375     BLEProtocol::AddressType_t peerAddrType,
00376     const Gap::ConnectionParams_t *connectionParams,
00377     const GapScanningParams *scanParams
00378 ) {
00379     return gap().connect(peerAddr, peerAddrType, connectionParams, scanParams);
00380 }
00381 
00382 ble_error_t BLE::disconnect(Gap::DisconnectionReason_t reason) {
00383     return gap().disconnect(reason);
00384 }
00385 
00386 BLE_DEPRECATED_API_USE_END
00387