Holla back

Fork of BLE_API by Bluetooth Low Energy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BLEDevice.h Source File

BLEDevice.h

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 #ifndef __BLE_DEVICE__
00018 #define __BLE_DEVICE__
00019 
00020 #include "mbed.h"
00021 #include "blecommon.h"
00022 #include "Gap.h"
00023 #include "GattServer.h"
00024 #include "BLEDeviceInstanceBase.h"
00025 
00026 /**
00027  * The base class used to abstract away BLE capable radio transceivers or SOCs,
00028  * to enable this BLE API to work with any radio transparently.
00029  */
00030 class BLEDevice
00031 {
00032 public:
00033     /**
00034      * Initialize the BLE controller. This should be called before using
00035      * anything else in the BLE_API.
00036      */
00037     ble_error_t init();
00038     ble_error_t reset(void);
00039 
00040     /* GAP specific APIs */
00041 public:
00042     /**
00043      * Set the BTLE MAC address and type.
00044      * @return
00045      */
00046     ble_error_t setAddress(Gap::addr_type_t type, const uint8_t address[6]);
00047 
00048     /**
00049      * @param[in] advType
00050      *              The GAP advertising mode to use for this device. Valid
00051      *              values are defined in AdvertisingType:
00052      *
00053      *              \par ADV_NON_CONNECTABLE_UNDIRECTED
00054      *              All connections to the peripheral device will be refused.
00055      *
00056      *              \par ADV_CONNECTABLE_DIRECTED
00057      *              Only connections from a pre-defined central device will be
00058      *              accepted.
00059      *
00060      *              \par ADV_CONNECTABLE_UNDIRECTED
00061      *              Any central device can connect to this peripheral.
00062      *
00063      *              \par ADV_SCANNABLE_UNDIRECTED
00064      *              Any central device can connect to this peripheral, and
00065      *              the secondary Scan Response payload will be included or
00066      *              available to central devices.
00067      *
00068      *              \par
00069      *              See Bluetooth Core Specification 4.0 (Vol. 3), Part C,
00070      *              Section 9.3 and Core Specification 4.0 (Vol. 6), Part B,
00071      *              Section 2.3.1 for further information on GAP connection
00072      *              modes
00073      */
00074     void        setAdvertisingType (GapAdvertisingParams::AdvertisingType);
00075 
00076     /**
00077      * @param[in] interval
00078      *              Advertising interval between 0x0020 and 0x4000 in 0.625ms
00079      *              units (20ms to 10.24s).  If using non-connectable mode
00080      *              (ADV_NON_CONNECTABLE_UNDIRECTED) this min value is
00081      *              0x00A0 (100ms). To reduce the likelihood of collisions, the
00082      *              link layer perturbs this interval by a pseudo-random delay
00083      *              with a range of 0 ms to 10 ms for each advertising event.
00084      *
00085      *              \par
00086      *              Decreasing this value will allow central devices to detect
00087      *              your peripheral faster at the expense of more power being
00088      *              used by the radio due to the higher data transmit rate.
00089      *
00090      *              \par
00091      *              This field must be set to 0 if connectionMode is equal
00092      *              to ADV_CONNECTABLE_DIRECTED
00093      *
00094      *              \par
00095      *              See Bluetooth Core Specification, Vol 3., Part C,
00096      *              Appendix A for suggested advertising intervals.
00097      */
00098     void        setAdvertisingInterval (uint16_t interval);
00099 
00100     /**
00101      * @param[in] timeout
00102      *              Advertising timeout between 0x1 and 0x3FFF (1 and 16383)
00103      *              in seconds.  Enter 0 to disable the advertising timeout.
00104      */
00105     void        setAdvertisingTimeout (uint16_t timeout);
00106 
00107     /**
00108      * Please refer to the APIs above.
00109      */
00110     void        setAdvertisingParams(const GapAdvertisingParams &advParams);
00111 
00112     /**
00113      * This API is typically used as an internal helper to udpate the transport
00114      * backend with advertising data before starting to advertise. It may also
00115      * be explicity used to dynamically reset the accumulated advertising
00116      * payload and scanResponse; to do this, the application can clear and re-
00117      * accumulate a new advertising payload (and scanResponse) before using this
00118      * API.
00119      */
00120     ble_error_t setAdvertisingPayload(void);
00121 
00122     /**
00123      * Reset any advertising payload prepared from prior calls to
00124      * accumulateAdvertisingPayload().
00125      */
00126     void        clearAdvertisingPayload(void);
00127 
00128     /**
00129      * Accumulate an AD structure in the advertising payload. Please note that
00130      * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
00131      * as an additional 31 bytes if the advertising payload proves to be too
00132      * small.
00133      *
00134      * @param  flags
00135      *         The flags to be added. Multiple flags may be specified in
00136      *         combination.
00137      */
00138     ble_error_t accumulateAdvertisingPayload(uint8_t flags);
00139 
00140     /**
00141      * Accumulate an AD structure in the advertising payload. Please note that
00142      * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
00143      * as an additional 31 bytes if the advertising payload proves to be too
00144      * small.
00145      *
00146      * @param  app
00147      *         The appearance of the peripheral.
00148      */
00149     ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app);
00150 
00151     /**
00152      * Accumulate an AD structure in the advertising payload. Please note that
00153      * the payload is limited to 31 bytes. The SCAN_RESPONSE message may be used
00154      * as an additional 31 bytes if the advertising payload proves to be too
00155      * small.
00156      *
00157      * @param  app
00158      *         The max transmit power to be used by the controller. This is
00159      *         only a hint.
00160      */
00161     ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power);
00162 
00163     /**
00164      * Accumulate a variable length byte-stream as an AD structure in the
00165      * advertising payload. Please note that the payload is limited to 31 bytes.
00166      * The SCAN_RESPONSE message may be used as an additional 31 bytes if the
00167      * advertising payload proves to be too small.
00168      *
00169      * @param  type The type which describes the variable length data.
00170      * @param  data data bytes.
00171      * @param  len  length of data.
00172      */
00173     ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len);
00174 
00175     /**
00176      * Accumulate a variable length byte-stream as an AD structure in the
00177      * scanResponse payload.
00178      *
00179      * @param  type The type which describes the variable length data.
00180      * @param  data data bytes.
00181      * @param  len  length of data.
00182      */
00183     ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len);
00184 
00185     /**
00186      * Start advertising (GAP Discoverable, Connectable modes, Broadcast
00187      * Procedure).
00188      */
00189     ble_error_t startAdvertising(void);
00190 
00191     /**
00192      * Stop advertising (GAP Discoverable, Connectable modes, Broadcast
00193      * Procedure).
00194      */
00195     ble_error_t stopAdvertising(void);
00196 
00197     ble_error_t disconnect(Gap::DisconnectionReason_t reason);
00198 
00199     /* APIs to set GAP callbacks. */
00200     void onTimeout(Gap::EventCallback_t timeoutCallback);
00201 
00202     void onConnection(void (*callback)(Gap::Handle_t handle, const Gap::ConnectionParams_t *eventDataP));
00203     template <typename T> void onConnection(T *objPtr, void (T::*memberPtr)(Gap::Handle_t handle, const Gap::ConnectionParams_t *context));
00204 
00205     /**
00206      * Used to setup a callback for GAP disconnection.
00207      */
00208      void onDisconnection(void (*callback)(Gap::Handle_t handle, Gap::DisconnectionReason_t reason));
00209      template <typename T> void onDisconnection(T *objPtr, void (T::*memberPtr)(Gap::Handle_t handle, Gap::DisconnectionReason_t reason));
00210 
00211     /**
00212      * Setup a callback for the GATT event DATA_SENT.
00213      */
00214     void onDataSent(GattServer::ServerEventCallbackWithCount_t callback);
00215 
00216     /**
00217      * Setup a callback for when a characteristic has its value updated by a
00218      * client.
00219      *
00220      * @Note: it is possible to chain together multiple onDataWritten callbacks
00221      * (potentially from different modules of an application) to receive updates
00222      * to characteristics. Many services, such as DFU and UART add their own
00223      * onDataWritten callbacks behind the scenes to trap interesting events.
00224      *
00225      * @Note: it is also possible to setup a callback into a member function of
00226      * some object.
00227      */
00228     void onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP));
00229     template <typename T> void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context));
00230 
00231     void onUpdatesEnabled(GattServer::EventCallback_t callback);
00232     void onUpdatesDisabled(GattServer::EventCallback_t callback);
00233     void onConfirmationReceived(GattServer::EventCallback_t callback);
00234 
00235     /**
00236      * Add a service declaration to the local server ATT table. Also add the
00237      * characteristics contained within.
00238      */
00239     ble_error_t addService(GattService &service);
00240 
00241     Gap::GapState_t getGapState(void) const;
00242 
00243     /**
00244      * @param[in/out]  lengthP
00245      *     input:  Length in bytes to be read,
00246      *     output: Total length of attribute value upon successful return.
00247      */
00248     ble_error_t readCharacteristicValue (uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP);
00249 
00250     /**
00251      * @param  localOnly
00252      *         Only update the characteristic locally regardless of notify/indicate flags in the CCCD.
00253      */
00254     ble_error_t updateCharacteristicValue (uint16_t handle, const uint8_t* value, uint16_t size, bool localOnly = false);
00255 
00256     /**
00257      * Yield control to the BLE stack or to other tasks waiting for events. This
00258      * is a sleep function which will return when there is an application
00259      * specific interrupt, but the MCU might wake up several times before
00260      * returning (to service the stack). This is not always interchangeable with
00261      * WFE().
00262      */
00263     void waitForEvent(void);
00264 
00265     ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params);
00266     ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params);
00267     ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params);
00268 
00269     /**
00270      * This call allows the application to get the BLE stack version information.
00271      *
00272      * @return  A pointer to a const string representing the version.
00273      *          Note: The string is owned by the BLE_API.
00274      */
00275     const char *getVersion(void);
00276 
00277      /**
00278       * Set the device name characteristic in the GAP service.
00279       * @param  deviceName The new value for the device-name. This is a UTF-8 encoded, <b>NULL-terminated</b> string.
00280       */
00281      ble_error_t setDeviceName(const uint8_t *deviceName);
00282 
00283      /**
00284       * Get the value of the device name characteristic in the GAP service.
00285       * @param[out]    deviceName Pointer to an empty buffer where the UTF-8 *non NULL-
00286       *                           terminated* string will be placed. Set this
00287       *                           value to NULL in order to obtain the deviceName-length
00288       *                           from the 'length' parameter.
00289       *
00290       * @param[in/out] lengthP    (on input) Length of the buffer pointed to by deviceName;
00291       *                           (on output) the complete device name length (without the
00292       *                           null terminator).
00293       *
00294       * @note          If the device name is longer than the size of the supplied buffer,
00295       *                length will return the complete device name length,
00296       *                and not the number of bytes actually returned in deviceName.
00297       *                The application may use this information to retry with a suitable buffer size.
00298       *
00299       * Sample use:
00300       *     uint8_t deviceName[20];
00301       *     unsigned length = sizeof(deviceName);
00302       *     ble.getDeviceName(deviceName, &length);
00303       *     if (length < sizeof(deviceName)) {
00304       *         deviceName[length] = 0;
00305       *     }
00306       *     DEBUG("length: %u, deviceName: %s\r\n", length, deviceName);
00307       */
00308      ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP);
00309 
00310      /**
00311       * Set the appearance characteristic in the GAP service.
00312       * @param[in]  appearance The new value for the device-appearance.
00313       */
00314      ble_error_t setAppearance(uint16_t appearance);
00315 
00316      /**
00317       * Set the appearance characteristic in the GAP service.
00318       * @param[out]  appearance The new value for the device-appearance.
00319       */
00320      ble_error_t getAppearance(uint16_t *appearanceP);
00321 
00322      /**
00323       * Set the radio's transmit power.
00324       * @param[in] txPower Radio transmit power in dBm.
00325       */
00326      ble_error_t setTxPower(int8_t txPower);
00327 
00328 public:
00329     BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true) {
00330         advPayload.clear();
00331         scanResponse.clear();
00332     }
00333 
00334 private:
00335     BLEDeviceInstanceBase *const transport; /* the device specific backend */
00336 
00337     GapAdvertisingParams advParams;
00338     GapAdvertisingData   advPayload;
00339     GapAdvertisingData   scanResponse;
00340 
00341     /* Accumulation of AD structures in the advertisement payload should
00342      * eventually result in a call to the target's setAdvertisingData() before
00343      * the server begins advertising. This flag marks the status of the pending update.*/
00344     bool                 needToSetAdvPayload;
00345 
00346     /**
00347      * DEPRECATED
00348      */
00349 public:
00350     ble_error_t setAdvertisingData(const GapAdvertisingData &ADStructures, const GapAdvertisingData &scanResponse);
00351     ble_error_t setAdvertisingData(const GapAdvertisingData &ADStructures);
00352 
00353     ble_error_t startAdvertising(const GapAdvertisingParams &advParams);
00354 };
00355 
00356 /* BLEDevice methods. Most of these simply forward the calls to the underlying
00357  * transport.*/
00358 
00359 inline ble_error_t
00360 BLEDevice::reset(void)
00361 {
00362     return transport->reset();
00363 }
00364 
00365 inline ble_error_t
00366 BLEDevice::setAddress(Gap::addr_type_t type, const uint8_t address[6])
00367 {
00368     return transport->getGap().setAddress(type, address);
00369 }
00370 
00371 inline void
00372 BLEDevice::setAdvertisingType (GapAdvertisingParams::AdvertisingType advType)
00373 {
00374     advParams.setAdvertisingType(advType);
00375 }
00376 
00377 inline void
00378 BLEDevice::setAdvertisingInterval (uint16_t interval)
00379 {
00380     advParams.setInterval(interval);
00381 }
00382 
00383 inline void
00384 BLEDevice::setAdvertisingTimeout (uint16_t timeout)
00385 {
00386     advParams.setTimeout(timeout);
00387 }
00388 
00389 inline void
00390 BLEDevice::setAdvertisingParams(const GapAdvertisingParams &newAdvParams)
00391 {
00392     advParams = newAdvParams;
00393 }
00394 
00395 inline void
00396 BLEDevice::clearAdvertisingPayload(void)
00397 {
00398     needToSetAdvPayload = true;
00399     advPayload.clear();
00400 }
00401 
00402 inline ble_error_t
00403 BLEDevice::accumulateAdvertisingPayload(uint8_t flags)
00404 {
00405     needToSetAdvPayload = true;
00406     return advPayload.addFlags(flags);
00407 }
00408 
00409 inline ble_error_t
00410 BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app)
00411 {
00412     needToSetAdvPayload = true;
00413     return advPayload.addAppearance(app);
00414 }
00415 
00416 inline ble_error_t
00417 BLEDevice::accumulateAdvertisingPayloadTxPower(int8_t txPower)
00418 {
00419     needToSetAdvPayload = true;
00420     return advPayload.addTxPower(txPower);
00421 }
00422 
00423 inline ble_error_t
00424 BLEDevice::accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len)
00425 {
00426     needToSetAdvPayload = true;
00427     return advPayload.addData(type, data, len);
00428 }
00429 
00430 inline ble_error_t
00431 BLEDevice::accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len)
00432 {
00433     needToSetAdvPayload = true;
00434     return scanResponse.addData(type, data, len);
00435 }
00436 
00437 inline ble_error_t
00438 BLEDevice::setAdvertisingPayload(void) {
00439     needToSetAdvPayload = false;
00440     return transport->getGap().setAdvertisingData(advPayload, scanResponse);
00441 }
00442 
00443 inline ble_error_t
00444 BLEDevice::startAdvertising(void)
00445 {
00446     if (needToSetAdvPayload) {
00447         ble_error_t rc;
00448         if ((rc = setAdvertisingPayload()) != BLE_ERROR_NONE) {
00449             return rc;
00450         }
00451     }
00452 
00453     return transport->getGap().startAdvertising(advParams);
00454 }
00455 
00456 inline ble_error_t
00457 BLEDevice::stopAdvertising(void)
00458 {
00459     return transport->getGap().stopAdvertising();
00460 }
00461 
00462 inline ble_error_t
00463 BLEDevice::disconnect(Gap::DisconnectionReason_t reason)
00464 {
00465     return transport->getGap().disconnect(reason);
00466 }
00467 
00468 inline void
00469 BLEDevice::onTimeout(Gap::EventCallback_t timeoutCallback)
00470 {
00471     transport->getGap().setOnTimeout(timeoutCallback);
00472 }
00473 
00474 inline void
00475 BLEDevice::onConnection(void (*callback)(Gap::Handle_t handle, const Gap::ConnectionParams_t *eventDataP)) {
00476     transport->getGap().setOnConnection(callback);
00477 }
00478 
00479 template <typename T> inline void
00480 BLEDevice::onConnection(T *objPtr, void (T::*memberPtr)(Gap::Handle_t handle, const Gap::ConnectionParams_t *context)) {
00481     transport->getGap().setOnConnection(objPtr, memberPtr);
00482 }
00483 
00484 inline void
00485 BLEDevice::onDisconnection(void (*callback)(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)) {
00486     transport->getGap().setOnDisconnection(callback);
00487 }
00488 
00489 template <typename T> inline void
00490 BLEDevice::onDisconnection(T *objPtr, void (T::*memberPtr)(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)) {
00491     transport->getGap().setOnDisconnection(objPtr, memberPtr);
00492 }
00493 
00494 inline void
00495 BLEDevice::onDataSent(GattServer::ServerEventCallbackWithCount_t callback)
00496 {
00497     transport->getGattServer().setOnDataSent(callback);
00498 }
00499 
00500 inline void
00501 BLEDevice::onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)) {
00502     transport->getGattServer().setOnDataWritten(callback);
00503 }
00504 
00505 template <typename T> inline void
00506 BLEDevice::onDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) {
00507     transport->getGattServer().setOnDataWritten(objPtr, memberPtr);
00508 }
00509 
00510 
00511 inline void
00512 BLEDevice::onUpdatesEnabled(GattServer::EventCallback_t callback)
00513 {
00514     transport->getGattServer().setOnUpdatesEnabled(callback);
00515 }
00516 
00517 inline void
00518 BLEDevice::onUpdatesDisabled(GattServer::EventCallback_t callback)
00519 {
00520     transport->getGattServer().setOnUpdatesDisabled(callback);
00521 }
00522 
00523 inline void
00524 BLEDevice::onConfirmationReceived(GattServer::EventCallback_t callback)
00525 {
00526     transport->getGattServer().setOnConfirmationReceived(callback);
00527 }
00528 
00529 inline ble_error_t
00530 BLEDevice::addService(GattService &service)
00531 {
00532     return transport->getGattServer().addService(service);
00533 }
00534 
00535 inline Gap::GapState_t
00536 BLEDevice::getGapState(void) const
00537 {
00538     return transport->getGap().getState();
00539 }
00540 
00541 inline ble_error_t BLEDevice::readCharacteristicValue (uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP)
00542 {
00543     return transport->getGattServer().readValue(handle, buffer, lengthP);
00544 }
00545 
00546 inline ble_error_t
00547 BLEDevice::updateCharacteristicValue (uint16_t handle, const uint8_t* value, uint16_t size, bool localOnly)
00548 {
00549     return transport->getGattServer().updateValue(handle, const_cast<uint8_t *>(value), size, localOnly);
00550 }
00551 
00552 inline void
00553 BLEDevice::waitForEvent(void)
00554 {
00555     transport->waitForEvent();
00556 }
00557 
00558 inline ble_error_t
00559 BLEDevice::getPreferredConnectionParams(Gap::ConnectionParams_t *params)
00560 {
00561     return transport->getGap().getPreferredConnectionParams(params);
00562 }
00563 
00564 inline ble_error_t
00565 BLEDevice::setPreferredConnectionParams(const Gap::ConnectionParams_t *params)
00566 {
00567     return transport->getGap().setPreferredConnectionParams(params);
00568 }
00569 
00570 inline ble_error_t
00571 BLEDevice::updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) {
00572     return transport->getGap().updateConnectionParams(handle, params);
00573 }
00574 
00575 inline const char *
00576 BLEDevice::getVersion(void)
00577 {
00578     return transport->getVersion();
00579 }
00580 
00581 inline ble_error_t
00582 BLEDevice::setDeviceName(const uint8_t *deviceName)
00583 {
00584     return transport->getGap().setDeviceName(deviceName);
00585 }
00586 
00587 inline ble_error_t
00588 BLEDevice::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
00589 {
00590     return transport->getGap().getDeviceName(deviceName, lengthP);
00591 }
00592 
00593 inline ble_error_t
00594 BLEDevice::setAppearance(uint16_t appearance)
00595 {
00596     return transport->getGap().setAppearance(appearance);
00597 }
00598 
00599 inline ble_error_t
00600 BLEDevice::getAppearance(uint16_t *appearanceP)
00601 {
00602     return transport->getGap().getAppearance(appearanceP);
00603 }
00604 
00605 inline ble_error_t
00606 BLEDevice::setTxPower(int8_t txPower)
00607 {
00608     return transport->setTxPower(txPower);
00609 }
00610 
00611 /*
00612  * ALL OF THE FOLLOWING METHODS ARE DEPRECATED
00613  */
00614 
00615 inline ble_error_t
00616 BLEDevice::setAdvertisingData(const GapAdvertisingData &ADStructures, const GapAdvertisingData &scanResponse)
00617 {
00618     needToSetAdvPayload = false;
00619     return transport->getGap().setAdvertisingData(ADStructures, scanResponse);
00620 }
00621 
00622 inline ble_error_t
00623 BLEDevice::setAdvertisingData(const GapAdvertisingData &ADStructures)
00624 {
00625     GapAdvertisingData scanResponse;
00626 
00627     needToSetAdvPayload = false;
00628     return transport->getGap().setAdvertisingData(ADStructures, scanResponse);
00629 }
00630 
00631 inline ble_error_t
00632 BLEDevice::startAdvertising(const GapAdvertisingParams &_advParams)
00633 {
00634     return transport->getGap().startAdvertising(_advParams);
00635 }
00636 
00637 #endif // ifndef __BLE_DEVICE__