High level Bluetooth Low Energy API and radio abstraction layer
Fork of BLE_API by
Diff: ble/Gap.h
- Revision:
- 1135:22aada733dbd
- Parent:
- 1134:d540a48f650d
- Child:
- 1156:e1ea38b576c6
diff -r d540a48f650d -r 22aada733dbd ble/Gap.h --- a/ble/Gap.h Wed Apr 06 19:13:52 2016 +0100 +++ b/ble/Gap.h Wed Apr 06 19:13:54 2016 +0100 @@ -17,12 +17,14 @@ #ifndef __GAP_H__ #define __GAP_H__ +#include "ble/BLEProtocol.h" #include "GapAdvertisingData.h" #include "GapAdvertisingParams.h" #include "GapScanningParams.h" #include "GapEvents.h" #include "CallChainOfFunctionPointersWithContext.h" #include "FunctionPointerWithContext.h" +#include "deprecate.h" /* Forward declarations for classes that will only be used for pointers or references in the following. */ class GapAdvertisingParams; @@ -30,19 +32,44 @@ class GapAdvertisingData; class Gap { + /* + * DEPRECATION ALERT: all of the APIs in this `public` block are deprecated. + * They have been relocated to the class BLEProtocol. + */ public: - enum AddressType_t { - ADDR_TYPE_PUBLIC = 0, - ADDR_TYPE_RANDOM_STATIC, - ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, - ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE + /** + * Address-type for BLEProtocol addresses. + * + * @note: deprecated. Use BLEProtocol::AddressType_t instead. + */ + typedef BLEProtocol::AddressType_t AddressType_t; + + /** + * Address-type for BLEProtocol addresses. + * @note: deprecated. Use BLEProtocol::AddressType_t instead. + */ + typedef BLEProtocol::AddressType_t addr_type_t; + + /** + * Address-type for BLEProtocol addresses. + * \deprecated: Use BLEProtocol::AddressType_t instead. + * + * DEPRECATION ALERT: The following constants have been left in their + * deprecated state to transparenly support existing applications which may + * have used Gap::ADDR_TYPE_*. + */ + enum DeprecatedAddressType_t { + ADDR_TYPE_PUBLIC = BLEProtocol::AddressType::PUBLIC, + ADDR_TYPE_RANDOM_STATIC = BLEProtocol::AddressType::RANDOM_STATIC, + ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE = BLEProtocol::AddressType::RANDOM_PRIVATE_RESOLVABLE, + ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE }; - typedef enum AddressType_t addr_type_t; /* @Note: Deprecated. Use AddressType_t instead. */ - static const unsigned ADDR_LEN = 6; - typedef uint8_t Address_t[ADDR_LEN]; /* 48-bit address, LSB format. */ - typedef Address_t address_t; /* @Note: Deprecated. Use Address_t instead. */ + static const unsigned ADDR_LEN = BLEProtocol::ADDR_LEN; /**< Length (in octets) of the BLE MAC address. */ + typedef BLEProtocol::AddressBytes_t Address_t; /**< 48-bit address, LSB format. @Note: Deprecated. Use BLEProtocol::AddressBytes_t instead. */ + typedef BLEProtocol::AddressBytes_t address_t; /**< 48-bit address, LSB format. @Note: Deprecated. Use BLEProtocol::AddressBytes_t instead. */ +public: enum TimeoutSource_t { TIMEOUT_SRC_ADVERTISING = 0x00, /**< Advertising timeout. */ TIMEOUT_SRC_SECURITY_REQUEST = 0x01, /**< Security request timeout. */ @@ -66,6 +93,56 @@ CONN_INTERVAL_UNACCEPTABLE = 0x3B, }; + /** + * Enumeration for whitelist advertising policy filter modes. The possible + * filter modes were obtained from the Bluetooth Core Specification + * 4.2 (Vol. 6), Part B, Section 4.3.2. + * + * @experimental + */ + enum AdvertisingPolicyMode_t { + ADV_POLICY_IGNORE_WHITELIST = 0, + ADV_POLICY_FILTER_SCAN_REQS = 1, + ADV_POLICY_FILTER_CONN_REQS = 2, + ADV_POLICY_FILTER_ALL_REQS = 3, + }; + + /** + * Enumeration for whitelist scanning policy filter modes. The possible + * filter modes were obtained from the Bluetooth Core Specification + * 4.2 (Vol. 6), Part B, Section 4.3.3. + * + * @experimental + */ + enum ScanningPolicyMode_t { + SCAN_POLICY_IGNORE_WHITELIST = 0, + SCAN_POLICY_FILTER_ALL_ADV = 1, + }; + + /** + * Enumeration for the whitelist initiator policy fiter modes. The possible + * filter modes were obtained from the Bluetooth Core Specification + * 4.2 (vol. 6), Part B, Section 4.4.4. + * + * @experimental + */ + enum InitiatorPolicyMode_t { + INIT_POLICY_IGNORE_WHITELIST = 0, + INIT_POLICY_FILTER_ALL_ADV = 1, + }; + + /** + * Representation of a Bluetooth Low Enery Whitelist containing addresses. + * + * @experimental + */ + struct Whitelist_t { + BLEProtocol::Address_t *addresses; + uint8_t size; + uint8_t capacity; + }; + + /* Describes the current state of the device (more than one bit can be set). */ struct GapState_t { unsigned advertising : 1; /**< Peripheral is currently advertising. */ @@ -75,9 +152,9 @@ typedef uint16_t Handle_t; /* Type for connection handle. */ typedef struct { - uint16_t minConnectionInterval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t maxConnectionInterval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t slaveLatency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t minConnectionInterval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t maxConnectionInterval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t slaveLatency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ uint16_t connectionSupervisionTimeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ } ConnectionParams_t; @@ -87,31 +164,31 @@ }; struct AdvertisementCallbackParams_t { - Address_t peerAddr; - int8_t rssi; - bool isScanResponse; - GapAdvertisingParams::AdvertisingType_t type; - uint8_t advertisingDataLen; - const uint8_t *advertisingData; + BLEProtocol::AddressBytes_t peerAddr; + int8_t rssi; + bool isScanResponse; + GapAdvertisingParams::AdvertisingType_t type; + uint8_t advertisingDataLen; + const uint8_t *advertisingData; }; typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t; struct ConnectionCallbackParams_t { - Handle_t handle; - Role_t role; - AddressType_t peerAddrType; - Address_t peerAddr; - AddressType_t ownAddrType; - Address_t ownAddr; - const ConnectionParams_t *connectionParams; + Handle_t handle; + Role_t role; + BLEProtocol::AddressType_t peerAddrType; + BLEProtocol::AddressBytes_t peerAddr; + BLEProtocol::AddressType_t ownAddrType; + BLEProtocol::AddressBytes_t ownAddr; + const ConnectionParams_t *connectionParams; - ConnectionCallbackParams_t(Handle_t handleIn, - Role_t roleIn, - AddressType_t peerAddrTypeIn, - const uint8_t *peerAddrIn, - AddressType_t ownAddrTypeIn, - const uint8_t *ownAddrIn, - const ConnectionParams_t *connectionParamsIn) : + ConnectionCallbackParams_t(Handle_t handleIn, + Role_t roleIn, + BLEProtocol::AddressType_t peerAddrTypeIn, + const uint8_t *peerAddrIn, + BLEProtocol::AddressType_t ownAddrTypeIn, + const uint8_t *ownAddrIn, + const ConnectionParams_t *connectionParamsIn) : handle(handleIn), role(roleIn), peerAddrType(peerAddrTypeIn), @@ -151,17 +228,20 @@ typedef FunctionPointerWithContext<bool> RadioNotificationEventCallback_t; + typedef FunctionPointerWithContext<const Gap *> GapShutdownCallback_t; + typedef CallChainOfFunctionPointersWithContext<const Gap *> GapShutdownCallbackChain_t; + /* * The following functions are meant to be overridden in the platform-specific sub-class. */ public: /** * Set the BTLE MAC address and type. Please note that the address format is - * least significant byte first (LSB). Please refer to Address_t. + * least significant byte first (LSB). Please refer to BLEProtocol::AddressBytes_t. * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t setAddress(AddressType_t type, const Address_t address) { + virtual ble_error_t setAddress(BLEProtocol::AddressType_t type, const BLEProtocol::AddressBytes_t address) { /* avoid compiler warnings about unused variables */ (void)type; (void)address; @@ -174,7 +254,7 @@ * * @return BLE_ERROR_NONE on success. */ - virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) { + virtual ble_error_t getAddress(BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address) { /* Avoid compiler warnings about unused variables. */ (void)typeP; (void)address; @@ -233,10 +313,10 @@ * successfully. The connectionCallChain (if set) will be invoked upon * a connection event. */ - virtual ble_error_t connect(const Address_t peerAddr, - Gap::AddressType_t peerAddrType, - const ConnectionParams_t *connectionParams, - const GapScanningParams *scanParams) { + virtual ble_error_t connect(const BLEProtocol::AddressBytes_t peerAddr, + BLEProtocol::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) { /* Avoid compiler warnings about unused variables. */ (void)peerAddr; (void)peerAddrType; @@ -247,6 +327,23 @@ } /** + * Create a connection (GAP Link Establishment). + * + * \deprecated: This funtion overloads Gap::connect(const BLEProtocol::Address_t peerAddr, + BLEProtocol::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) + * to maintain backward compatibility for change from Gap::AddressType_t to BLEProtocol::AddressType_t + */ + ble_error_t connect(const BLEProtocol::AddressBytes_t peerAddr, + DeprecatedAddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) + __deprecated_message("Gap::DeprecatedAddressType_t is deprecated, use BLEProtocol::AddressType_t instead") { + return connect(peerAddr, (BLEProtocol::AddressType_t) peerAddrType, connectionParams, scanParams); + } + + /** * This call initiates the disconnection procedure, and its completion will * be communicated to the application with an invocation of the * disconnectionCallback. @@ -425,6 +522,156 @@ *countP = 0; /* Requesting action from porter(s): override this API if this capability is supported. */ } + /** + * @return Maximum size of the whitelist. + * + * @experimental + */ + virtual uint8_t getMaxWhitelistSize(void) const + { + return 0; + } + + /** + * Get the internal whitelist to be used by the Link Layer when scanning, + * advertising or initiating a connection depending on the filter policies. + * + * @param[in/out] whitelist + * (on input) whitelist.capacity contains the maximum number + * of addresses to be returned. + * (on output) The populated whitelist with copies of the + * addresses in the implementation's whitelist. + * + * @return BLE_ERROR_NONE if the implementation's whitelist was successfully + * copied into the supplied reference. + * + * @experimental + */ + virtual ble_error_t getWhitelist(Whitelist_t &whitelist) const + { + (void) whitelist; + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /** + * Set the internal whitelist to be used by the Link Layer when scanning, + * advertising or initiating a connection depending on the filter policies. + * + * @param[in] whitelist + * A reference to a whitelist containing the addresses to + * be added to the internal whitelist. + * + * @return BLE_ERROR_NONE if the implementation's whitelist was successfully + * populated with the addresses in the given whitelist. + * + * @note The whitelist must not contain addresses of type @ref + * BLEProtocol::AddressType_t::RANDOM_PRIVATE_NON_RESOLVABLE, this + * this will result in a @ref BLE_ERROR_INVALID_PARAM since the + * remote peer might change its private address at any time and it + * is not possible to resolve it. + * @note If the input whitelist is larger than @ref getMaxWhitelistSize() + * the @ref BLE_ERROR_PARAM_OUT_OF_RANGE is returned. + * + * @experimental + */ + virtual ble_error_t setWhitelist(const Whitelist_t &whitelist) + { + (void) whitelist; + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /** + * Set the advertising policy filter mode to be used in the next call + * to startAdvertising(). + * + * @param[in] mode + * The new advertising policy filter mode. + * + * @return BLE_ERROR_NONE if the specified policy filter mode was set + * successfully. + * + * @experimental + */ + virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode) + { + (void) mode; + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /** + * Set the scan policy filter mode to be used in the next call + * to startScan(). + * + * @param[in] mode + * The new scan policy filter mode. + * + * @return BLE_ERROR_NONE if the specified policy filter mode was set + * successfully. + * + * @experimental + */ + virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode) + { + (void) mode; + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /** + * Set the initiator policy filter mode to be used. + * + * @param[in] mode + * The new initiator policy filter mode. + * + * @return BLE_ERROR_NONE if the specified policy filter mode was set + * successfully. + * + * @experimental + */ + virtual ble_error_t setInitiatorPolicyMode(InitiatorPolicyMode_t mode) + { + (void) mode; + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /** + * Get the advertising policy filter mode that will be used in the next + * call to startAdvertising(). + * + * @return The set advertising policy filter mode. + * + * @experimental + */ + virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const + { + return ADV_POLICY_IGNORE_WHITELIST; + } + + /** + * Get the scan policy filter mode that will be used in the next + * call to startScan(). + * + * @return The set scan policy filter mode. + * + * @experimental + */ + virtual ScanningPolicyMode_t getScanningPolicyMode(void) const + { + return SCAN_POLICY_IGNORE_WHITELIST; + } + + /** + * Get the initiator policy filter mode that will be used. + * + * @return The set scan policy filter mode. + * + * @experimental + */ + virtual InitiatorPolicyMode_t getInitiatorPolicyMode(void) const + { + return INIT_POLICY_IGNORE_WHITELIST; + } + + protected: /* Override the following in the underlying adaptation layer to provide the functionality of scanning. */ virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) { @@ -575,6 +822,16 @@ * @param type The type describing the variable length data. * @param data Data bytes. * @param len Length of data. + * + * @return BLE_ERROR_NONE if the advertisement payload was updated based on + * matching AD type; otherwise, an appropriate error. + * + * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS, + * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS, + * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS, + * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the + * supplied value is appended to the values previously added to the + * payload. */ ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { @@ -591,8 +848,7 @@ /** * Update a particular ADV field in the advertising payload (based on - * matching type and length). Note: the length of the new data must be the - * same as the old one. + * matching type). * * @param[in] type The ADV type field describing the variable length data. * @param[in] data Data bytes. @@ -601,7 +857,7 @@ * @note: If advertisements are enabled, then the update will take effect immediately. * * @return BLE_ERROR_NONE if the advertisement payload was updated based on - * a <type, len> match; otherwise, an appropriate error. + * matching AD type; otherwise, an appropriate error. */ ble_error_t updateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { @@ -983,6 +1239,80 @@ radioNotificationCallback.attach(tptr, mptr); } + /** + * Setup a callback to be invoked to notify the user application that the + * Gap instance is about to shutdown (possibly as a result of a call + * to BLE::shutdown()). + * + * @Note: It is possible to chain together multiple onShutdown callbacks + * (potentially from different modules of an application) to be notified + * before the Gap instance is shutdown. + * + * @Note: It is also possible to set up a callback into a member function of + * some object. + * + * @Note It is possible to unregister a callback using onShutdown().detach(callback) + */ + void onShutdown(const GapShutdownCallback_t& callback) { + shutdownCallChain.add(callback); + } + template <typename T> + void onShutdown(T *objPtr, void (T::*memberPtr)(void)) { + shutdownCallChain.add(objPtr, memberPtr); + } + + /** + * @brief provide access to the callchain of shutdown event callbacks + * It is possible to register callbacks using onShutdown().add(callback); + * It is possible to unregister callbacks using onShutdown().detach(callback) + * @return The shutdown event callbacks chain + */ + GapShutdownCallbackChain_t& onShutdown() { + return shutdownCallChain; + } + +public: + /** + * Notify all registered onShutdown callbacks that the Gap instance is + * about to be shutdown and clear all Gap state of the + * associated object. + * + * This function is meant to be overridden in the platform-specific + * sub-class. Nevertheless, the sub-class is only expected to reset its + * state and not the data held in Gap members. This shall be achieved by a + * call to Gap::reset() from the sub-class' reset() implementation. + * + * @return BLE_ERROR_NONE on success. + * + * @note: Currently a call to reset() does not reset the advertising and + * scan parameters to default values. + */ + virtual ble_error_t reset(void) { + /* Notify that the instance is about to shutdown */ + shutdownCallChain.call(this); + shutdownCallChain.clear(); + + /* Clear Gap state */ + state.advertising = 0; + state.connected = 0; + + /* Clear scanning state */ + scanningActive = false; + + /* Clear advertising and scanning data */ + _advPayload.clear(); + _scanResponse.clear(); + + /* Clear callbacks */ + timeoutCallbackChain.clear(); + connectionCallChain.clear(); + disconnectionCallChain.clear(); + radioNotificationCallback = NULL; + onAdvertisementReport = NULL; + + return BLE_ERROR_NONE; + } + protected: Gap() : _advParams(), @@ -1002,13 +1332,13 @@ /* Entry points for the underlying stack to report events back to the user. */ public: - void processConnectionEvent(Handle_t handle, - Role_t role, - AddressType_t peerAddrType, - const Address_t peerAddr, - AddressType_t ownAddrType, - const Address_t ownAddr, - const ConnectionParams_t *connectionParams) { + void processConnectionEvent(Handle_t handle, + Role_t role, + BLEProtocol::AddressType_t peerAddrType, + const BLEProtocol::AddressBytes_t peerAddr, + BLEProtocol::AddressType_t ownAddrType, + const BLEProtocol::AddressBytes_t ownAddr, + const ConnectionParams_t *connectionParams) { state.connected = 1; ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); connectionCallChain.call(&callbackParams); @@ -1020,12 +1350,12 @@ disconnectionCallChain.call(&callbackParams); } - void processAdvertisementReport(const Address_t peerAddr, - int8_t rssi, - bool isScanResponse, + void processAdvertisementReport(const BLEProtocol::AddressBytes_t peerAddr, + int8_t rssi, + bool isScanResponse, GapAdvertisingParams::AdvertisingType_t type, - uint8_t advertisingDataLen, - const uint8_t *advertisingData) { + uint8_t advertisingDataLen, + const uint8_t *advertisingData) { AdvertisementCallbackParams_t params; memcpy(params.peerAddr, peerAddr, ADDR_LEN); params.rssi = rssi; @@ -1059,6 +1389,9 @@ DisconnectionEventCallbackChain_t disconnectionCallChain; private: + GapShutdownCallbackChain_t shutdownCallChain; + +private: /* Disallow copy and assignment. */ Gap(const Gap &); Gap& operator=(const Gap &);