High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Revision:
1135:22aada733dbd
Parent:
1134:d540a48f650d
Child:
1156:e1ea38b576c6
--- 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 &);