Merge pull request #8738 from pan-/ble-extended-advertising

Ble extended advertising
pull/8890/head
Martin Kojtal 2018-11-28 09:39:13 +01:00 committed by GitHub
commit 4758ddd2c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 13560 additions and 2230 deletions

View File

@ -18,7 +18,7 @@
#define MBED_BLE_H__ #define MBED_BLE_H__
#include "blecommon.h" #include "blecommon.h"
#include "Gap.h" #include "ble/Gap.h"
#include "GattServer.h" #include "GattServer.h"
#include "GattClient.h" #include "GattClient.h"
#include "SecurityManager.h" #include "SecurityManager.h"
@ -28,7 +28,9 @@
#ifdef YOTTA_CFG_MBED_OS #ifdef YOTTA_CFG_MBED_OS
#include "mbed-drivers/mbed_error.h" #include "mbed-drivers/mbed_error.h"
#else #else
#include "platform/mbed_error.h" #include "platform/mbed_error.h"
#endif #endif
#include "platform/mbed_toolchain.h" #include "platform/mbed_toolchain.h"
@ -132,8 +134,7 @@ class BLEInstanceBase;
* } * }
* @endcode * @endcode
*/ */
class BLE class BLE {
{
public: public:
/** /**
* Opaque type used to store the ID of a BLE instance. * Opaque type used to store the ID of a BLE instance.
@ -178,7 +179,8 @@ public:
* *
* @return Instance id of this BLE instance. * @return Instance id of this BLE instance.
*/ */
InstanceID_t getInstanceID(void) const { InstanceID_t getInstanceID(void) const
{
return instanceID; return instanceID;
} }
@ -192,13 +194,13 @@ public:
/** /**
* The ble instance which have events to process. * The ble instance which have events to process.
*/ */
BLE& ble; BLE &ble;
}; };
/** /**
* Events to process event handler * Events to process event handler
*/ */
typedef FunctionPointerWithContext<OnEventsToProcessCallbackContext*> typedef FunctionPointerWithContext<OnEventsToProcessCallbackContext *>
OnEventsToProcessCallback_t; OnEventsToProcessCallback_t;
/** /**
@ -209,7 +211,7 @@ public:
* *
* @param on_event_cb Callback invoked when there are new events to process. * @param on_event_cb Callback invoked when there are new events to process.
*/ */
void onEventsToProcess(const OnEventsToProcessCallback_t& on_event_cb); void onEventsToProcess(const OnEventsToProcessCallback_t &on_event_cb);
/** /**
* Process ALL pending events living in the BLE stack and return once all * Process ALL pending events living in the BLE stack and return once all
@ -229,7 +231,7 @@ public:
/** /**
* Reference to the BLE object that has been initialized * Reference to the BLE object that has been initialized
*/ */
BLE& ble; BLE &ble;
/** /**
* Error status of the initialization. * Error status of the initialization.
@ -283,7 +285,8 @@ public:
* @attention This should be called before using anything else in the BLE * @attention This should be called before using anything else in the BLE
* API. * API.
*/ */
ble_error_t init(InitializationCompleteCallback_t completion_cb = NULL) { ble_error_t init(InitializationCompleteCallback_t completion_cb = NULL)
{
FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback(completion_cb); FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback(completion_cb);
return initImplementation(callback); return initImplementation(callback);
} }
@ -299,7 +302,8 @@ public:
* initialization is complete. * initialization is complete.
*/ */
template<typename T> template<typename T>
ble_error_t init(T *object, void (T::*completion_cb)(InitializationCompleteCallbackContext *context)) { ble_error_t init(T *object, void (T::*completion_cb)(InitializationCompleteCallbackContext *context))
{
FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback(object, completion_cb); FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback(object, completion_cb);
return initImplementation(callback); return initImplementation(callback);
} }
@ -357,7 +361,7 @@ public:
* *
* @return A reference to a GattServer object associated to this BLE instance. * @return A reference to a GattServer object associated to this BLE instance.
*/ */
GattServer& gattServer(); GattServer &gattServer();
/** /**
* A const alternative to gattServer(). * A const alternative to gattServer().
@ -365,7 +369,7 @@ public:
* @return A const reference to a GattServer object associated to this BLE * @return A const reference to a GattServer object associated to this BLE
* instance. * instance.
*/ */
const GattServer& gattServer() const; const GattServer &gattServer() const;
/** /**
* Accessors to GattClient. All GattClient related functionality requires * Accessors to GattClient. All GattClient related functionality requires
@ -373,7 +377,7 @@ public:
* *
* @return A reference to a GattClient object associated to this BLE instance. * @return A reference to a GattClient object associated to this BLE instance.
*/ */
GattClient& gattClient(); GattClient &gattClient();
/** /**
* A const alternative to gattClient(). * A const alternative to gattClient().
@ -381,7 +385,7 @@ public:
* @return A const reference to a GattClient object associated to this BLE * @return A const reference to a GattClient object associated to this BLE
* instance. * instance.
*/ */
const GattClient& gattClient() const; const GattClient &gattClient() const;
/** /**
* Accessors to SecurityManager. All SecurityManager-related functionality * Accessors to SecurityManager. All SecurityManager-related functionality
@ -390,7 +394,7 @@ public:
* @return A reference to a SecurityManager object associated to this BLE * @return A reference to a SecurityManager object associated to this BLE
* instance. * instance.
*/ */
SecurityManager& securityManager(); SecurityManager &securityManager();
/** /**
* A const alternative to securityManager(). * A const alternative to securityManager().
@ -398,7 +402,7 @@ public:
* @return A const reference to a SecurityManager object associated to this * @return A const reference to a SecurityManager object associated to this
* BLE instance. * BLE instance.
*/ */
const SecurityManager& securityManager() const; const SecurityManager &securityManager() const;
/** /**
* Translate error code into a printable string. * Translate error code into a printable string.
@ -407,7 +411,7 @@ public:
* *
* @return A pointer to a const string describing the error. * @return A pointer to a const string describing the error.
*/ */
static const char* errorToString(ble_error_t error); static const char *errorToString(ble_error_t error);
/* /*
* Deprecation alert! * Deprecation alert!
@ -471,7 +475,8 @@ public:
MBED_DEPRECATED("Use ble.gap().getAddress(...)") MBED_DEPRECATED("Use ble.gap().getAddress(...)")
ble_error_t getAddress( ble_error_t getAddress(
BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address BLEProtocol::AddressType_t *typeP, BLEProtocol::AddressBytes_t address
) { )
{
return gap().getAddress(typeP, address); return gap().getAddress(typeP, address);
} }
@ -484,9 +489,7 @@ public:
* ble.gap().setAdvertisingType(...). * ble.gap().setAdvertisingType(...).
*/ */
MBED_DEPRECATED("Use ble.gap().setAdvertisingType(...)") MBED_DEPRECATED("Use ble.gap().setAdvertisingType(...)")
void setAdvertisingType(GapAdvertisingParams::AdvertisingType advType) { void setAdvertisingType(GapAdvertisingParams::AdvertisingType advType);
gap().setAdvertisingType(advType);
}
/** /**
* @param[in] interval * @param[in] interval
@ -515,9 +518,7 @@ public:
* code depending on the old semantics needs to be updated accordingly. * code depending on the old semantics needs to be updated accordingly.
*/ */
MBED_DEPRECATED("Use ble.gap().setAdvertisingInterval(...)") MBED_DEPRECATED("Use ble.gap().setAdvertisingInterval(...)")
void setAdvertisingInterval(uint16_t interval) { void setAdvertisingInterval(uint16_t interval);
gap().setAdvertisingInterval(interval);
}
/** /**
* @return Minimum Advertising interval in milliseconds. * @return Minimum Advertising interval in milliseconds.
@ -528,7 +529,8 @@ public:
* ble.gap().getMinAdvertisingInterval(...). * ble.gap().getMinAdvertisingInterval(...).
*/ */
MBED_DEPRECATED("Use ble.gap().getMinAdvertisingInterval(...)") MBED_DEPRECATED("Use ble.gap().getMinAdvertisingInterval(...)")
uint16_t getMinAdvertisingInterval(void) const { uint16_t getMinAdvertisingInterval(void) const
{
return gap().getMinAdvertisingInterval(); return gap().getMinAdvertisingInterval();
} }
@ -541,7 +543,8 @@ public:
* ble.gap().getMinNonConnectableAdvertisingInterval(...). * ble.gap().getMinNonConnectableAdvertisingInterval(...).
*/ */
MBED_DEPRECATED("Use ble.gap().getMinNonConnectableAdvertisingInterval(...)") MBED_DEPRECATED("Use ble.gap().getMinNonConnectableAdvertisingInterval(...)")
uint16_t getMinNonConnectableAdvertisingInterval(void) const { uint16_t getMinNonConnectableAdvertisingInterval(void) const
{
return gap().getMinNonConnectableAdvertisingInterval(); return gap().getMinNonConnectableAdvertisingInterval();
} }
@ -554,7 +557,8 @@ public:
* ble.gap().getMaxAdvertisingInterval(...). * ble.gap().getMaxAdvertisingInterval(...).
*/ */
MBED_DEPRECATED("Use ble.gap().getMaxAdvertisingInterval(...)") MBED_DEPRECATED("Use ble.gap().getMaxAdvertisingInterval(...)")
uint16_t getMaxAdvertisingInterval(void) const { uint16_t getMaxAdvertisingInterval(void) const
{
return gap().getMaxAdvertisingInterval(); return gap().getMaxAdvertisingInterval();
} }
@ -569,9 +573,7 @@ public:
* ble.gap().setAdvertisingTimeout(...). * ble.gap().setAdvertisingTimeout(...).
*/ */
MBED_DEPRECATED("Use ble.gap().setAdvertisingTimeout(...)") MBED_DEPRECATED("Use ble.gap().setAdvertisingTimeout(...)")
void setAdvertisingTimeout(uint16_t timeout) { void setAdvertisingTimeout(uint16_t timeout);
gap().setAdvertisingTimeout(timeout);
}
/** /**
* Set up a particular, user-constructed set of advertisement parameters for * Set up a particular, user-constructed set of advertisement parameters for
@ -585,9 +587,7 @@ public:
* ble.gap().setAdvertisingParams(...). * ble.gap().setAdvertisingParams(...).
*/ */
MBED_DEPRECATED("Use ble.gap().setAdvertisingParams(...)") MBED_DEPRECATED("Use ble.gap().setAdvertisingParams(...)")
void setAdvertisingParams(const GapAdvertisingParams &advParams) { void setAdvertisingParams(const GapAdvertisingParams &advParams);
gap().setAdvertisingParams(advParams);
}
/** /**
* @return Read back advertising parameters. Useful for storing and * @return Read back advertising parameters. Useful for storing and
@ -599,9 +599,7 @@ public:
* ble.gap().getAdvertisingParams(...). * ble.gap().getAdvertisingParams(...).
*/ */
MBED_DEPRECATED("Use ble.gap().getAdvertisingParams(...)") MBED_DEPRECATED("Use ble.gap().getAdvertisingParams(...)")
const GapAdvertisingParams &getAdvertisingParams(void) const { const GapAdvertisingParams &getAdvertisingParams(void) const;
return gap().getAdvertisingParams();
}
/** /**
* Accumulate an AD structure in the advertising payload. Please note that * Accumulate an AD structure in the advertising payload. Please note that
@ -620,9 +618,7 @@ public:
* ble.gap().accumulateAdvertisingPayload(flags). * ble.gap().accumulateAdvertisingPayload(flags).
*/ */
MBED_DEPRECATED("Use ble.gap().accumulateAdvertisingPayload(flags)") MBED_DEPRECATED("Use ble.gap().accumulateAdvertisingPayload(flags)")
ble_error_t accumulateAdvertisingPayload(uint8_t flags) { ble_error_t accumulateAdvertisingPayload(uint8_t flags);
return gap().accumulateAdvertisingPayload(flags);
}
/** /**
* Accumulate an AD structure in the advertising payload. Please note that * Accumulate an AD structure in the advertising payload. Please note that
@ -640,9 +636,7 @@ public:
* ble.gap().accumulateAdvertisingPayload(appearance). * ble.gap().accumulateAdvertisingPayload(appearance).
*/ */
MBED_DEPRECATED("Use ble.gap().accumulateAdvertisingPayload(appearance)") MBED_DEPRECATED("Use ble.gap().accumulateAdvertisingPayload(appearance)")
ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) { ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::Appearance app);
return gap().accumulateAdvertisingPayload(app);
}
/** /**
* Accumulate an AD structure in the advertising payload. Please note that * Accumulate an AD structure in the advertising payload. Please note that
@ -660,9 +654,7 @@ public:
* ble.gap().accumulateAdvertisingPayloadTxPower(txPower). * ble.gap().accumulateAdvertisingPayloadTxPower(txPower).
*/ */
MBED_DEPRECATED("Use ble.gap().accumulateAdvertisingPayloadTxPower(...)") MBED_DEPRECATED("Use ble.gap().accumulateAdvertisingPayloadTxPower(...)")
ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power) { ble_error_t accumulateAdvertisingPayloadTxPower(int8_t power);
return gap().accumulateAdvertisingPayloadTxPower(power);
}
/** /**
* Accumulate a variable length byte-stream as an AD structure in the * Accumulate a variable length byte-stream as an AD structure in the
@ -680,9 +672,7 @@ public:
* be replaced with ble.gap().accumulateAdvertisingPayload(...). * be replaced with ble.gap().accumulateAdvertisingPayload(...).
*/ */
MBED_DEPRECATED("Use ble.gap().accumulateAdvertisingPayload(...)") MBED_DEPRECATED("Use ble.gap().accumulateAdvertisingPayload(...)")
ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { ble_error_t accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len);
return gap().accumulateAdvertisingPayload(type, data, len);
}
/** /**
* Set up a particular, user-constructed advertisement payload for the * Set up a particular, user-constructed advertisement payload for the
@ -695,9 +685,7 @@ public:
* ble.gap().setAdvertisingPayload(...). * ble.gap().setAdvertisingPayload(...).
*/ */
MBED_DEPRECATED("Use ble.gap().setAdvertisingData(...)") MBED_DEPRECATED("Use ble.gap().setAdvertisingData(...)")
ble_error_t setAdvertisingData(const GapAdvertisingData &advData) { ble_error_t setAdvertisingData(const GapAdvertisingData &advData);
return gap().setAdvertisingPayload(advData);
}
/** /**
* @return Read back advertising data. Useful for storing and * @return Read back advertising data. Useful for storing and
@ -709,9 +697,7 @@ public:
* ble.gap().getAdvertisingPayload()(...). * ble.gap().getAdvertisingPayload()(...).
*/ */
MBED_DEPRECATED("Use ble.gap().getAdvertisingData(...)") MBED_DEPRECATED("Use ble.gap().getAdvertisingData(...)")
const GapAdvertisingData &getAdvertisingData(void) const { const GapAdvertisingData &getAdvertisingData(void) const;
return gap().getAdvertisingPayload();
}
/** /**
* Reset any advertising payload prepared from prior calls to * Reset any advertising payload prepared from prior calls to
@ -724,9 +710,7 @@ public:
* ble.gap().clearAdvertisingPayload(...). * ble.gap().clearAdvertisingPayload(...).
*/ */
MBED_DEPRECATED("Use ble.gap().clearAdvertisingPayload(...)") MBED_DEPRECATED("Use ble.gap().clearAdvertisingPayload(...)")
void clearAdvertisingPayload(void) { void clearAdvertisingPayload(void);
gap().clearAdvertisingPayload();
}
/** /**
* Dynamically reset the accumulated advertising * Dynamically reset the accumulated advertising
@ -743,9 +727,7 @@ public:
* implicitly. * implicitly.
*/ */
MBED_DEPRECATED("Use ble.gap().setAdvertisingPayload(...)") MBED_DEPRECATED("Use ble.gap().setAdvertisingPayload(...)")
ble_error_t setAdvertisingPayload(void) { ble_error_t setAdvertisingPayload(void);
return BLE_ERROR_NONE;
}
/** /**
* Accumulate a variable length byte-stream as an AD structure in the * Accumulate a variable length byte-stream as an AD structure in the
@ -761,9 +743,7 @@ public:
* ble.gap().accumulateScanResponse(...). * ble.gap().accumulateScanResponse(...).
*/ */
MBED_DEPRECATED("Use ble.gap().accumulateScanResponse(...)") MBED_DEPRECATED("Use ble.gap().accumulateScanResponse(...)")
ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) { ble_error_t accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len);
return gap().accumulateScanResponse(type, data, len);
}
/** /**
* Reset any scan response prepared from prior calls to * Reset any scan response prepared from prior calls to
@ -775,9 +755,7 @@ public:
* ble.gap().clearScanResponse(...). * ble.gap().clearScanResponse(...).
*/ */
MBED_DEPRECATED("Use ble.gap().clearScanResponse(...)") MBED_DEPRECATED("Use ble.gap().clearScanResponse(...)")
void clearScanResponse(void) { void clearScanResponse(void);
gap().clearScanResponse();
}
/** /**
* Start advertising. * Start advertising.
@ -788,9 +766,7 @@ public:
* ble.gap().startAdvertising(...). * ble.gap().startAdvertising(...).
*/ */
MBED_DEPRECATED("Use ble.gap().startAdvertising(...)") MBED_DEPRECATED("Use ble.gap().startAdvertising(...)")
ble_error_t startAdvertising(void) { ble_error_t startAdvertising(void);
return gap().startAdvertising();
}
/** /**
* Stop advertising. * Stop advertising.
@ -801,9 +777,7 @@ public:
* ble.gap().stopAdvertising(...). * ble.gap().stopAdvertising(...).
*/ */
MBED_DEPRECATED("Use ble.gap().stopAdvertising(...)") MBED_DEPRECATED("Use ble.gap().stopAdvertising(...)")
ble_error_t stopAdvertising(void) { ble_error_t stopAdvertising(void);
return gap().stopAdvertising();
}
/** /**
* Set up parameters for GAP scanning (observer mode). * Set up parameters for GAP scanning (observer mode).
@ -835,12 +809,12 @@ public:
* ble.gap().setScanParams(...). * ble.gap().setScanParams(...).
*/ */
MBED_DEPRECATED("Use ble.gap().setScanParams(...)") MBED_DEPRECATED("Use ble.gap().setScanParams(...)")
ble_error_t setScanParams(uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX, ble_error_t setScanParams(
uint16_t interval = GapScanningParams::SCAN_INTERVAL_MAX,
uint16_t window = GapScanningParams::SCAN_WINDOW_MAX, uint16_t window = GapScanningParams::SCAN_WINDOW_MAX,
uint16_t timeout = 0, uint16_t timeout = 0,
bool activeScanning = false) { bool activeScanning = false
return gap().setScanParams(interval, window, timeout, activeScanning); );
}
/** /**
* Set up the scanInterval parameter for GAP scanning (observer mode). * Set up the scanInterval parameter for GAP scanning (observer mode).
@ -863,9 +837,7 @@ public:
* ble.gap().setScanInterval(interval). * ble.gap().setScanInterval(interval).
*/ */
MBED_DEPRECATED("Use ble.gap().setScanInterval(...)") MBED_DEPRECATED("Use ble.gap().setScanInterval(...)")
ble_error_t setScanInterval(uint16_t interval) { ble_error_t setScanInterval(uint16_t interval);
return gap().setScanInterval(interval);
}
/** /**
* Set up the scanWindow parameter for GAP scanning (observer mode). * Set up the scanWindow parameter for GAP scanning (observer mode).
@ -888,9 +860,7 @@ public:
* ble.gap().setScanWindow(window). * ble.gap().setScanWindow(window).
*/ */
MBED_DEPRECATED("Use ble.gap().setScanWindow(...)") MBED_DEPRECATED("Use ble.gap().setScanWindow(...)")
ble_error_t setScanWindow(uint16_t window) { ble_error_t setScanWindow(uint16_t window);
return gap().setScanWindow(window);
}
/** /**
* Set up parameters for GAP scanning (observer mode). * Set up parameters for GAP scanning (observer mode).
@ -915,9 +885,7 @@ public:
* ble.gap().setScanTimeout(...). * ble.gap().setScanTimeout(...).
*/ */
MBED_DEPRECATED("Use ble.gap().setScanTimeout(...)") MBED_DEPRECATED("Use ble.gap().setScanTimeout(...)")
ble_error_t setScanTimeout(uint16_t timeout) { ble_error_t setScanTimeout(uint16_t timeout);
return gap().setScanTimeout(timeout);
}
/** /**
* Set up parameters for GAP scanning (observer mode). * Set up parameters for GAP scanning (observer mode).
@ -934,9 +902,7 @@ public:
* ble.gap().setActiveScanning(...). * ble.gap().setActiveScanning(...).
*/ */
MBED_DEPRECATED("Use ble.gap().setActiveScan(...)") MBED_DEPRECATED("Use ble.gap().setActiveScan(...)")
void setActiveScan(bool activeScanning) { void setActiveScan(bool activeScanning);
gap().setActiveScanning(activeScanning);
}
/** /**
* Start scanning (Observer Procedure) based on the parameters currently in * Start scanning (Observer Procedure) based on the parameters currently in
@ -953,9 +919,7 @@ public:
* ble.gap().startScan(callback). * ble.gap().startScan(callback).
*/ */
MBED_DEPRECATED("Use ble.gap().startScan(callback)") MBED_DEPRECATED("Use ble.gap().startScan(callback)")
ble_error_t startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)) { ble_error_t startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params));
return gap().startScan(callback);
}
/** /**
* Same as above, but this takes an (object, method) pair for a callback. * Same as above, but this takes an (object, method) pair for a callback.
@ -980,7 +944,8 @@ public:
* ble.gap().stopScan(). * ble.gap().stopScan().
*/ */
MBED_DEPRECATED("Use ble.gap().stopScan()") MBED_DEPRECATED("Use ble.gap().stopScan()")
ble_error_t stopScan(void) { ble_error_t stopScan(void)
{
return gap().stopScan(); return gap().stopScan();
} }
@ -1004,10 +969,12 @@ public:
* ble.gap().connect(...). * ble.gap().connect(...).
*/ */
MBED_DEPRECATED("Use ble.gap().connect(...)") MBED_DEPRECATED("Use ble.gap().connect(...)")
ble_error_t connect(const BLEProtocol::AddressBytes_t peerAddr, ble_error_t connect(
const BLEProtocol::AddressBytes_t peerAddr,
BLEProtocol::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC, BLEProtocol::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC,
const Gap::ConnectionParams_t *connectionParams = NULL, const Gap::ConnectionParams_t *connectionParams = NULL,
const GapScanningParams *scanParams = NULL); const GapScanningParams *scanParams = NULL
);
/** /**
* This call initiates the disconnection procedure, and its completion is * This call initiates the disconnection procedure, and its completion is
@ -1019,9 +986,7 @@ public:
* The reason for disconnection; sent back to the peer. * The reason for disconnection; sent back to the peer.
*/ */
MBED_DEPRECATED("Use ble.gap().disconnect(...)") MBED_DEPRECATED("Use ble.gap().disconnect(...)")
ble_error_t disconnect(Gap::Handle_t connectionHandle, Gap::DisconnectionReason_t reason) { ble_error_t disconnect(Gap::Handle_t connectionHandle, Gap::DisconnectionReason_t reason);
return gap().disconnect(connectionHandle, reason);
}
/** /**
* This call initiates the disconnection procedure, and its completion * This call initiates the disconnection procedure, and its completion
@ -1053,9 +1018,7 @@ public:
* ble.gap().getState(). * ble.gap().getState().
*/ */
MBED_DEPRECATED("Use ble.gap().getGapState(...)") MBED_DEPRECATED("Use ble.gap().getGapState(...)")
Gap::GapState_t getGapState(void) const { Gap::GapState_t getGapState(void) const;
return gap().getState();
}
/** /**
* Get the GAP peripheral's preferred connection parameters. These are the * Get the GAP peripheral's preferred connection parameters. These are the
@ -1075,7 +1038,8 @@ public:
* ble.gap().getPreferredConnectionParams(). * ble.gap().getPreferredConnectionParams().
*/ */
MBED_DEPRECATED("Use ble.gap().getPreferredConnectionParams(...)") MBED_DEPRECATED("Use ble.gap().getPreferredConnectionParams(...)")
ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params) { ble_error_t getPreferredConnectionParams(Gap::ConnectionParams_t *params)
{
return gap().getPreferredConnectionParams(params); return gap().getPreferredConnectionParams(params);
} }
@ -1093,7 +1057,8 @@ public:
* ble.gap().setPreferredConnectionParams(). * ble.gap().setPreferredConnectionParams().
*/ */
MBED_DEPRECATED("Use ble.gap().setPreferredConnectionParams(...)") MBED_DEPRECATED("Use ble.gap().setPreferredConnectionParams(...)")
ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params) { ble_error_t setPreferredConnectionParams(const Gap::ConnectionParams_t *params)
{
return gap().setPreferredConnectionParams(params); return gap().setPreferredConnectionParams(params);
} }
@ -1113,9 +1078,7 @@ public:
* ble.gap().updateConnectionParams(). * ble.gap().updateConnectionParams().
*/ */
MBED_DEPRECATED("Use ble.gap().updateConnectionParams(...)") MBED_DEPRECATED("Use ble.gap().updateConnectionParams(...)")
ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) { ble_error_t updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params);
return gap().updateConnectionParams(handle, params);
}
/** /**
* Set the device name characteristic in the Gap service. * Set the device name characteristic in the Gap service.
@ -1128,7 +1091,8 @@ public:
* ble.gap().setDeviceName(). * ble.gap().setDeviceName().
*/ */
MBED_DEPRECATED("Use ble.gap().setDeviceName(...)") MBED_DEPRECATED("Use ble.gap().setDeviceName(...)")
ble_error_t setDeviceName(const uint8_t *deviceName) { ble_error_t setDeviceName(const uint8_t *deviceName)
{
return gap().setDeviceName(deviceName); return gap().setDeviceName(deviceName);
} }
@ -1156,7 +1120,8 @@ public:
* ble.gap().getDeviceName(). * ble.gap().getDeviceName().
*/ */
MBED_DEPRECATED("Use ble.gap().getDeviceName(...)") MBED_DEPRECATED("Use ble.gap().getDeviceName(...)")
ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP) { ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP)
{
return gap().getDeviceName(deviceName, lengthP); return gap().getDeviceName(deviceName, lengthP);
} }
@ -1171,7 +1136,8 @@ public:
* ble.gap().setAppearance(). * ble.gap().setAppearance().
*/ */
MBED_DEPRECATED("Use ble.gap().setAppearance(...)") MBED_DEPRECATED("Use ble.gap().setAppearance(...)")
ble_error_t setAppearance(GapAdvertisingData::Appearance appearance) { ble_error_t setAppearance(GapAdvertisingData::Appearance appearance)
{
return gap().setAppearance(appearance); return gap().setAppearance(appearance);
} }
@ -1186,7 +1152,8 @@ public:
* ble.gap().getAppearance(). * ble.gap().getAppearance().
*/ */
MBED_DEPRECATED("Use ble.gap().getAppearance(...)") MBED_DEPRECATED("Use ble.gap().getAppearance(...)")
ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP) { ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP)
{
return gap().getAppearance(appearanceP); return gap().getAppearance(appearanceP);
} }
@ -1200,9 +1167,7 @@ public:
* ble.gap().setTxPower(). * ble.gap().setTxPower().
*/ */
MBED_DEPRECATED("Use ble.gap().setTxPower(...)") MBED_DEPRECATED("Use ble.gap().setTxPower(...)")
ble_error_t setTxPower(int8_t txPower) { ble_error_t setTxPower(int8_t txPower);
return gap().setTxPower(txPower);
}
/** /**
* Query the underlying stack for permitted arguments for setTxPower(). * Query the underlying stack for permitted arguments for setTxPower().
@ -1218,9 +1183,7 @@ public:
* ble.gap().getPermittedTxPowerValues(). * ble.gap().getPermittedTxPowerValues().
*/ */
MBED_DEPRECATED("Use ble.gap().getPermittedTxPowerValues(...)") MBED_DEPRECATED("Use ble.gap().getPermittedTxPowerValues(...)")
void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP);
gap().getPermittedTxPowerValues(valueArrayPP, countP);
}
/** /**
* Add a service declaration to the local server ATT table. Also add the * Add a service declaration to the local server ATT table. Also add the
@ -1232,7 +1195,8 @@ public:
* ble.gattServer().addService(). * ble.gattServer().addService().
*/ */
MBED_DEPRECATED("Use ble.gattServer().addService(...)") MBED_DEPRECATED("Use ble.gattServer().addService(...)")
ble_error_t addService(GattService &service) { ble_error_t addService(GattService &service)
{
return gattServer().addService(service); return gattServer().addService(service);
} }
@ -1257,7 +1221,8 @@ public:
* ble.gattServer().read(). * ble.gattServer().read().
*/ */
MBED_DEPRECATED("Use ble.gattServer().read(...)") MBED_DEPRECATED("Use ble.gattServer().read(...)")
ble_error_t readCharacteristicValue(GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) { ble_error_t readCharacteristicValue(GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP)
{
return gattServer().read(attributeHandle, buffer, lengthP); return gattServer().read(attributeHandle, buffer, lengthP);
} }
@ -1288,7 +1253,13 @@ public:
* ble.gattServer().read(). * ble.gattServer().read().
*/ */
MBED_DEPRECATED("Use ble.gattServer().read(...)") MBED_DEPRECATED("Use ble.gattServer().read(...)")
ble_error_t readCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) { ble_error_t readCharacteristicValue(
Gap::Handle_t connectionHandle,
GattAttribute::Handle_t attributeHandle,
uint8_t *buffer,
uint16_t *lengthP
)
{
return gattServer().read(connectionHandle, attributeHandle, buffer, lengthP); return gattServer().read(connectionHandle, attributeHandle, buffer, lengthP);
} }
@ -1316,10 +1287,13 @@ public:
* ble.gattServer().write(). * ble.gattServer().write().
*/ */
MBED_DEPRECATED("Use ble.gattServer().write(...)") MBED_DEPRECATED("Use ble.gattServer().write(...)")
ble_error_t updateCharacteristicValue(GattAttribute::Handle_t attributeHandle, ble_error_t updateCharacteristicValue(
GattAttribute::Handle_t attributeHandle,
const uint8_t *value, const uint8_t *value,
uint16_t size, uint16_t size,
bool localOnly = false) { bool localOnly = false
)
{
return gattServer().write(attributeHandle, value, size, localOnly); return gattServer().write(attributeHandle, value, size, localOnly);
} }
@ -1351,11 +1325,14 @@ public:
* ble.gattServer().write(). * ble.gattServer().write().
*/ */
MBED_DEPRECATED("Use ble.gattServer().write(...)") MBED_DEPRECATED("Use ble.gattServer().write(...)")
ble_error_t updateCharacteristicValue(Gap::Handle_t connectionHandle, ble_error_t updateCharacteristicValue(
Gap::Handle_t connectionHandle,
GattAttribute::Handle_t attributeHandle, GattAttribute::Handle_t attributeHandle,
const uint8_t *value, const uint8_t *value,
uint16_t size, uint16_t size,
bool localOnly = false) { bool localOnly = false
)
{
return gattServer().write(connectionHandle, attributeHandle, value, size, localOnly); return gattServer().write(connectionHandle, attributeHandle, value, size, localOnly);
} }
@ -1380,10 +1357,13 @@ public:
* ble.securityManager().init(...). * ble.securityManager().init(...).
*/ */
MBED_DEPRECATED("Use ble.gattServer().write(...)") MBED_DEPRECATED("Use ble.gattServer().write(...)")
ble_error_t initializeSecurity(bool enableBonding = true, ble_error_t initializeSecurity(
bool enableBonding = true,
bool requireMITM = true, bool requireMITM = true,
SecurityManager::SecurityIOCapabilities_t iocaps = SecurityManager::IO_CAPS_NONE, SecurityManager::SecurityIOCapabilities_t iocaps = SecurityManager::IO_CAPS_NONE,
const SecurityManager::Passkey_t passkey = NULL) { const SecurityManager::Passkey_t passkey = NULL
)
{
return securityManager().init(enableBonding, requireMITM, iocaps, passkey); return securityManager().init(enableBonding, requireMITM, iocaps, passkey);
} }
@ -1401,7 +1381,8 @@ public:
* ble.securityManager().getLinkSecurity(...). * ble.securityManager().getLinkSecurity(...).
*/ */
MBED_DEPRECATED("ble.securityManager().getLinkSecurity(...)") MBED_DEPRECATED("ble.securityManager().getLinkSecurity(...)")
ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP) { ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
{
return securityManager().getLinkSecurity(connectionHandle, securityStatusP); return securityManager().getLinkSecurity(connectionHandle, securityStatusP);
} }
@ -1419,7 +1400,8 @@ public:
* ble.securityManager().purgeAllBondingState(). * ble.securityManager().purgeAllBondingState().
*/ */
MBED_DEPRECATED("ble.securityManager().purgeAllBondingState(...)") MBED_DEPRECATED("ble.securityManager().purgeAllBondingState(...)")
ble_error_t purgeAllBondingState(void) { ble_error_t purgeAllBondingState(void)
{
return securityManager().purgeAllBondingState(); return securityManager().purgeAllBondingState();
} }
@ -1433,9 +1415,7 @@ public:
* ble.gap().onTimeout(callback). * ble.gap().onTimeout(callback).
*/ */
MBED_DEPRECATED("ble.gap().onTimeout(callback)") MBED_DEPRECATED("ble.gap().onTimeout(callback)")
void onTimeout(Gap::TimeoutEventCallback_t timeoutCallback) { void onTimeout(Gap::TimeoutEventCallback_t timeoutCallback);
gap().onTimeout(timeoutCallback);
}
/** /**
* Set up a callback for connection events. Refer to Gap::ConnectionEventCallback_t. * Set up a callback for connection events. Refer to Gap::ConnectionEventCallback_t.
@ -1446,9 +1426,7 @@ public:
* ble.gap().onConnection(callback). * ble.gap().onConnection(callback).
*/ */
MBED_DEPRECATED("ble.gap().onConnection(callback)") MBED_DEPRECATED("ble.gap().onConnection(callback)")
void onConnection(Gap::ConnectionEventCallback_t connectionCallback) { void onConnection(Gap::ConnectionEventCallback_t connectionCallback);
gap().onConnection(connectionCallback);
}
/** /**
* Append to a chain of callbacks to be invoked upon GAP disconnection. * Append to a chain of callbacks to be invoked upon GAP disconnection.
@ -1458,10 +1436,8 @@ public:
* to ble.onDisconnection(callback) should be replaced with * to ble.onDisconnection(callback) should be replaced with
* ble.gap().onDisconnection(callback). * ble.gap().onDisconnection(callback).
*/ */
MBED_DEPRECATED("ble.gap().onDisconnection(callback)") MBED_DEPRECATED("ble.gap().onDisconnectionComplete(callback)")
void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) { void onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback);
gap().onDisconnection(disconnectionCallback);
}
/** /**
* The same as onDisconnection() but allows an object reference and member function * The same as onDisconnection() but allows an object reference and member function
@ -1473,8 +1449,9 @@ public:
* ble.gap().onDisconnection(callback). * ble.gap().onDisconnection(callback).
*/ */
template<typename T> template<typename T>
MBED_DEPRECATED("ble.gap().onDisconnection(callback)") MBED_DEPRECATED("ble.gap().onDisconnectionComplete(callback)")
void onDisconnection(T *tptr, void (T::*mptr)(const Gap::DisconnectionCallbackParams_t*)) { void onDisconnection(T *tptr, void (T::*mptr)(const Gap::DisconnectionCallbackParams_t *))
{
gap().onDisconnection(tptr, mptr); gap().onDisconnection(tptr, mptr);
} }
@ -1500,9 +1477,7 @@ public:
* ble.gap().onRadioNotification(...). * ble.gap().onRadioNotification(...).
*/ */
MBED_DEPRECATED("ble.gap().onRadioNotification(...)") MBED_DEPRECATED("ble.gap().onRadioNotification(...)")
void onRadioNotification(void (*callback)(bool)) { void onRadioNotification(void (*callback)(bool));
gap().onRadioNotification(callback);
}
/** /**
* Add a callback for the GATT event DATA_SENT (which is triggered when * Add a callback for the GATT event DATA_SENT (which is triggered when
@ -1521,7 +1496,8 @@ public:
* ble.gattServer().onDataSent(...). * ble.gattServer().onDataSent(...).
*/ */
MBED_DEPRECATED("ble.gattServer().onDataSent(...)") MBED_DEPRECATED("ble.gattServer().onDataSent(...)")
void onDataSent(void (*callback)(unsigned count)) { void onDataSent(void (*callback)(unsigned count))
{
gattServer().onDataSent(callback); gattServer().onDataSent(callback);
} }
@ -1534,9 +1510,10 @@ public:
* to ble.onDataSent(...) should be replaced with * to ble.onDataSent(...) should be replaced with
* ble.gattServer().onDataSent(...). * ble.gattServer().onDataSent(...).
*/ */
template <typename T> template<typename T>
MBED_DEPRECATED("ble.gattServer().onDataSent(...)") MBED_DEPRECATED("ble.gattServer().onDataSent(...)")
void onDataSent(T * objPtr, void (T::*memberPtr)(unsigned count)) { void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count))
{
gattServer().onDataSent(objPtr, memberPtr); gattServer().onDataSent(objPtr, memberPtr);
} }
@ -1561,7 +1538,8 @@ public:
* ble.gattServer().onDataWritten(...). * ble.gattServer().onDataWritten(...).
*/ */
MBED_DEPRECATED("ble.gattServer().onDataWritten(...)") MBED_DEPRECATED("ble.gattServer().onDataWritten(...)")
void onDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP)) { void onDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP))
{
gattServer().onDataWritten(callback); gattServer().onDataWritten(callback);
} }
@ -1574,9 +1552,10 @@ public:
* to ble.onDataWritten(...) should be replaced with * to ble.onDataWritten(...) should be replaced with
* ble.gattServer().onDataWritten(...). * ble.gattServer().onDataWritten(...).
*/ */
template <typename T> template<typename T>
MBED_DEPRECATED("ble.gattServer().onDataWritten(...)") MBED_DEPRECATED("ble.gattServer().onDataWritten(...)")
void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) { void onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context))
{
gattServer().onDataWritten(objPtr, memberPtr); gattServer().onDataWritten(objPtr, memberPtr);
} }
@ -1605,7 +1584,8 @@ public:
* ble.gattServer().onDataRead(...). * ble.gattServer().onDataRead(...).
*/ */
MBED_DEPRECATED("ble.gattServer().onDataRead(...)") MBED_DEPRECATED("ble.gattServer().onDataRead(...)")
ble_error_t onDataRead(void (*callback)(const GattReadCallbackParams *eventDataP)) { ble_error_t onDataRead(void (*callback)(const GattReadCallbackParams *eventDataP))
{
return gattServer().onDataRead(callback); return gattServer().onDataRead(callback);
} }
@ -1618,9 +1598,10 @@ public:
* to ble.onDataRead(...) should be replaced with * to ble.onDataRead(...) should be replaced with
* ble.gattServer().onDataRead(...). * ble.gattServer().onDataRead(...).
*/ */
template <typename T> template<typename T>
MBED_DEPRECATED("ble.gattServer().onDataRead(...)") MBED_DEPRECATED("ble.gattServer().onDataRead(...)")
ble_error_t onDataRead(T * objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) { ble_error_t onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context))
{
return gattServer().onDataRead(objPtr, memberPtr); return gattServer().onDataRead(objPtr, memberPtr);
} }
@ -1634,7 +1615,8 @@ public:
* ble.gattServer().onUpdatesEnabled(callback). * ble.gattServer().onUpdatesEnabled(callback).
*/ */
MBED_DEPRECATED("ble.gattServer().onUpdatesEnabled(...)") MBED_DEPRECATED("ble.gattServer().onUpdatesEnabled(...)")
void onUpdatesEnabled(GattServer::EventCallback_t callback) { void onUpdatesEnabled(GattServer::EventCallback_t callback)
{
gattServer().onUpdatesEnabled(callback); gattServer().onUpdatesEnabled(callback);
} }
@ -1648,7 +1630,8 @@ public:
* ble.gattServer().onUpdatesDisabled(callback). * ble.gattServer().onUpdatesDisabled(callback).
*/ */
MBED_DEPRECATED("ble.gattServer().onUpdatesDisabled(...)") MBED_DEPRECATED("ble.gattServer().onUpdatesDisabled(...)")
void onUpdatesDisabled(GattServer::EventCallback_t callback) { void onUpdatesDisabled(GattServer::EventCallback_t callback)
{
gattServer().onUpdatesDisabled(callback); gattServer().onUpdatesDisabled(callback);
} }
@ -1662,7 +1645,8 @@ public:
* ble.gattServer().onConfirmationReceived(callback). * ble.gattServer().onConfirmationReceived(callback).
*/ */
MBED_DEPRECATED("ble.gattServer().onConfirmationReceived(...)") MBED_DEPRECATED("ble.gattServer().onConfirmationReceived(...)")
void onConfirmationReceived(GattServer::EventCallback_t callback) { void onConfirmationReceived(GattServer::EventCallback_t callback)
{
gattServer().onConfirmationReceived(callback); gattServer().onConfirmationReceived(callback);
} }
@ -1679,7 +1663,8 @@ public:
* ble.securityManager().onSecuritySetupInitiated(callback). * ble.securityManager().onSecuritySetupInitiated(callback).
*/ */
MBED_DEPRECATED("ble.securityManager().onSecuritySetupInitiated(callback)") MBED_DEPRECATED("ble.securityManager().onSecuritySetupInitiated(callback)")
void onSecuritySetupInitiated(SecurityManager::SecuritySetupInitiatedCallback_t callback) { void onSecuritySetupInitiated(SecurityManager::SecuritySetupInitiatedCallback_t callback)
{
securityManager().onSecuritySetupInitiated(callback); securityManager().onSecuritySetupInitiated(callback);
} }
@ -1695,7 +1680,8 @@ public:
* ble.securityManager().onSecuritySetupCompleted(callback). * ble.securityManager().onSecuritySetupCompleted(callback).
*/ */
MBED_DEPRECATED("ble.securityManager().onSecuritySetupCompleted(callback)") MBED_DEPRECATED("ble.securityManager().onSecuritySetupCompleted(callback)")
void onSecuritySetupCompleted(SecurityManager::SecuritySetupCompletedCallback_t callback) { void onSecuritySetupCompleted(SecurityManager::SecuritySetupCompletedCallback_t callback)
{
securityManager().onSecuritySetupCompleted(callback); securityManager().onSecuritySetupCompleted(callback);
} }
@ -1713,7 +1699,8 @@ public:
* ble.securityManager().onLinkSecured(callback). * ble.securityManager().onLinkSecured(callback).
*/ */
MBED_DEPRECATED("ble.securityManager().onLinkSecured(callback)") MBED_DEPRECATED("ble.securityManager().onLinkSecured(callback)")
void onLinkSecured(SecurityManager::LinkSecuredCallback_t callback) { void onLinkSecured(SecurityManager::LinkSecuredCallback_t callback)
{
securityManager().onLinkSecured(callback); securityManager().onLinkSecured(callback);
} }
@ -1727,7 +1714,8 @@ public:
* ble.securityManager().onSecurityContextStored(callback). * ble.securityManager().onSecurityContextStored(callback).
*/ */
MBED_DEPRECATED("ble.securityManager().onSecurityContextStored(callback)") MBED_DEPRECATED("ble.securityManager().onSecurityContextStored(callback)")
void onSecurityContextStored(SecurityManager::HandleSpecificEvent_t callback) { void onSecurityContextStored(SecurityManager::HandleSpecificEvent_t callback)
{
securityManager().onSecurityContextStored(callback); securityManager().onSecurityContextStored(callback);
} }
@ -1744,7 +1732,8 @@ public:
* ble.securityManager().onPasskeyDisplay(callback). * ble.securityManager().onPasskeyDisplay(callback).
*/ */
MBED_DEPRECATED("ble.securityManager().onPasskeyDisplay(callback)") MBED_DEPRECATED("ble.securityManager().onPasskeyDisplay(callback)")
void onPasskeyDisplay(SecurityManager::PasskeyDisplayCallback_t callback) { void onPasskeyDisplay(SecurityManager::PasskeyDisplayCallback_t callback)
{
return securityManager().onPasskeyDisplay(callback); return securityManager().onPasskeyDisplay(callback);
} }
@ -1772,7 +1761,8 @@ private:
private: private:
// Prevent copy construction and copy assignment of BLE. // Prevent copy construction and copy assignment of BLE.
BLE(const BLE&); BLE(const BLE &);
BLE &operator=(const BLE &); BLE &operator=(const BLE &);
private: private:

View File

@ -21,7 +21,7 @@
#ifndef MBED_BLE_DEVICE_INSTANCE_BASE__ #ifndef MBED_BLE_DEVICE_INSTANCE_BASE__
#define MBED_BLE_DEVICE_INSTANCE_BASE__ #define MBED_BLE_DEVICE_INSTANCE_BASE__
#include "Gap.h" #include "ble/Gap.h"
#include "ble/SecurityManager.h" #include "ble/SecurityManager.h"
#include "ble/BLE.h" #include "ble/BLE.h"

View File

@ -22,6 +22,7 @@
#include <string.h> #include <string.h>
#include "ble/SafeEnum.h" #include "ble/SafeEnum.h"
#include "ble/ArrayView.h" #include "ble/ArrayView.h"
#include "ble/gap/Types.h"
/** /**
* @addtogroup ble * @addtogroup ble
@ -32,6 +33,43 @@
namespace ble { namespace ble {
/** Special advertising set handle used for the legacy advertising set. */
static const advertising_handle_t LEGACY_ADVERTISING_HANDLE = 0x00;
/** Special advertising set handle used as return or parameter to signify an invalid handle. */
static const advertising_handle_t INVALID_ADVERTISING_HANDLE = 0xFF;
/** Maximum advertising data length that can fit in a legacy PDU. */
static const uint8_t LEGACY_ADVERTISING_MAX_SIZE = 0x1F;
/** Features supported by the controller.
* @see BLUETOOTH SPECIFICATION Version 5.0 | Vol 6, Part B - 4.6 */
struct controller_supported_features_t : SafeEnum<controller_supported_features_t, uint8_t> {
enum type {
LE_ENCRYPTION = 0,
CONNECTION_PARAMETERS_REQUEST_PROCEDURE,
EXTENDED_REJECT_INDICATION,
SLAVE_INITIATED_FEATURES_EXCHANGE,
LE_PING,
LE_DATA_PACKET_LENGTH_EXTENSION,
LL_PRIVACY,
EXTENDED_SCANNER_FILTER_POLICIES,
LE_2M_PHY,
STABLE_MODULATION_INDEX_TRANSMITTER,
STABLE_MODULATION_INDEX_RECEIVER,
LE_CODED_PHY,
LE_EXTENDED_ADVERTISING,
LE_PERIODIC_ADVERTISING,
CHANNEL_SELECTION_ALGORITHM_2,
LE_POWER_CLASS
};
/**
* Construct a new instance of ControllerSupportedFeatures_t.
*/
controller_supported_features_t(type value) : SafeEnum(value) { }
};
/** /**
* Opaque reference to a connection. * Opaque reference to a connection.
* *
@ -48,7 +86,6 @@ typedef uintptr_t connection_handle_t;
*/ */
typedef uint16_t attribute_handle_t; typedef uint16_t attribute_handle_t;
/** /**
* Inclusive range of GATT attributes handles. * Inclusive range of GATT attributes handles.
* *
@ -284,6 +321,10 @@ void set_all_zeros(byte_array_class &byte_array) {
memset(&byte_array[0], 0x00, byte_array.size()); memset(&byte_array[0], 0x00, byte_array.size());
} }
/**
* Model fixed size array values.
* @tparam array_size The size of the array.
*/
template <size_t array_size> template <size_t array_size>
struct byte_array_t { struct byte_array_t {
/** /**
@ -556,7 +597,12 @@ struct peer_address_type_t :SafeEnum<peer_address_type_t, uint8_t> {
/** /**
* A Random static address used as a device identity address. * A Random static address used as a device identity address.
*/ */
RANDOM_STATIC_IDENTITY RANDOM_STATIC_IDENTITY,
/**
* No address provided (anonymous advertisement).
*/
ANONYMOUS = 0xFF
}; };
/** /**
@ -578,6 +624,13 @@ struct peer_address_type_t :SafeEnum<peer_address_type_t, uint8_t> {
struct phy_t : SafeEnum<phy_t, uint8_t> { struct phy_t : SafeEnum<phy_t, uint8_t> {
/** struct scoped enum wrapped by the class */ /** struct scoped enum wrapped by the class */
enum type { enum type {
/**
* No phy selected.
*
* @note This value can be used to indicate the absence of phy
*/
NONE = 0,
/** /**
* 1Mbit/s LE. * 1Mbit/s LE.
* *
@ -625,6 +678,8 @@ struct phy_t : SafeEnum<phy_t, uint8_t> {
*/ */
phy_t(type value) : phy_t(type value) :
SafeEnum<phy_t, uint8_t>(value) { } SafeEnum<phy_t, uint8_t>(value) { }
explicit phy_t(uint8_t raw_value) : SafeEnum(raw_value) { }
}; };
/** /**
@ -658,16 +713,36 @@ public:
* @param phy_2m Prefer LE 2M if avaiable * @param phy_2m Prefer LE 2M if avaiable
* @param phy_coded Prefer coded modulation if avaiable * @param phy_coded Prefer coded modulation if avaiable
*/ */
phy_set_t( phy_set_t(bool phy_1m, bool phy_2m, bool phy_coded) :
bool phy_1m, _value()
bool phy_2m, {
bool phy_coded
) {
set_1m(phy_1m); set_1m(phy_1m);
set_2m(phy_2m); set_2m(phy_2m);
set_coded(phy_coded); set_coded(phy_coded);
} }
/**
* Create a set from a single phy.
*
* @param phy The phy to add to the set.
*/
phy_set_t(phy_t phy) : _value()
{
switch (phy.value()) {
case phy_t::LE_1M:
set_1m(true);
break;
case phy_t::LE_2M:
set_2m(true);
break;
case phy_t::LE_CODED:
set_coded(true);
break;
default:
break;
}
}
/** Prefer 1M PHY. */ /** Prefer 1M PHY. */
void set_1m(bool enabled = true) { void set_1m(bool enabled = true) {
if (enabled) { if (enabled) {
@ -715,6 +790,10 @@ public:
return _value; return _value;
} }
uint8_t count() const {
return (get_1m() ? 1 : 0) + (get_2m() ? 1 : 0) + (get_coded() ? 1 : 0);
}
private: private:
uint8_t _value; uint8_t _value;
}; };

View File

@ -18,7 +18,7 @@
#define MBED_DISCOVERED_CHARACTERISTIC_H__ #define MBED_DISCOVERED_CHARACTERISTIC_H__
#include "UUID.h" #include "UUID.h"
#include "Gap.h" #include "ble/Gap.h"
#include "GattAttribute.h" #include "GattAttribute.h"
#include "GattClient.h" #include "GattClient.h"
#include "CharacteristicDescriptorDiscovery.h" #include "CharacteristicDescriptorDiscovery.h"

View File

@ -18,7 +18,7 @@
#define MBED_DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__ #define MBED_DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__
#include "UUID.h" #include "UUID.h"
#include "Gap.h" #include "ble/Gap.h"
#include "GattAttribute.h" #include "GattAttribute.h"
#include "GattClient.h" #include "GattClient.h"
#include "CharacteristicDescriptorDiscovery.h" #include "CharacteristicDescriptorDiscovery.h"

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef MBED_GAP_ADVERTISING_DATA_H__ #ifndef MBED_GAP_ADVERTISING_DATA__LEGACY_H__
#define MBED_GAP_ADVERTISING_DATA_H__ #define MBED_GAP_ADVERTISING_DATA__LEGACY_H__
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -109,6 +109,10 @@
* some basic checks on the payload length and tries to avoid common * some basic checks on the payload length and tries to avoid common
* errors such as adding an exclusive AD field twice in the advertising * errors such as adding an exclusive AD field twice in the advertising
* or scan response payload. * or scan response payload.
*
* @deprecated Use AdvertisingData instead.
* This version provides the buffer backing for the advertising data
* but it's only big enough for legacy advertising.
*/ */
class GapAdvertisingData class GapAdvertisingData
{ {
@ -921,4 +925,4 @@ private:
*/ */
#endif /* ifndef MBED_GAP_ADVERTISING_DATA_H__ */ #endif /* ifndef MBED_GAP_ADVERTISING_DATA__LEGACY_H__ */

View File

@ -17,7 +17,7 @@
#ifndef __GATT_CHARACTERISTIC_H__ #ifndef __GATT_CHARACTERISTIC_H__
#define __GATT_CHARACTERISTIC_H__ #define __GATT_CHARACTERISTIC_H__
#include "Gap.h" #include "ble/Gap.h"
#include "SecurityManager.h" #include "SecurityManager.h"
#include "GattAttribute.h" #include "GattAttribute.h"
#include "GattCallbackParamTypes.h" #include "GattCallbackParamTypes.h"

View File

@ -17,7 +17,7 @@
#ifndef MBED_GATT_CLIENT_H__ #ifndef MBED_GATT_CLIENT_H__
#define MBED_GATT_CLIENT_H__ #define MBED_GATT_CLIENT_H__
#include "Gap.h" #include "ble/Gap.h"
#include "GattAttribute.h" #include "GattAttribute.h"
#include "ServiceDiscovery.h" #include "ServiceDiscovery.h"
#include "CharacteristicDescriptorDiscovery.h" #include "CharacteristicDescriptorDiscovery.h"

View File

@ -17,7 +17,7 @@
#ifndef MBED_GATT_SERVER_H__ #ifndef MBED_GATT_SERVER_H__
#define MBED_GATT_SERVER_H__ #define MBED_GATT_SERVER_H__
#include "Gap.h" #include "ble/Gap.h"
#include "GattService.h" #include "GattService.h"
#include "GattAttribute.h" #include "GattAttribute.h"
#include "GattServerEvents.h" #include "GattServerEvents.h"

View File

@ -107,6 +107,10 @@ namespace ble {
*/ */
template<typename Target, typename LayoutType = unsigned int> template<typename Target, typename LayoutType = unsigned int>
struct SafeEnum { struct SafeEnum {
/**
* Type of the representation.
*/
typedef LayoutType representation_t;
/** /**
* Construction of an enumeration value. * Construction of an enumeration value.
@ -197,6 +201,14 @@ struct SafeEnum {
return _value; return _value;
} }
/**
* Return a pointer to the inner storage.
*/
const LayoutType* storage() const
{
return &_value;
}
private: private:
LayoutType _value; LayoutType _value;
}; };

View File

@ -19,7 +19,7 @@
#include <stdint.h> #include <stdint.h>
#include "Gap.h" #include "ble/Gap.h"
#include "CallChainOfFunctionPointersWithContext.h" #include "CallChainOfFunctionPointersWithContext.h"
#include "ble/BLETypes.h" #include "ble/BLETypes.h"

View File

@ -18,7 +18,7 @@
#define MBED_BLE_SERVICE_DISOVERY_H__ #define MBED_BLE_SERVICE_DISOVERY_H__
#include "UUID.h" #include "UUID.h"
#include "Gap.h" #include "ble/Gap.h"
#include "GattAttribute.h" #include "GattAttribute.h"
class DiscoveredService; class DiscoveredService;

View File

@ -210,6 +210,11 @@ enum ble_error_t {
* The platform-specific stack failed. * The platform-specific stack failed.
*/ */
BLE_ERROR_INTERNAL_STACK_FAILURE = 12, BLE_ERROR_INTERNAL_STACK_FAILURE = 12,
/**
* Data not found or there is nothing to return.
*/
BLE_ERROR_NOT_FOUND = 13
}; };
/** /**

View File

@ -0,0 +1,108 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_COMMON_BOUNDED_H_
#define BLE_COMMON_BOUNDED_H_
#include <stdint.h>
namespace ble {
/**
* Restrict values of an integer type to a defined range.
*
* The range is a closed interval that includes its left-bound (Min) and
* right-bound value (Max).
*
* @tparam Rep The C++ integer type used to represent the values.
* @tparam Min Minimum value allowed.
* @tparam Max Maximum value allowed.
*/
template<typename Rep, Rep Min, Rep Max>
struct Bounded {
/**
* Construct a bounded integer.
*
* If v is out of the range [Min : Max], then if it is less than Min, the
* value of the bounded integer will be Min. If it greater than Max, then
* the value of the bounded integer will be Max.
*
* @param v The value to store.
*/
Bounded(Rep v) : _value(v)
{
if (v < Min) {
_value = v;
} else if (v > Max) {
_value = v;
}
}
/**
* Access the inner value.
*
* @return The current value.
*/
Rep value() const
{
return _value;
}
/**
* The left-bound value.
*
* @return The lowest value that this type can represent
*/
static Rep min()
{
return Min;
}
/**
* The right-bound value.
*
* @return The highest value that this type can represent
*/
static Rep max()
{
return Max;
}
/**
* The left-bound value.
*/
static const Rep MIN = Min;
/**
* The right-bound value.
*/
static const Rep MAX = Max;
private:
Rep _value;
};
/* ---------------------- Static variable initialization -------------------- */
template<typename T, T Min, T Max>
const T Bounded<T, Min, Max>::MIN;
template<typename T, T Min, T Max>
const T Bounded<T, Min, Max>::MAX;
} // namespace ble
#endif //BLE_COMMON_BOUNDED_H_

View File

@ -0,0 +1,578 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_COMMON_DURATION_H_
#define BLE_COMMON_DURATION_H_
#include <stdint.h>
#include <stddef.h>
#include "platform/mbed_assert.h"
namespace ble {
#if !defined(DOXYGEN_ONLY)
/**
* Define a compile time range.
* @tparam Min left-bound
* @tparam Max right-bound
*/
template<uint32_t Min, uint32_t Max>
struct Range {
static const uint32_t MIN = Min;
static const uint32_t MAX = Max;
};
/**
* Deduce default range for C++ basic integer types.
*
*
* @tparam Rep The C++ integer type.
*/
template<typename Rep>
struct DefaultRange;
/**
* DefaultRange specialization for uint8_t.
*/
template<>
struct DefaultRange<uint8_t> {
typedef Range<0, 0xFF> type;
};
/**
* DefaultRange specialization for uint16_t.
*/
template<>
struct DefaultRange<uint16_t > {
typedef Range<0, 0xFFFF> type;
};
/**
* DefaultRange specialization for uint32_t
*/
template<>
struct DefaultRange<uint32_t> {
typedef Range<0, 0xFFFFFFFF> type;
};
/**
* Represent an integral compile time value that can be used in Duration.
*
* @tparam T Type of the integral value.
* @tparam V The integer value representing a never ending duration.
*/
template<typename T, T V>
struct Value {
static const T VALUE = V;
};
#endif
/**
* Model BLE durations.
*
* @tparam Rep The representation type of the duration.
* @tparam TB The time base in us.
* @tparam Range Closed interval of the duration
* @tparam Forever The special value (if applicable) that represents a forever
* duration.
*/
template<
typename Rep,
uint32_t TB,
typename Range = typename DefaultRange<Rep>::type,
typename Forever = void*
>
struct Duration {
/**
* Type of the actual representation.
*/
typedef Rep representation_t;
/**
* Construct a default Duration.
*
* It is initialized with the minimum value acceptable.
*/
Duration() : duration(Range::MIN)
{
}
/**
* Construct a Duration from an integer value.
*
* @param v The value of the duration in TN units.
*/
explicit Duration(Rep v) : duration(clamp(v))
{
}
/**
* Construct a Duration from another Duration.
*
* @note The operation fail at compile time of there is a loss of precision.
*
* @tparam OtherRep The type used to represent the other Duration.
* @tparam OtherTB The time base in us units of the other Duration.
* @tparam OtherRange The range of the other Duration.
* @tparam OtherF The forever value of the other type.
*
* @param other The Duration used to construct this object.
*/
template<typename OtherRep, uint32_t OtherTB, typename OtherRange, typename OtherF>
Duration(Duration<OtherRep, OtherTB, OtherRange, OtherF> other) :
duration(clamp(other.value() * (OtherTB / TB)))
{
MBED_STATIC_ASSERT(OtherTB >= TB && (OtherTB % TB) == 0, "Incompatible units");
}
/**
* Construct a new Duration from a Duration in milliseconds.
*
* @note The result of the conversion is rounded up.
*
* @tparam OtherRep The representation type used by other_ms.
* @tparam OtherRange The range used by other_ms.
* @tparam OtherF The forever value used by other_ms.
*
* @param other_ms The Duration in ms to convert.
*/
template<typename OtherRep, typename OtherRange, typename OtherF>
explicit Duration(Duration<OtherRep, 1000, OtherRange, OtherF> other_ms, void* = NULL) :
duration(clamp(((other_ms.value() * 1000) + TB - 1) / TB))
{
}
/**
* Return the duration in TB units.
*
* @return The duration in TB units.
*/
Rep value() const
{
return duration;
}
/**
* Return the duration in milliseconds.
*
* @return The duration in milliseconds.
*/
uint32_t valueInMs() const
{
return ((uint32_t)duration * TB) / 1000;
}
/**
* The time base.
*/
static const uint32_t TIME_BASE = TB;
/**
* Left-bound of the duration range.
*/
static const Rep MIN = Range::MIN;
/**
* Right bound of the duration range.
*/
static const Rep MAX = Range::MAX;
/**
* Return the minimum duration.
*
* @return The minimum duration.
*/
static Duration min()
{
return Duration(MIN);
}
/**
* Return the maximum duration.
*
* @return The maximum duration.
*/
static Duration max()
{
return Duration(MAX);
}
/**
* Return a pointer to the value of the duration.
*
* @return a pointer to the value of the duration.
*/
const Rep* storage() const
{
return &duration;
}
/**
* Return the Duration value meaning forever.
* @return the Duration value meaning forever.
*/
static Duration forever()
{
return Duration(Forever::VALUE);
}
private:
static Rep clamp(Rep in)
{
if (in < MIN) {
return MIN;
} else if (in > MAX) {
return MAX;
} else {
return in;
}
}
Rep duration;
};
/**
* Type that represents micro seconds.
*/
typedef Duration<uint32_t, 1> microsecond_t;
/**
* Type that represents milliseconds.
*/
typedef Duration<uint32_t, 1000 * microsecond_t::TIME_BASE> millisecond_t;
/**
* Type that represents seconds.
*/
typedef Duration<uint32_t, 1000 * millisecond_t::TIME_BASE> second_t;
/**
* Cast a duration to another.
*
* @tparam DurationOut Type of the Duration in output.
* @tparam RepIn The representation type of duration.
* @tparam TBIn The timebase of duration.
* @tparam RangeIn The range of duration.
* @tparam FIn The Forever value of duration.
* @param duration The duration to convert.
* @return The converted duration. It is rounded up if precision is loss.
*
* @related Duration
*/
template<typename DurationOut, typename RepIn, uint32_t TBIn, typename RangeIn, typename FIn>
DurationOut durationCast(Duration<RepIn, TBIn, RangeIn, FIn> duration)
{
return DurationOut(((duration.value() * TBIn) + DurationOut::TIME_BASE - 1) / DurationOut::TIME_BASE);
}
/**
* Add two durations together and return the result in microseconds.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return The result of the addition of the two durations in microseconds.
*
* @related Duration
*/
template<
typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS>
microsecond_t operator+(
Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
)
{
return microsecond_t((lhs.value() * lhs.TIME_BASE) + (rhs.value() * rhs.TIME_BASE));
}
/**
* Add two durations together.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return The addition of the two durations in input.
*
* @related Duration
*/
template<typename Rep, uint32_t TB, typename Range, typename F>
Duration<Rep, TB, Range, F> operator+(
Duration<Rep, TB, Range, F> lhs,
Duration<Rep, TB, Range, F> rhs
)
{
return Duration<Rep, TB, Range, F>(lhs.value() + rhs.value());
}
/**
* Multiply a duration and a positive integer.
*
* @param lhs The duration.
* @param rhs The integer.
*
* @return A duration that represents the multiplication of lhs with rhs.
*
* @related Duration
*/
template<typename Rep, uint32_t TB, typename Range, typename F>
Duration<Rep, TB, Range, F> operator*(Duration<Rep, TB, Range, F> lhs, uint32_t rhs)
{
return Duration<Rep, TB, Range, F>(lhs.value() * rhs);
}
/**
* Multiply a duration and a positive integer.
*
* @param lhs The integer.
* @param rhs The multiplication.
*
* @return A duration that represents the multiplication of lhs with rhs.
*
* @related Duration
*/
template<typename Rep, uint32_t TB, typename Range, typename F>
Duration<Rep, TB, Range, F> operator*(uint32_t lhs, Duration<Rep, TB, Range, F> rhs)
{
return Duration<Rep, TB, Range, F>(lhs * rhs.value());
}
/**
* Indicate if the duration lhs is less than the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is less than rhs and false otherwise.
*
* @related Duration
*/
template<
typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
>
bool operator<(Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs, Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs)
{
return lhs.value() * lhs.TIME_BASE < rhs.value() * rhs.TIME_BASE;
}
/**
* Indicate if the duration lhs is less than the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is less than rhs and false otherwise.
*
* @related Duration
*/
template<typename Rep, uint32_t Us, typename Range, typename F>
bool operator<(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
{
return lhs.value() < rhs.value();
}
/**
* Indicate if the duration lhs is less than or equal to the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is less than or equal to rhs and false otherwise.
*
* @related Duration
*/
template<
typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
>
bool operator<=(
Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
)
{
return lhs.value() * lhs.TIME_BASE <= rhs.value() * rhs.TIME_BASE;
}
/**
* Indicate if the duration lhs is less than or equal to the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is less than or equal to rhs and false otherwise.
*
* @related Duration
*/
template<typename Rep, uint32_t Us, typename Range>
bool operator<=(Duration<Rep, Us, Range> lhs, Duration<Rep, Us, Range> rhs)
{
return lhs.value() <= rhs.value();
}
/**
* Indicate if the duration lhs is equal to the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is equal to rhs and false otherwise.
*
* @related Duration
*/
template<
typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
>
bool operator==(
Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
)
{
return lhs.value() * lhs.TIME_BASE == rhs.value() * rhs.TIME_BASE;
}
/**
* Indicate if the duration lhs is equal to the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is equal to rhs and false otherwise.
*
* @related Duration
*/
template<typename Rep, uint32_t Us, typename Range, typename F>
bool operator==(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
{
return lhs.value() == rhs.value();
}
/**
* Indicate if the duration lhs is not equal to the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is not equal to rhs and false otherwise.
*
* @related Duration
*/
template<
typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
>
bool operator!=(
Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
)
{
return !(lhs == rhs);
}
/**
* Indicate if the duration lhs is not equal to the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is not equal to rhs and false otherwise.
*
* @related Duration
*/
template<typename Rep, uint32_t Us, typename Range, typename F>
bool operator!=(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
{
return !(lhs == rhs);
}
/**
* Indicate if the duration lhs greater or equal to the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is greater or equal to rhs and false otherwise.
*
* @related Duration
*/
template<
typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
>
bool operator>=(
Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
)
{
return rhs <= lhs;
}
/**
* Indicate if the duration lhs greater or equal to the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is greater or equal to rhs and false otherwise.
*
* @related Duration
*/
template<typename Rep, uint32_t Us, typename Range, typename F>
bool operator>=(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
{
return rhs <= lhs;
}
/**
* Indicate if the duration lhs greater than the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is greater than rhs and false otherwise.
*
* @related Duration
*/
template<
typename RepLHS, uint32_t TBLHS, typename RangeLHS, typename FLHS,
typename RepRHS, uint32_t TBRHS, typename RangeRHS, typename FRHS
>
bool operator>(
Duration<RepLHS, TBLHS, RangeLHS, FLHS> lhs,
Duration<RepRHS, TBRHS, RangeRHS, FRHS> rhs
)
{
return rhs < lhs;
}
/**
* Indicate if the duration lhs greater than the duration rhs.
* @param lhs Left hand side operand.
* @param rhs Right hand side operand.
* @return true if lhs is greater than rhs and false otherwise.
*
* @related Duration
*/
template<typename Rep, uint32_t Us, typename Range, typename F>
bool operator>(Duration<Rep, Us, Range, F> lhs, Duration<Rep, Us, Range, F> rhs)
{
return rhs < lhs;
}
/* ---------------------- Static variable initialization -------------------- */
#if !defined(DOXYGEN_ONLY)
template<uint32_t Min, uint32_t Max>
const uint32_t Range<Min, Max>::MIN;
template<uint32_t Min, uint32_t Max>
const uint32_t Range<Min, Max>::MAX;
template<typename T, T V>
const T Value<T, V>::VALUE;
#endif
template<typename Rep, uint32_t TB, typename Range, typename Forever>
const uint32_t Duration<Rep, TB, Range, Forever>::TIME_BASE;
template<typename Rep, uint32_t TB, typename Range, typename Forever>
const Rep Duration<Rep, TB, Range, Forever>::MIN;
template<typename Rep, uint32_t TB, typename Range, typename Forever>
const Rep Duration<Rep, TB, Range, Forever>::MAX;
}
#endif //BLE_COMMON_DURATION_H_

View File

@ -0,0 +1,446 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GAP_ADVERTISING_DATA_H__
#define MBED_GAP_ADVERTISING_DATA_H__
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "platform/Span.h"
#include "platform/NonCopyable.h"
#include "ble/blecommon.h"
#include "UUID.h"
#include "ble/gap/AdvertisingDataTypes.h"
#include "ble/gap/Types.h"
namespace ble {
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/**
* Build advertising data.
*
* The builder accepts an array of bytes in input and returns the result of the
* construction with getAdvertisingData().
*/
class AdvertisingDataBuilder {
public:
/** Advertising data needs a user-provided buffer to store the data.
*
* @param buffer Buffer used to store the data.
* @note Use Gap::getMaxAdvertisingDataLength() to find out how much can be accepted.
*/
AdvertisingDataBuilder(mbed::Span<uint8_t> buffer);
/** Advertising data needs a user provided buffer to store the data.
*
* @param buffer Pointer to buffer to be used for storing advertising data.
* @param buffer_size Size of the buffer.
* @note Use Gap::getMaxAdvertisingDataLength() to find out how much can be accepted.
*/
AdvertisingDataBuilder(uint8_t *buffer, size_t buffer_size);
/**
* Get the subspan of the buffer containing valid data.
*
* @return A Span containing the payload.
*/
mbed::Span<const uint8_t> getAdvertisingData() const;
/**
* Add a new field into the payload. Returns an error if type is already present.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] advDataType The type of the field to add.
* @param[in] fieldData Span of data to add.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_OPERATION_NOT_PERMITTED if data type already present.
* @retval BLE_ERROR_INVALID_PARAM if size of data is too big too fit in an individual data field.
*/
ble_error_t addData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
);
/**
* Replace a new field into the payload. Will fail if type is not already present.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] advDataType The type of the field to add.
* @param[in] fieldData Span of data to add.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_NOT_FOUND if data type not present.
* @retval BLE_ERROR_INVALID_PARAM if size of data is too big too fit in an individual data field.
*/
ble_error_t replaceData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
);
/**
* Append data to an existing field in the payload. Will fail if type is not already
* present.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] advDataType The type of the field to add.
* @param[in] fieldData Span of data to add.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_NOT_FOUND if data type not present.
* @retval BLE_ERROR_INVALID_PARAM if size of data is too big too fit in an individual data field.
*/
ble_error_t appendData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
);
/**
* Remove existing date of given type. Will return an error if type is not present.
*
* @param[in] advDataType The type of the field to remove.
*
* @return BLE_ERROR_NONE returned on success, BLE_ERROR_INVALID_PARAM if field doesn't exist
*/
ble_error_t removeData(adv_data_type_t advDataType);
/**
* Adds a new field into the payload. If the supplied advertising data type is
* already present in the advertising payload, then the value is replaced.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] advDataType The type of the field to add.
* @param[in] fieldData Span of data to add.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_INVALID_PARAM if size of data is too big too fit in an individual data field.
*/
ble_error_t addOrReplaceData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
);
/**
* Adds a new field into the payload. If the supplied advertising data type is
* already present in the advertising payload, then the value is replaced.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] advDataType The type of the field to add.
* @param[in] fieldData Span of data to add.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_INVALID_PARAM if size of data is too big too fit in an individual data field.
*/
ble_error_t addOrAppendData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
);
/**
* Clears the advertising data payload.
*
* @post getPayloadLen() returns 0.
*/
void clear();
/**
* Add device appearance in the advertising payload.
*
* @param[in] appearance The appearance to advertise.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
*
* @note This call is equivalent to calling addOrReplaceData() with
* adv_data_type_t::APPEARANCE as the field type.
*/
ble_error_t setAppearance(adv_data_appearance_t appearance);
/**
* Add BLE flags in the advertising payload.
*
* @param[in] flags Bitfield describing the capability of the device. See
* allowed flags in Flags_t.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
*
* @note This call is equivalent to calling addOrReplaceData() with
* adv_data_type_t::FLAGS as the field type.
*/
ble_error_t setFlags(
adv_data_flags_t flags = adv_data_flags_t::default_flags
);
/**
* Add the advertising TX in the advertising payload.
*
* @param[in] txPower Transmission power level in dB.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
*
* @note This call is equivalent to calling addOrReplaceData() with
* adv_data_type_t::TX_POWER_LEVEL as the field type.
*/
ble_error_t setTxPowerAdvertised(advertising_power_t txPower);
/**
* Add device name to the advertising payload.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] name Null terminated string containing the name.
* @param[in] complete Complete local name if true, otherwise
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_INVALID_PARAM if size of data is too big too fit in an individual data field.
*/
ble_error_t setName(const char *name, bool complete = true);
/**
* Add manufacturer-specific data to the advertising payload.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] data New data to be added.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_INVALID_PARAM if size of data is too big too fit in an individual
* data field or the data is too small (must contain
* 2 bytes of manufacturer ID)
*/
ble_error_t setManufacturerSpecificData(mbed::Span<const uint8_t> data);
/**
* Add advertising interval to the payload. This field can only carry 2 bytes.
*
* @param interval Interval to advertise. Cannot be larger than 0xFFFF.
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_INVALID_PARAM if interval value outside of valid range.
*/
ble_error_t setAdvertisingInterval(adv_interval_t interval);
/**
* Add connection interval preferences to the payload
*
* @param min Minimum connection interval to advertise.
* @param max Maximum connection interval to advertise.
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
*/
ble_error_t setConnectionIntervalPreference(
conn_interval_t min,
conn_interval_t max
);
/**
* Add service data data to the advertising payload.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] service UUID of the service.
* @param[in] data New data to be added.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_INVALID_PARAM if size of data is too big too fit in an individual data field.
*/
ble_error_t setServiceData(UUID service, mbed::Span<const uint8_t> data);
/**
* Add local service IDs to the advertising payload. If the data can't fit,
* no modification will take place.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] data New data to be added.
* @param[in] complete True if this is a complete list.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_INVALID_PARAM if number of UUIDs of any one type is too high.
*/
ble_error_t setLocalServiceList(
mbed::Span<const UUID> data,
bool complete = true
);
/**
* Add a list of UUIDs of solicited services.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] data List of 128 or 16 bit service UUIDs.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_INVALID_PARAM if number of UUIDs of any one type is too high.
*/
ble_error_t setRequestedServiceList(mbed::Span<const UUID> data);
/**
* Return a span of data containing the the type of data requested.
*
* @param[out] data Span used to return the requested data.
* @param[in] advDataType Data type to return.
*
* @return BLE_ERROR_NONE if data was found and BLE_ERROR_NOT_FOUND if not.
*/
ble_error_t getData(
mbed::Span<const uint8_t> &data,
adv_data_type_t advDataType
);
private:
/**
* Search advertisement data for a specific field.
*
* @param[in] type The type of the field to find.
*
* @return A pointer to the first element in the field if found. The first
* element being the length of the field followed by the value of the field.
* NULL if the field is not present in the payload.
*/
uint8_t *findField(adv_data_type_t type);
/**
* Get field size (includes type and size bytes)
*
* @param type The field type.
*
* @return Size of the whole field including type and size bytes.
*/
uint8_t getFieldSize(adv_data_type_t type);
/**
* Append advertising data based on the specified type.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] advDataType Type of the new data.
* @param[in] fieldData Span of data to add.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
*/
ble_error_t addField(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
);
/**
* Append data to a field in the advertising payload.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] fieldData Span of data to add.
* @param[in] field Pointer to the field in the advertising buffer.
*
* @return BLE_ERROR_NONE on success.
*/
ble_error_t appendToField(
mbed::Span<const uint8_t> fieldData,
uint8_t *field
);
/**
* Update in place the value of a field in the advertising payload.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] advDataType Type of the new data.
* @param[in] fieldData Span of data to add.
* @param[in] field Pointer to the field of type @p advDataType in the
* advertising buffer.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
*/
ble_error_t replaceField(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData,
uint8_t *field
);
/**
* Remove the field.
*
* @param[in] field Pointer to the field in the advertising buffer.
*
* @return BLE_ERROR_NONE on success.
*/
ble_error_t removeField(uint8_t *field);
/**
* Add a list of UUIDs to given types.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] data List of 128 or 16 bit service UUIDs.
* @param[in] shortType Type of field to add the short UUIDs to.
* @param[in] longType Type of field to add the long UUIDs to.
*
* @retval BLE_ERROR_NONE on success.
* @retval BLE_ERROR_BUFFER_OVERFLOW if buffer is too small to contain the new data.
* @retval BLE_ERROR_INVALID_PARAM if number of UUIDs of any one type is too high.
*/
ble_error_t setUUIDData(
mbed::Span<const UUID> data,
adv_data_type_t shortType,
adv_data_type_t longType
);
private:
/** The memory backing the the data provided by the user. */
mbed::Span<uint8_t> _buffer;
/** Length of the data added to the advertising buffer. */
uint8_t _payload_length;
};
/**
* @}
* @}
*/
} // namespace ble
#endif /* ifndef MBED_GAP_ADVERTISING_DATA_H__ */

View File

@ -0,0 +1,122 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_GAP_ADVERTISINGDATAPARSER_H
#define BLE_GAP_ADVERTISINGDATAPARSER_H
#include <stdint.h>
#include "ble/gap/AdvertisingDataTypes.h"
#include "platform/Span.h"
namespace ble {
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/**
* Parse and iterate over advertising data
*/
class AdvertisingDataParser {
enum {
DATA_SIZE_INDEX = 0,
TYPE_INDEX = 1,
VALUE_INDEX = 2,
TYPE_SIZE = 1,
DATA_SIZE_SIZE = 1
};
public:
/**
* Representation of an Advertising Data element.
*/
struct element_t {
adv_data_type_t type;
mbed::Span<const uint8_t> value;
};
/**
* Build a parser from an array of bytes.
* @param data The data to parse.
*/
AdvertisingDataParser(mbed::Span<const uint8_t> data) :
data(data),
position(0)
{
}
/**
* Return if there is advertising data element left to parse.
*/
bool hasNext() const
{
if (position >= data.size()) {
return false;
}
if (position + current_length() >= data.size()) {
return false;
}
return true;
}
/**
* Return the next advertising data element.
*
* @note Calling this function if there is no next element is undefined
* behavior.
*/
element_t next()
{
element_t element = {
(ble::adv_data_type_t::type) data[TYPE_INDEX],
data.subspan(position + VALUE_INDEX, current_length() - (TYPE_SIZE))
};
position += (DATA_SIZE_SIZE + current_length());
return element;
}
/**
* Reset the parser.
*/
void reset()
{
position = 0;
}
private:
uint8_t current_length() const {
return data[position + DATA_SIZE_INDEX];
}
mbed::Span<const uint8_t> data;
size_t position;
};
/**
* @}
* @}
*/
} // namespace ble
#endif //BLE_GAP_ADVERTISINGDATAPARSER_H

View File

@ -0,0 +1,315 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_GAP_SIMPLEADVERTISINGDATABUILDER_H
#define BLE_GAP_SIMPLEADVERTISINGDATABUILDER_H
#include "ble/gap/AdvertisingDataBuilder.h"
namespace ble {
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/**
* Build advertising data.
*
* It is a simplified version of AdvertisingDataBuilder that can generate
* advertising data "inline".
*
* It differs from AdvertisingDataBuilder on the following points:
* - The buffer used to build the advertising data is embedded in the object.
* - If insertion fails, an assertion is raised. Outside of debug mode, if an
* insertion fails, the buffer is not modified.
* - The API is fluent.
* - It hides advanced functions.
*
* @code
void setupAdvertisingData(ble::Gap& gap)
{
using namespace ble;
gap.setAdvertisingPayload(
LEGACY_ADVERTISING_HANDLE,
AdvertisingDataSimpleBuilder<LEGACY_ADVERTISING_MAX_SIZE>()
.setFlags()
.setName("My device", true)
.setAppearance(adv_data_appearance_t::GENERIC_HEART_RATE_SENSOR)
.setLocalService(ATT_UUID_HEART_RATE_SERVICE)
.getAdvertisingData()
);
}
* @endcode
*/
template<size_t DataSize>
class AdvertisingDataSimpleBuilder {
public:
/**
* Construct a AdvertisingDataSimpleBuilder
*/
AdvertisingDataSimpleBuilder() : _builder(_buffer)
{
}
/**
* Add device appearance in the advertising payload.
*
* @param[in] appearance The appearance to advertise.
*
* @return A reference to this object.
*
* @note If the field is already present in the payload, it is replaced.
*/
AdvertisingDataSimpleBuilder &setAppearance(adv_data_appearance_t appearance)
{
MBED_ASSERT(_builder.setAppearance(appearance) == BLE_ERROR_NONE);
return *this;
}
/**
* Add BLE flags in the advertising payload.
*
* @param[in] flags Bitfield describing the capability of the device. See
* allowed flags in Flags_t.
*
* @return A reference to this object.
*
* @note If the field is already present in the payload, it is replaced.
*/
AdvertisingDataSimpleBuilder &setFlags(
adv_data_flags_t flags = adv_data_flags_t::default_flags
)
{
MBED_ASSERT(_builder.setFlags(flags) == BLE_ERROR_NONE);
return *this;
}
/**
* Add the advertising TX in the advertising payload.
*
* @param[in] txPower Transmission power level in dB.
*
* @return A reference to this object.
*
* @note If the field is already present in the payload, it is replaced.
*/
AdvertisingDataSimpleBuilder &setTxPowerAdvertised(advertising_power_t txPower)
{
MBED_ASSERT(_builder.setTxPowerAdvertised(txPower) == BLE_ERROR_NONE);
return *this;
}
/**
* Add device name to the advertising payload.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] name Null terminated string containing the name.
* @param[in] complete Complete local name if true, otherwise
*
* @return A reference to this object.
*
* @note If the field is already present in the payload, it is replaced.
*/
AdvertisingDataSimpleBuilder &setName(const char *name, bool complete = true)
{
MBED_ASSERT(_builder.setName(name, complete) == BLE_ERROR_NONE);
return *this;
}
/**
* Add manufacturer specific data to the advertising payload.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] data New data to be added.
*
* @return a reference to this object.
*/
AdvertisingDataSimpleBuilder &setManufacturerSpecificData(mbed::Span<const uint8_t> data)
{
MBED_ASSERT(_builder.setManufacturerSpecificData(data) == BLE_ERROR_NONE);
return *this;
}
/**
* Add advertising interval to the payload. This field can only carry 2 bytes.
*
* @param interval Interval to advertise. Cannot be larger than 0xFFFF.
*
* @return a reference to this object.
*/
AdvertisingDataSimpleBuilder &setAdvertisingInterval(adv_interval_t interval)
{
MBED_ASSERT(_builder.setAdvertisingInterval(interval) == BLE_ERROR_NONE);
}
/**
* Add connection interval preferences to the payload
*
* @param min Minimum connection interval to advertise.
* @param max Maximum connection interval to advertise.
*
* @return a reference to this object.
*/
AdvertisingDataSimpleBuilder &setConnectionIntervalPreference(
conn_interval_t min,
conn_interval_t max
)
{
MBED_ASSERT(_builder.setConnectionIntervalPreference(min, max) == BLE_ERROR_NONE);
return *this;
}
/**
* Add service data to the advertising payload.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] service UUID of the service.
* @param[in] data New data to be added.
*
* @return A reference to this object.
*/
AdvertisingDataSimpleBuilder &setServiceData(UUID service, mbed::Span<const uint8_t> data)
{
MBED_ASSERT(_builder.setServiceData(service, data) == BLE_ERROR_NONE);
return *this;
}
/**
* Add local service ID to the advertising payload. If the data can't fit,
* no modification will take place.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] data New data to be added.
* @param[in] complete True if this is a complete list.
*
* @return A reference to this object.
*/
AdvertisingDataSimpleBuilder &setLocalService(
const UUID& data,
bool complete = true
)
{
MBED_ASSERT(
_builder.setLocalServiceList(
mbed::make_Span(&data, 1), complete
) == BLE_ERROR_NONE
);
return *this;
}
/**
* Add local service IDs to the advertising payload. If the data can't fit,
* no modification will take place.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] data New data to be added.
* @param[in] complete True if this is a complete list.
*
* @return A reference to this object.
*/
AdvertisingDataSimpleBuilder &setLocalServiceList(
mbed::Span<const UUID> data,
bool complete = true
)
{
MBED_ASSERT(_builder.setLocalServiceList(data, complete) == BLE_ERROR_NONE);
return *this;
}
/**
* Add a UUID of a solicited service.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] data List of 128 or 16 bit service UUIDs.
*
* @return A reference to this object.
*/
AdvertisingDataSimpleBuilder &setRequestedService(const UUID& data)
{
MBED_ASSERT(
_builder.setRequestedServiceList(mbed::make_Span(&data, 1)) == BLE_ERROR_NONE
);
return *this;
}
/**
* Add a list of UUIDs of solicited services.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] data List of 128 or 16 bit service UUIDs.
*
* @return A reference to this object.
*/
AdvertisingDataSimpleBuilder &setRequestedServiceList(mbed::Span<const UUID> data)
{
MBED_ASSERT(_builder.setRequestedServiceList(data) == BLE_ERROR_NONE);
return *this;
}
/**
* Add a new field into the payload. The operation fails if type is already present.
*
* @note Data size for individual types cannot exceed 255 bytes.
*
* @param[in] advDataType The type of the field to add.
* @param[in] fieldData Span of data to add.
*
* @return A reference to this object.
*/
AdvertisingDataSimpleBuilder& addData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
)
{
MBED_ASSERT(_builder.addData(advDataType, fieldData) == BLE_ERROR_NONE);
return *this;
}
/**
* Get the subspan of the buffer containing valid data.
*
* @return A Span containing the payload.
*/
mbed::Span<const uint8_t> getAdvertisingData() const
{
return _builder.getAdvertisingData();
}
private:
uint8_t _buffer[DataSize];
AdvertisingDataBuilder _builder;
};
/**
* @}
* @}
*/
} // namespace ble
#endif //BLE_GAP_SIMPLEADVERTISINGDATABUILDER_H

View File

@ -0,0 +1,539 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_GAP_ADVERTISINGDATATYPES_H
#define BLE_GAP_ADVERTISINGDATATYPES_H
#include "ble/SafeEnum.h"
namespace ble {
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/*!
* List of standard Advertising Data types.
*
* These AD types are used to describe the capabilities of the peripheral
* and are inserted inside the advertising or scan response payloads.
*
* @par Source
*
* @li @c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 11, 18.
* @li @c https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile.
*/
struct adv_data_type_t : SafeEnum<adv_data_type_t, uint8_t> {
/** struct scoped enum wrapped by the class */
enum type {
/**
* Flags, refer to AdvertisingData::Flags_t.
*/
FLAGS = 0x01,
/**
* Incomplete list of 16-bit Service IDs.
*/
INCOMPLETE_LIST_16BIT_SERVICE_IDS = 0x02,
/**
* Complete list of 16-bit Service IDs.
*/
COMPLETE_LIST_16BIT_SERVICE_IDS = 0x03,
/**
* Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0).
*/
INCOMPLETE_LIST_32BIT_SERVICE_IDS = 0x04,
/**
* Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0).
*/
COMPLETE_LIST_32BIT_SERVICE_IDS = 0x05,
/**
* Incomplete list of 128-bit Service IDs.
*/
INCOMPLETE_LIST_128BIT_SERVICE_IDS = 0x06,
/**
* Complete list of 128-bit Service IDs.
*/
COMPLETE_LIST_128BIT_SERVICE_IDS = 0x07,
/**
* Shortened Local Name.
*/
SHORTENED_LOCAL_NAME = 0x08,
/**
* Complete Local Name.
*/
COMPLETE_LOCAL_NAME = 0x09,
/**
* TX Power Level (in dBm).
*/
TX_POWER_LEVEL = 0x0A,
/**
* Device ID.
*/
DEVICE_ID = 0x10,
/**
* Slave Connection Interval Range.
*/
SLAVE_CONNECTION_INTERVAL_RANGE = 0x12,
/**
* List of 128-bit service UUIDs the device is looking for.
*/
LIST_16BIT_SOLICITATION_IDS = 0x14,
/**
* List of 128-bit service UUIDs the device is looking for.
*/
LIST_128BIT_SOLICITATION_IDS = 0x15,
/**
* Service Data.
*/
SERVICE_DATA = 0x16,
/**
* Service Data.
*/
SERVICE_DATA_16BIT_ID = 0x16,
/**
* Service Data.
*/
SERVICE_DATA_128BIT_ID = 0x21,
/**
* Appearance, refer to AdvertisingData::Appearance_t.
*/
APPEARANCE = 0x19,
/**
* Advertising Interval.
*/
ADVERTISING_INTERVAL = 0x1A,
/**
* Manufacturer Specific Data.
*/
MANUFACTURER_SPECIFIC_DATA = 0xFF
};
/**
* Construct a new instance of adv_data_type_t.
*/
adv_data_type_t(type value) : SafeEnum(value)
{
}
};
/**
* Set of advertising flags.
*
* @note LE_LIMITED_DISCOVERABLE and LE_GENERAL_DISCOVERABLE are mutually
* exclusive
*
* @li @c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 18.1.
*/
struct adv_data_flags_t {
enum {
LE_LIMITED_DISCOVERABLE = 0x01, /**< Discoverable for a limited period of time.*/
LE_GENERAL_DISCOVERABLE = 0x02, /**< Discoverable at any moment. */
BREDR_NOT_SUPPORTED = 0x04, /**< LE only and does not support Bluetooth Enhanced DataRate. */
SIMULTANEOUS_LE_BREDR_C = 0x08, /**< Not relevant - dual mode only. */
SIMULTANEOUS_LE_BREDR_H = 0x10 /**< Not relevant - dual mode only. */
};
static const uint8_t default_flags = BREDR_NOT_SUPPORTED | LE_GENERAL_DISCOVERABLE;
/** Create from raw value */
adv_data_flags_t(uint8_t value = 0) : _value(value)
{
}
adv_data_flags_t &setGeneralDiscoverable(bool enable = true)
{
_value &= ~0x03;
if (enable) {
_value |= LE_GENERAL_DISCOVERABLE;
}
return *this;
}
adv_data_flags_t &setLimitedDiscoverable(bool enable = true)
{
_value &= ~0x03;
if (enable) {
_value |= LE_LIMITED_DISCOVERABLE;
}
return *this;
}
adv_data_flags_t &setBredrNotSupported(bool enable = true)
{
_value &= ~BREDR_NOT_SUPPORTED;
if (enable) {
_value |= BREDR_NOT_SUPPORTED;
}
return *this;
}
adv_data_flags_t &setSimultaneousLeBredrC(bool enable = true)
{
_value &= ~SIMULTANEOUS_LE_BREDR_C;
if (enable) {
_value |= SIMULTANEOUS_LE_BREDR_C;
}
return *this;
}
adv_data_flags_t &setSimultaneousLeBredrH(bool enable = true)
{
_value &= ~SIMULTANEOUS_LE_BREDR_H;
if (enable) {
_value |= SIMULTANEOUS_LE_BREDR_H;
}
return *this;
}
bool getGeneralDiscoverable()
{
return _value & LE_GENERAL_DISCOVERABLE;
}
bool getlimitedDiscoverable()
{
return _value & LE_LIMITED_DISCOVERABLE;
}
bool getBrEdrNotSupported()
{
return _value & BREDR_NOT_SUPPORTED;
}
bool getSimultaneousLeBredrC()
{
return _value & SIMULTANEOUS_LE_BREDR_C;
}
bool getSimultaneousLeBredrH()
{
return _value & SIMULTANEOUS_LE_BREDR_H;
}
void clear()
{
_value = 0;
}
uint8_t value()
{
return _value;
}
private:
uint8_t _value;
};
/**
* Enumeration of values for the adv_data_type_t::APPEARANCE.
*
* These values describe the physical shape or appearance of the device.
*
* @par Source
*
* @li @c Bluetooth Core Specification Supplement, Part A, Section 1.12.
* @li @c Bluetooth Core Specification 4.0 (Vol. 3), Part C, Section 12.2.
* @li @c https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml.
*/
struct adv_data_appearance_t : SafeEnum<adv_data_appearance_t, uint16_t> {
/** struct scoped enum wrapped by the class */
enum type {
/**
* Unknown or unspecified appearance type.
*/
UNKNOWN = 0,
/**
* Generic Phone.
*/
GENERIC_PHONE = 64,
/**
* Generic Computer.
*/
GENERIC_COMPUTER = 128,
/**
* Generic Watch.
*/
GENERIC_WATCH = 192,
/**
* Sports Watch.
*/
WATCH_SPORTS_WATCH = 193,
/**
* Generic Clock.
*/
GENERIC_CLOCK = 256,
/**
* Generic Display.
*/
GENERIC_DISPLAY = 320,
/**
* Generic Remote Control.
*/
GENERIC_REMOTE_CONTROL = 384,
/**
* Generic Eye Glasses.
*/
GENERIC_EYE_GLASSES = 448,
/**
* Generic Tag.
*/
GENERIC_TAG = 512,
/**
* Generic Keyring.
*/
GENERIC_KEYRING = 576,
/**
* Generic Media Player.
*/
GENERIC_MEDIA_PLAYER = 640,
/**
* Generic Bar Code Scanner.
*/
GENERIC_BARCODE_SCANNER = 704,
/**
* Generic Thermometer.
*/
GENERIC_THERMOMETER = 768,
/**
* Ear Thermometer.
*/
THERMOMETER_EAR = 769,
/**
* Generic Heart Rate Sensor.
*/
GENERIC_HEART_RATE_SENSOR = 832,
/**
* Belt Heart Rate Sensor.
*/
HEART_RATE_SENSOR_HEART_RATE_BELT = 833,
/**
* Generic Blood Pressure.
*/
GENERIC_BLOOD_PRESSURE = 896,
/**
* Arm Blood Pressure.
*/
BLOOD_PRESSURE_ARM = 897,
/**
* Wrist Blood Pressure.
*/
BLOOD_PRESSURE_WRIST = 898,
/**
* Human Interface Device (HID).
*/
HUMAN_INTERFACE_DEVICE_HID = 960,
/**
* Keyboard.
*/
KEYBOARD = 961,
/**
* Mouse.
*/
MOUSE = 962,
/**
* Joystick.
*/
JOYSTICK = 963,
/**
* Gamepad.
*/
GAMEPAD = 964,
/**
* Digitizer Tablet.
*/
DIGITIZER_TABLET = 965,
/**
* Card Reader.
*/
CARD_READER = 966,
/**
* Digital Pen.
*/
DIGITAL_PEN = 967,
/**
* Bar Code Scanner.
*/
BARCODE_SCANNER = 968,
/**
* Generic Glucose Meter.
*/
GENERIC_GLUCOSE_METER = 1024,
/**
* Generic Running/Walking Sensor.
*/
GENERIC_RUNNING_WALKING_SENSOR = 1088,
/**
* In Shoe Running/Walking Sensor.
*/
RUNNING_WALKING_SENSOR_IN_SHOE = 1089,
/**
* On Shoe Running/Walking Sensor.
*/
RUNNING_WALKING_SENSOR_ON_SHOE = 1090,
/**
* On Hip Running/Walking Sensor.
*/
RUNNING_WALKING_SENSOR_ON_HIP = 1091,
/**
* Generic Cycling.
*/
GENERIC_CYCLING = 1152,
/**
* Cycling Computer.
*/
CYCLING_CYCLING_COMPUTER = 1153,
/**
* Cycling Speed Sensor.
*/
CYCLING_SPEED_SENSOR = 1154,
/**
* Cycling Cadence Sensor.
*/
CYCLING_CADENCE_SENSOR = 1155,
/**
* Cycling Power Sensor.
*/
CYCLING_POWER_SENSOR = 1156,
/**
* Cycling Speed and Cadence Sensor.
*/
CYCLING_SPEED_AND_CADENCE_SENSOR = 1157,
/**
* Generic Pulse Oximeter.
*/
PULSE_OXIMETER_GENERIC = 3136,
/**
* Fingertip Pulse Oximeter.
*/
PULSE_OXIMETER_FINGERTIP = 3137,
/**
* Wrist Worn Pulse Oximeter.
*/
PULSE_OXIMETER_WRIST_WORN = 3138,
/**
* Generic Weight Scale.
*/
GENERIC_WEIGHT_SCALE = 3200,
/**
* Generic Outdoor.
*/
OUTDOOR_GENERIC = 5184,
/**
* Outdoor Location Display Device.
*/
OUTDOOR_LOCATION_DISPLAY_DEVICE = 5185,
/**
* Outdoor Location and Navigation Display Device.
*/
OUTDOOR_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE = 5186,
/**
* Outdoor Location Pod.
*/
OUTDOOR_LOCATION_POD = 5187,
/**
* Outdoor Location and Navigation Pod.
*/
OUTDOOR_LOCATION_AND_NAVIGATION_POD = 5188
};
/**
* Construct a new instance of adv_data_appearance_t.
*/
adv_data_appearance_t(type value) : SafeEnum(value)
{
}
};
/**
* @}
* @}
*/
} // namespace ble
#endif //BLE_GAP_ADVERTISINGDATATYPES_H

View File

@ -0,0 +1,541 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_ADVERTISING_PARAMETERS_H__
#define MBED_ADVERTISING_PARAMETERS_H__
#include <algorithm>
#include "BLETypes.h"
#include "BLEProtocol.h"
#include "blecommon.h"
#include "SafeEnum.h"
namespace ble {
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/**
* Parameters defining the advertising process.
*
* @par Legacy advertising:
*
* Advertising parameters for legacy advertising are a mainly defined by a pair
* of values:
* - The Advertising mode modeled after advertising_type_t. It defines
* whether the device is connectable and scannable. You can set this value at
* construction time, update it with setType() and query it with getType().
* - Time interval between advertisement. You can set it at construction time,
* update it with setPrimaryInterval() and obtain it from getMinPrimaryInterval()
* and getMaxPrimaryInterval().
*
* In addition, it is possible to adjust other parameters:
* - You can select the advertising channels with setPrimaryChannels() and
* queried them with getChannel37(), getChannel38() and getChannel39().
* - You can set the address type used by the local device with setOwnAddressType()
* and query it by getOwnAddressType().
* - You can set the filter policy for scan and connection requests with
* setFilter() and query it with getFilter().
*
* For directed advertising, you can set the address of the target with the help
* of setPeer() and query it with getPeerAddress() and getPeerAddressType().
*
* @par Extended advertising:
*
* To use extended advertising features, first disable legacy advertising
* with setUseLegacyPDU().
*
* Extended advertising adds new features to BLE advertising:
* - Control the advertising power with setTxPower().
* - Include the Tx power in advertising packet with includeTxPowerInHeader().
* - Set a secondary phy_t channel with setPhy().
* - Enable scan requests notification to let the application be aware of any
* incoming scan requests with setScanRequestNotification().
* - Advertise anonymously with setAnonymousAdvertising()
*
* @par Fluent interface:
*
* This API is designed for usability. You can construct
* it and pass it in place. To achieve this, the fluent interface pattern
* is used. Every setter returns a reference to the object modified and can be
* chained.
*
* @code
void setAdvertisingParameters(ble::Gap& gap) {
using namespace ble;
gap.setAdvertisingParameters(
LEGACY_ADVERTISING_HANDLE,
AdvertisingParameters()
.setType(advertising_type_t::ADV_CONNECTABLE_UNDIRECTED)
.setPrimaryInterval(millisecond_t(200), millisecond_t(500))
.setOwnAddressType(own_address_type_t::RANDOM)
.setUseLegacyPDU(false)
.setPhy(phy_t::LE_1M, phy_t::LE_CODED)
);
}
* @endcode
*
* @see ble::Gap::createAdvertisingSet(), ble::Gap::setAdvertisingParameters()
*/
class AdvertisingParameters {
/**
* Default minimum advertising interval.
*/
static const uint32_t DEFAULT_ADVERTISING_INTERVAL_MIN = 0x400;
/**
* Default maximum advertising interval.
*/
static const uint32_t DEFAULT_ADVERTISING_INTERVAL_MAX = 0x800;
/**
* Minimum Advertising interval for scannable and nonconnectable
* undirected events in 625us units.
*
* @note Equal to 100ms.
*/
static const uint32_t GAP_ADV_PARAMS_INTERVAL_MIN_NONCON = 0x00A0;
public:
/**
* Construct an instance of GapAdvertisingParams.
*
* @param[in] advType Type of advertising.
* @param[in] minInterval, maxInterval Time interval between two advertisement.
* A range is provided to the LE subsystem, so it can adjust the advertising
* interval with other transmission happening on the BLE radio.
*
* @note If values in input are out of range, they will be normalized.
*/
AdvertisingParameters(
advertising_type_t advType = advertising_type_t::CONNECTABLE_UNDIRECTED,
adv_interval_t minInterval = adv_interval_t(DEFAULT_ADVERTISING_INTERVAL_MIN),
adv_interval_t maxInterval = adv_interval_t(DEFAULT_ADVERTISING_INTERVAL_MAX)
) :
_advType(advType),
_minInterval(minInterval),
_maxInterval(maxInterval),
_peerAddressType(target_peer_address_type_t::PUBLIC),
_ownAddressType(own_address_type_t::PUBLIC),
_policy(advertising_filter_policy_t::NO_FILTER),
_primaryPhy(phy_t::LE_1M),
_secondaryPhy(phy_t::LE_1M),
_peerAddress(),
_txPower(127),
_maxSkip(0),
_channel37(true),
_channel38(true),
_channel39(true),
_anonymous(false),
_notifyOnScan(false),
_legacyPDU(true),
_includeHeaderTxPower(false)
{
/* Min interval is slightly larger than in other modes. */
if (_advType == advertising_type_t::NON_CONNECTABLE_UNDIRECTED) {
_minInterval = adv_interval_t(std::max(_minInterval.value(), GAP_ADV_PARAMS_INTERVAL_MIN_NONCON));
_maxInterval = adv_interval_t(std::max(_maxInterval.value(), GAP_ADV_PARAMS_INTERVAL_MIN_NONCON));
}
}
public:
/**
* Update the advertising type.
*
* @param[in] newAdvType The new advertising type.
*
* @return reference to this object.
*/
AdvertisingParameters &setType(advertising_type_t newAdvType)
{
_advType = newAdvType;
return *this;
}
/**
* Return the advertising type.
*
* @return Advertising type.
*/
advertising_type_t getType() const
{
return _advType;
}
/** Set the advertising intervals on the primary channels.
*
* @param[in] min, max Time interval between two advertisements.
* A range is provided to the LE subsystem, so it can adjust the advertising
* interval with other transmission happening on the BLE radio.
*
* @return reference to this object.
*/
AdvertisingParameters &setPrimaryInterval(
adv_interval_t min, adv_interval_t max
)
{
_minInterval = min;
_maxInterval = max;
return *this;
}
/** Get the minimum advertising intervals on the primary channels.
*
* @return The lower bound of the primary interval selected.
*/
adv_interval_t getMinPrimaryInterval() const
{
return _minInterval;
}
/** Get the maximum advertising intervals on the primary channels.
*
* @return The higher bound of the primary interval selected.
*/
adv_interval_t getMaxPrimaryInterval() const
{
return _maxInterval;
}
/** Set which channels are to be used for primary advertising.
* At least must be used. If all are set to disabled, all channels will be used.
*
* @param channel37 Use channel 37.
* @param channel38 Use channel 38.
* @param channel39 Use channel 39.
*
* @return a reference to this object.
*/
AdvertisingParameters &setPrimaryChannels(
bool channel37, bool channel38, bool channel39
)
{
if (!channel37 && !channel38 && !channel39) {
channel37 = channel38 = channel39 = true;
}
_channel37 = channel37;
_channel38 = channel38;
_channel39 = channel39;
return *this;
}
/** Check if channel 37 is used for primary advertising.
*
* @return True if channel used.
*/
bool getChannel37() const
{
return _channel37;
}
/** Check if channel 38 is used for primary advertising.
*
* @return True if channel used.
*/
bool getChannel38() const
{
return _channel38;
}
/** Check if channel 39 is used for primary advertising.
*
* @return True if channel used.
*/
bool getChannel39() const
{
return _channel39;
}
/** Get what type of address is to be used as your own address during advertising.
*
* @return a reference to this object.
*/
AdvertisingParameters &setOwnAddressType(own_address_type_t addressType)
{
_ownAddressType = addressType;
return *this;
}
/** Get what type of address is to be used as your own address during advertising.
*
* @return Addres tpe used.
*/
own_address_type_t getOwnAddressType() const
{
return _ownAddressType;
}
/** Set peer address and type used during directed advertising.
*
* @param address Peer's address bytes.
* @param addressType Peer's address type.
*
* @return a reference to this object.
*/
AdvertisingParameters &setPeer(
const address_t &address,
target_peer_address_type_t addressType
)
{
_peerAddress = address;
_peerAddressType = addressType;
return *this;
};
/** Get the peer address used during directed advertising.
*
* @return Address of the peer targeted by directed advertising.
*/
const address_t &getPeerAddress() const
{
return _peerAddress;
};
/** Get the peer address type used during directed advertising.
*
* @return The type of address of the peer targeted by directed advertising.
*/
target_peer_address_type_t getPeerAddressType() const
{
return _peerAddressType;
};
/** Set the filter policy of whitelist use during advertising;
*
* @param mode Policy to use.
*
* @return A reference to this object.
*/
AdvertisingParameters &setFilter(advertising_filter_policy_t mode)
{
_policy = mode;
return *this;
}
/** Get the filter policy of whitelist use during advertising;
*
* @return Policy used.
*/
advertising_filter_policy_t getFilter() const
{
return _policy;
}
/* Extended advertising parameters */
/** Get PHYs used on primary and secondary advertising channels.
*
* @param primaryPhy Primary advertising channels PHY.
* @param secondaryPhy Secondary advertising channels PHY.
*
* @return A reference to this.
*/
AdvertisingParameters &setPhy(phy_t primaryPhy, phy_t secondaryPhy)
{
_primaryPhy = primaryPhy;
_secondaryPhy = secondaryPhy;
return *this;
}
/** Get PHY used for primary advertising.
*
* @return PHY used for primary advertising.
*/
phy_t getPrimaryPhy() const
{
return _primaryPhy;
}
/** Get PHY used for secondary advertising.
*
* @return PHY used for secondary advertising.
*/
phy_t getSecondaryPhy() const
{
return _secondaryPhy;
}
/** Set the advertising TX power.
*
* @param txPower Advertising TX power.
*
* @return A reference to this object.
*/
AdvertisingParameters &setTxPower(advertising_power_t txPower)
{
_txPower = txPower;
return *this;
}
/** Get the advertising TX power.
*
* @return Advertising TX power.
*/
advertising_power_t getTxPower() const
{
return _txPower;
}
/** Set how many events can be skipped on the secondary channel.
*
* @param eventNumber Number of events that can be skipped.
*
* @return A reference to this object.
*/
AdvertisingParameters &setSecondaryMaxSkip(uint8_t eventNumber)
{
_maxSkip = eventNumber;
return *this;
}
/** Return how many events can be skipped on the secondary channel.
*
* @return How many events can be skipped on the secondary channel.
*/
uint8_t getSecondaryMaxSkip() const
{
return _maxSkip;
}
/** Enabled or disable the callback that notifies the user about a scan request.
*
* @param enable Enable callback if true.
*
* @return A reference to this object.
*
* @see ::ble::Gap::EventHandler::onScanRequestReceived()
*/
AdvertisingParameters &setScanRequestNotification(bool enable = true)
{
_notifyOnScan = enable;
return *this;
}
/** Return of the callback for scan request is enabled.
*
* @return True if callback is enabled.
*/
bool getScanRequestNotification() const
{
return _notifyOnScan;
}
/** Use legacy PDU during advertising.
*
* @param enable If true, legacy PDU will be used.
*
* @return A reference to this object.
*/
AdvertisingParameters &setUseLegacyPDU(bool enable = true)
{
_legacyPDU = enable;
return *this;
}
/** Check if legacy PDU is used during advertising.
*
* @return True legacy PDU will be used.
*/
bool getUseLegacyPDU() const
{
return _legacyPDU;
}
/** Set if TX power should be included in the header.
*
* @param enable If true, include the TX power in the header.
*
* @return A reference to this object.
*/
AdvertisingParameters &includeTxPowerInHeader(bool enable = true)
{
_includeHeaderTxPower = enable;
return *this;
}
/** Check if TX power should be included in the header.
*
* @return True if TX power is included in the header.
*/
bool getTxPowerInHeader() const
{
return _includeHeaderTxPower;
}
/** Advertise without your own address.
*
* @param enable Advertising anonymous if true.
*
* @return reference to this object.
*/
AdvertisingParameters &setAnonymousAdvertising(bool enable)
{
_anonymous = enable;
return *this;
}
/** Check if advertising is anonymous.
*
* @return True if advertising is anonymous.
*/
bool getAnonymousAdvertising() const
{
return _anonymous;
}
private:
advertising_type_t _advType;
/* The advertising interval in ADV duration units (in other words, 0.625ms). */
adv_interval_t _minInterval;
/* The advertising max interval in ADV duration units (in other words, 0.625ms) used in extended advertising. */
adv_interval_t _maxInterval;
target_peer_address_type_t _peerAddressType;
own_address_type_t _ownAddressType;
advertising_filter_policy_t _policy;
phy_t _primaryPhy;
phy_t _secondaryPhy;
address_t _peerAddress;
advertising_power_t _txPower;
uint8_t _maxSkip;
bool _channel37:1;
bool _channel38:1;
bool _channel39:1;
bool _anonymous:1;
bool _notifyOnScan:1;
bool _legacyPDU:1;
bool _includeHeaderTxPower:1;
};
/**
* @}
* @}
*/
} // namespace ble
#endif /* ifndef MBED_ADVERTISING_PARAMETERS_H__ */

View File

@ -0,0 +1,459 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_EXTENDED_CONNECT_PARAMETERS_H__
#define MBED_EXTENDED_CONNECT_PARAMETERS_H__
#include "ble/BLETypes.h"
#include "mbed_assert.h"
namespace ble {
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/**
* Parameters defining the connection initiation process.
*
* The connection initiation process is divided in two different phases. First,
* the initiating device scans for the peer to which it should connect. Once it finds
* the peer, it sends a connection request that contains the connection
* parameters.
*
* @par Scan parameters
*
* The scan parameters are defined by two durations: the scan interval and the
* scan window. The scan interval is the duration between two scan cycles, and the
* scan window defines how long the device searches during a scan cycle.
*
* You can set the scan window and the scan interval at construction time or by
* calling setScanParameters().
*
* @par Connection parameters
*
* A Bluetooth connection is defined by three parameters:
* - Connection interval: The time between two connection events. A minimum
* and a maximum connection interval are requested to help the Bluetooth
* subsystem deal with concurrent radio processing.
* - Slave latency: Number of connection events that can be ignored by the
* slave.
* - Supervision timeout: Time after which the connection is considered lost
* if the connected devices haven't exchanged a single packet. It is important
* to note that even if the application doesn't send actual data, the Bluetooth
* controller takes care of sending empty data packets to maintain the
* connection.
*
* You can set these parameters at construction time or by calling the function
* setConnectionParameters().
*
* @par PHY
*
* Bluetooth 5 has introduced the support of different physical layer to either
* increase the range or the throughput. You can configure multiple PHY
* independently for scanning and connecting.
*
* Legacy connection happens on the 1M PHY (phy_t::LE_1M). It is the only PHY
* that you can configure on legacy systems.
*
* The constructor, setScanParameters() and setConnectionParameters() accept
* a phy_t parameter that defines to which PHY the parameters set applies.
*
* @par Other parameters:
*
* It is possible to define what type of address is used to establish the
* connection and whether the whitelist should be used to find the peer
* to connect to.
*
* @par Example:
*
* Thanks to the fluent API, you can compose the connection parameters at
* instantiation point:
*
* @code
*
void do_connect(ble::Gap& gap, ble::target_peer_address_type_t addr_type, ble::address_t& address)
{
using namespace ble;
gap.connect(
addr_type,
address,
ConnectionParameters()
.setScanParameters(
phy_t::LE_1M,
scan_interval_t(millisecond_t(500)),
scan_window_t(millisecond_t(250))
)
.setConnectionParameters(
phy_t::LE_1M,
conn_interval_t(millisecond_t(100)),
conn_interval_t(millisecond_t(200)),
slave_latency_t(0),
supervision_timeout_t(millisecond_t(1000))
)
.setOwnAddressType(own_address_type_t::RANDOM)
);
}
*
* @endcode
*
* @note It is not possible to configure phy_t::LE_2M for scanning.
*
* @see ble::Gap::connect()
*/
class ConnectionParameters {
enum {
LE_1M_INDEX = 0,
LE_2M_INDEX = 1,
LE_CODED_INDEX = 2,
MAX_PARAM_PHYS = 3
};
public:
/**
* Create a ConnectionParameters object.
*
* @param phy The PHY being configured.
* @param scanInterval Interval between two scans.
* @param scanWindow Scan duration during a scan interval.
* @param minConnectionInterval Minimum value of the connection interval.
* @param maxConnectionInterval Maximum value of the connection interval.
* @param slaveLatency Maximum number of packets the slave can drop.
* @param connectionSupervisionTimeout Time after which the connection is
* considered lost if no data has been exchanged.
* @param minEventLength Minimum duration of a connection event.
* @param maxEventLength Maximum duration of a connection event.
*/
ConnectionParameters(
phy_t phy = phy_t::LE_1M,
scan_interval_t scanInterval = scan_interval_t::min(),
scan_window_t scanWindow = scan_window_t::min(),
conn_interval_t minConnectionInterval = conn_interval_t::min(),
conn_interval_t maxConnectionInterval = conn_interval_t::max(),
slave_latency_t slaveLatency = slave_latency_t::min(),
supervision_timeout_t connectionSupervisionTimeout = supervision_timeout_t::max(),
conn_event_length_t minEventLength = conn_event_length_t::min(),
conn_event_length_t maxEventLength = conn_event_length_t::max()
);
/* setters */
/**
* Set the scan parameters for a given PHY.
*
* @param phy PHY being configured.
* @param scanInterval Interval between two scans.
* @param scanWindow Scan duration within a scan interval.
*
* @note It is useless to configure the 2M PHY because it is not used during
* scanning.
*
* @return A reference to this.
*/
ConnectionParameters &setScanParameters(
phy_t phy,
scan_interval_t scanInterval,
scan_window_t scanWindow
);
/**
* Set the conenction parameters of a given PHY.
*
* @param phy The PHY being configured.
* @param minConnectionInterval Minimum connection interval.
* @param maxConnectionInterval Maximum connection interval.
* @param slaveLatency Maximum number of packets the slave can drop.
* @param connectionSupervisionTimeout Time after which the connection is
* considered lost if no data has been exchanged.
* @param minEventLength Minimum duration of a connection event.
* @param maxEventLength Maximum duration of a connection event.
*
* @return A reference to this.
*/
ConnectionParameters &setConnectionParameters(
phy_t phy,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t connectionSupervisionTimeout,
conn_event_length_t minEventLength = conn_event_length_t::min(),
conn_event_length_t maxEventLength = conn_event_length_t::max()
);
/**
* Address type used by the local device to connect the peer.
* @param ownAddress Type of address used to initiate the connection.
* @return A reference to this.
*/
ConnectionParameters &setOwnAddressType(own_address_type_t ownAddress)
{
_ownAddressType = ownAddress;
return *this;
}
/**
* Set if the whitelist should be used to find the peer.
*
* @param filterPolicy The initiator filter to apply.
*
* @return A reference to this.
*/
ConnectionParameters &setFilterPolicy(initiator_filter_policy_t filterPolicy)
{
_filterPolicy = filterPolicy;
return *this;
}
/**
* Enable or disable PHYs.
*
* @param phy1M true to enable the 1M PHY and false to disable it.
* @param phy2M true to enable the 2M PHY and false to disable it.
* @param phyCoded true to enable the CODED PHY and false to disable it.
*
* @return A reference to this.
*/
ConnectionParameters &togglePhy(bool phy1M, bool phy2M, bool phyCoded)
{
handlePhyToggle(phy_t::LE_1M, phy1M);
handlePhyToggle(phy_t::LE_2M, phy2M);
handlePhyToggle(phy_t::LE_CODED, phyCoded);
return *this;
}
/**
* Disable an individual PHY.
*
* @param phy The PHY to disable.
*
* @return A reference to this.
*/
ConnectionParameters &disablePhy(phy_t phy = phy_t::LE_1M)
{
handlePhyToggle(phy, false);
return *this;
}
/**
* Enable an individual PHY.
*
* @param phy The PHY to enable.
*
* @return A reference to this.
*/
ConnectionParameters &enablePhy(phy_t phy = phy_t::LE_1M)
{
handlePhyToggle(phy, true);
return *this;
}
/* getters */
/**
* Return the local address type used.
*
* @return The local address type to use.
*/
own_address_type_t getOwnAddressType() const
{
return _ownAddressType;
}
/**
* Return the initiator policy.
*
* @return The initiator policy.
*/
initiator_filter_policy_t getFilterPolicy() const
{
return _filterPolicy;
}
/**
* Return the number of PHY enabled.
* @return The number of PHY enabled.
*/
uint8_t getNumberOfEnabledPhys() const
{
return (
_enabledPhy[LE_1M_INDEX] * 1 +
_enabledPhy[LE_2M_INDEX] * 1 +
_enabledPhy[LE_CODED_INDEX] * 1
);
}
#if !defined(DOXYGEN_ONLY)
phy_set_t getPhySet() const
{
phy_set_t set(
_enabledPhy[LE_1M_INDEX],
_enabledPhy[LE_2M_INDEX],
_enabledPhy[LE_CODED_INDEX]
);
return set;
}
/* These return pointers to arrays of settings valid only across the number of active PHYs */
const uint16_t *getScanIntervalArray() const
{
return &_scanInterval[getFirstEnabledIndex()];
}
const uint16_t *getScanWindowArray() const
{
return &_scanWindow[getFirstEnabledIndex()];
}
const uint16_t *getMinConnectionIntervalArray() const
{
return &_minConnectionInterval[getFirstEnabledIndex()];
}
const uint16_t *getMaxConnectionIntervalArray() const
{
return &_maxConnectionInterval[getFirstEnabledIndex()];
}
const uint16_t *getSlaveLatencyArray() const
{
return &_slaveLatency[getFirstEnabledIndex()];
}
const uint16_t *getConnectionSupervisionTimeoutArray() const
{
return &_connectionSupervisionTimeout[getFirstEnabledIndex()];
}
const uint16_t *getMinEventLengthArray() const
{
return &_minEventLength[getFirstEnabledIndex()];
}
const uint16_t *getMaxEventLengthArray() const
{
return &_maxEventLength[getFirstEnabledIndex()];
}
#endif
private:
uint8_t getFirstEnabledIndex() const
{
if (_enabledPhy[LE_1M_INDEX]) {
return LE_1M_INDEX;
} else if (_enabledPhy[LE_2M_INDEX]) {
return LE_2M_INDEX;
} else if (_enabledPhy[LE_CODED_INDEX]) {
return LE_CODED_INDEX;
}
/* This should never happen; it means you were trying to start a connection with a blank set
* of parameters - you need to enable at least one PHY */
MBED_ASSERT("Trying to use connection parameters without any PHY defined.");
return 0;
}
/** Handle toggling PHYs on and off and return the correct index to use to set the configuration elements.
*
* @param phy Which PHY is being toggled.
* @param enable On or Off.
* @return The index to the array of settings.
*/
uint8_t handlePhyToggle(phy_t phy, bool enable)
{
uint8_t index = phyToIndex(phy);
bool was_swapped = isSwapped();
_enabledPhy[index] = enable;
bool is_swapped = isSwapped();
if (was_swapped != is_swapped) {
swapCodedAnd2M();
}
if (is_swapped && index == LE_CODED_INDEX) {
/* To keep the data contiguous, coded params are in place of the missing 2M params */
index = LE_2M_INDEX;
}
return index;
}
uint8_t phyToIndex(phy_t phy) const
{
uint8_t index;
switch (phy.value()) {
case phy_t::LE_1M:
index = LE_1M_INDEX;
break;
case phy_t::LE_2M:
index = LE_2M_INDEX;
break;
case phy_t::LE_CODED:
index = LE_CODED_INDEX;
break;
default:
index = MAX_PARAM_PHYS;
MBED_ASSERT("Illegal PHY");
break;
}
return index;
}
bool isSwapped() const
{
return (
_enabledPhy[LE_1M_INDEX] &&
!_enabledPhy[LE_2M_INDEX] &&
_enabledPhy[LE_CODED_INDEX]
);
}
/** Handle the swapping of 2M and CODED so that the array is ready for the pal call. */
void swapCodedAnd2M();
private:
initiator_filter_policy_t _filterPolicy;
own_address_type_t _ownAddressType;
uint16_t _scanInterval[MAX_PARAM_PHYS]; /* 0.625 ms */
uint16_t _scanWindow[MAX_PARAM_PHYS]; /* 0.625 ms */
uint16_t _minConnectionInterval[MAX_PARAM_PHYS]; /* 1.25 ms */
uint16_t _maxConnectionInterval[MAX_PARAM_PHYS]; /* 1.25 ms */
uint16_t _slaveLatency[MAX_PARAM_PHYS]; /* events */
uint16_t _connectionSupervisionTimeout[MAX_PARAM_PHYS]; /* 10 ms */
uint16_t _minEventLength[MAX_PARAM_PHYS]; /* 0.625 ms */
uint16_t _maxEventLength[MAX_PARAM_PHYS]; /* 0.625 ms */
bool _enabledPhy[MAX_PARAM_PHYS];
};
/**
* @}
* @}
*/
} // namespace ble
#endif /* ifndef MBED_EXTENDED_CONNECT_PARAMETERS_H__ */

View File

@ -0,0 +1,822 @@
/* mbed Microcontroller Library
* Copyright (c) 2018-2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_GAP_EVENTS_H
#define BLE_GAP_EVENTS_H
#include "ble/blecommon.h"
#include "ble/BLETypes.h"
#include "platform/Span.h"
namespace ble {
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/**
* Event generated when an advertising packet is seen during passive scanning
* or a scan response is received during active scanning.
*
* @see ble::Gap::EventHandler::onPeriodicAdvertisingReport()
*/
struct AdvertisingReportEvent {
#if !defined(DOXYGEN_ONLY)
/** Create an advertising report event.
*
* @param type Type of advertising used.
* @param peerAddressType Peer address type of advertiser.
* @param peerAddress Peer address of advertiser.
* @param primaryPhy PHY used on the primary channels.
* @param secondaryPhy PHY used on secondary channels.
* @param SID Set identification number.
* @param txPower Transmission power reported by the packet.
* @param rssi Measured signal strength.
* @param periodicInterval Interval of periodic advertising.
* @param directAddressType Directed advertising target address type.
* @param directAddress Directed advertising target address.
* @param advertisingData Advertising payload.
*/
AdvertisingReportEvent(
const advertising_event_t &type,
const peer_address_type_t &peerAddressType,
const address_t &peerAddress,
const phy_t &primaryPhy,
const phy_t &secondaryPhy,
advertising_sid_t SID,
advertising_power_t txPower,
rssi_t rssi,
periodic_interval_t periodicInterval,
const peer_address_type_t &directAddressType,
const address_t &directAddress,
const mbed::Span<const uint8_t> &advertisingData
) :
type(type),
peerAddressType(peerAddressType),
peerAddress(peerAddress),
primaryPhy(primaryPhy),
secondaryPhy(secondaryPhy),
SID(SID),
txPower(txPower),
rssi(rssi),
periodicInterval(periodicInterval),
directAddressType(directAddressType),
directAddress(directAddress),
advertisingData(advertisingData)
{
}
#endif
/** Get event type. */
const advertising_event_t &getType() const
{
return type;
}
/** Get peer address type. */
const peer_address_type_t &getPeerAddressType() const
{
return peerAddressType;
}
/** Get peer address. */
const address_t &getPeerAddress() const
{
return peerAddress;
}
/** Get primary PHY. */
const phy_t &getPrimaryPhy() const
{
return primaryPhy;
}
/** Get secondary PHY. */
const phy_t &getSecondaryPhy() const
{
return secondaryPhy;
}
/** Get advertising set identifier. */
advertising_sid_t getSID() const
{
return SID;
}
/** Get TX power. */
advertising_power_t getTxPower() const
{
return txPower;
}
/** Get received signal strength. */
rssi_t getRssi() const
{
return rssi;
}
/** Get interval. */
periodic_interval_t getPeriodicInterval() const
{
return periodicInterval;
}
/** Get target address type in directed advertising. */
const peer_address_type_t &getDirectAddressType() const
{
return directAddressType;
}
/** Get target address in directed advertising. */
const address_t &getDirectAddress() const
{
return directAddress;
}
/** Get payload. */
const mbed::Span<const uint8_t> &getAdvertisingData() const
{
return advertisingData;
}
private:
advertising_event_t type;
peer_address_type_t peerAddressType;
address_t const &peerAddress;
phy_t primaryPhy;
phy_t secondaryPhy;
advertising_sid_t SID;
advertising_power_t txPower;
rssi_t rssi;
periodic_interval_t periodicInterval;
peer_address_type_t directAddressType;
const address_t &directAddress;
mbed::Span<const uint8_t> advertisingData;
};
/**
* Event generated when a connection initiation ends (successfully or not).
*
* @see ble::Gap::EventHandler::onConnectionComplete().
*/
struct ConnectionCompleteEvent {
#if !defined(DOXYGEN_ONLY)
/** Create a connection complete event.
*
* @param success BLE_ERROR_NONE if connection succeeded.
* @param connectionHandle Connection handle if successful.
* @param ownRole Role of the local device.
* @param peerAddressType Peer address type.
* @param peerAddress Peer address.
* @param localResolvablePrivateAddress Local address type if privacy enabled.
* @param peerResolvablePrivateAddress Peer address type if privacy enabled.
* @param connectionInterval Connection interval.
* @param connectionLatency Connection latency in events.
* @param supervisionTimeout Supervision timeout.
* @param masterClockAccuracy Peer clock accuracy in parts per million.
*/
ConnectionCompleteEvent(
ble_error_t status,
connection_handle_t connectionHandle,
connection_role_t ownRole,
const peer_address_type_t &peerAddressType,
const address_t &peerAddress,
const address_t &localResolvablePrivateAddress,
const address_t &peerResolvablePrivateAddress,
conn_interval_t connectionInterval,
slave_latency_t connectionLatency,
supervision_timeout_t supervisionTimeout,
uint16_t masterClockAccuracy
) :
status(status),
connectionHandle(connectionHandle),
ownRole(ownRole),
peerAddressType(peerAddressType),
peerAddress(peerAddress),
localResolvablePrivateAddress(localResolvablePrivateAddress),
peerResolvablePrivateAddress(peerResolvablePrivateAddress),
connectionInterval(connectionInterval),
connectionLatency(connectionLatency),
supervisionTimeout(supervisionTimeout),
masterClockAccuracy(masterClockAccuracy)
{
}
#endif
/** Get connection complete event status. */
ble_error_t getStatus() const
{
return status;
}
/** Get connection handle (valid only when successful). */
connection_handle_t getConnectionHandle() const
{
return connectionHandle;
}
/** Get own role. */
connection_role_t getOwnRole() const
{
return ownRole;
}
/** Get peer address type. */
const peer_address_type_t &getPeerAddressType() const
{
return peerAddressType;
}
/** Get peer address. */
const address_t &getPeerAddress() const
{
return peerAddress;
}
/** Get get local resolvable random address if privacy is used. */
const address_t &getLocalResolvablePrivateAddress() const
{
return localResolvablePrivateAddress;
}
/** Get peer resolvable private address if privacy is used. */
const address_t &getPeerResolvablePrivateAddress() const
{
return peerResolvablePrivateAddress;
}
/** Get connection interval. */
conn_interval_t getConnectionInterval() const
{
return connectionInterval;
}
/** Get connection latency. */
slave_latency_t getConnectionLatency() const
{
return connectionLatency;
}
/** Get supervision timeout. */
supervision_timeout_t getSupervisionTimeout() const
{
return supervisionTimeout;
}
/** Get clock accuracy in parts per million. */
uint16_t getMasterClockAccuracy() const
{
return masterClockAccuracy;
}
private:
ble_error_t status;
connection_handle_t connectionHandle;
connection_role_t ownRole;
peer_address_type_t peerAddressType;
const address_t &peerAddress;
const address_t &localResolvablePrivateAddress;
const address_t &peerResolvablePrivateAddress;
conn_interval_t connectionInterval;
slave_latency_t connectionLatency;
supervision_timeout_t supervisionTimeout;
uint16_t masterClockAccuracy;
};
/**
* Event generated when you first receive a periodic advertisement.
*
* @see ble::Gap::EventHandler::onPeriodicAdvertisingSyncEstablished().
*/
struct PeriodicAdvertisingSyncEstablishedEvent {
#if !defined(DOXYGEN_ONLY)
/** Create advertising sync event.
*
* @param success BLE_ERROR_NONE if synchronisation was achieved.
* @param syncHandle Advertising sync handle.
* @param sid Advertising set identifier.
* @param peerAddressType Peer address type.
* @param peerAddress Peer address.
* @param peerPhy PHY used for advertisements.
* @param advertisingInterval Periodic advertising interval.
* @param masterClockAccuracy Peer clock accuracy in parts per million.
*/
PeriodicAdvertisingSyncEstablishedEvent(
ble_error_t status,
periodic_sync_handle_t syncHandle,
advertising_sid_t sid,
const peer_address_type_t &peerAddressType,
const address_t &peerAddress,
const phy_t &peerPhy,
uint16_t advertisingInterval,
const clock_accuracy_t &peerClockAccuracy
) :
status(status),
syncHandle(syncHandle),
sid(sid),
peerAddressType(peerAddressType),
peerAddress(peerAddress),
peerPhy(peerPhy),
advertisingInterval(advertisingInterval),
peerClockAccuracy(peerClockAccuracy)
{
}
#endif
/** Get sync establishment status. */
ble_error_t getStatus() const
{
return status;
}
/** Get periodic advertising sync handle. */
periodic_sync_handle_t getSyncHandle() const
{
return syncHandle;
}
/** Get advertising set identifier. */
advertising_sid_t getSid() const
{
return sid;
}
/** Get peer address type. */
const peer_address_type_t &getPeerAddressType() const
{
return peerAddressType;
}
/** Get peer address. */
const address_t &getPeerAddress() const
{
return peerAddress;
}
/** Get PHY used. */
const phy_t &getPeerPhy() const
{
return peerPhy;
}
/** Get interval. */
uint16_t getAdvertisingInterval() const
{
return advertisingInterval;
}
/** Get clock accuracy in parts per million. */
const clock_accuracy_t &getPeerClockAccuracy() const
{
return peerClockAccuracy;
}
private:
ble_error_t status;
periodic_sync_handle_t syncHandle;
advertising_sid_t sid;
peer_address_type_t peerAddressType;
const address_t &peerAddress;
phy_t peerPhy;
uint16_t advertisingInterval;
clock_accuracy_t peerClockAccuracy;
};
/**
* Event generated when periodic advertising packet is received.
*
* @see ble::Gap::EventHandler::onPeriodicAdvertisingReport().
*/
struct PeriodicAdvertisingReportEvent {
#if !defined(DOXYGEN_ONLY)
/** Create periodic advertising report event.
*
* @param syncHandle Periodic advertising sync handle
* @param txPower TX power.
* @param rssi Received signal strength.
* @param dataStatus Status to indicate the completeness of the payload.
* @param payload Periodic advertisement payload.
*/
PeriodicAdvertisingReportEvent(
periodic_sync_handle_t syncHandle,
advertising_power_t txPower,
rssi_t rssi,
advertising_data_status_t dataStatus,
const mbed::Span<const uint8_t> &payload
) :
syncHandle(syncHandle),
txPower(txPower),
rssi(rssi),
dataStatus(dataStatus),
payload(payload)
{
}
#endif
/** Get periodic advertising sync handle. */
periodic_sync_handle_t getSyncHandle() const
{
return syncHandle;
}
/** Get TX power as reported by the advertising packet. */
advertising_power_t getTxPower() const
{
return txPower;
}
/** Get received signal strength. */
rssi_t getRssi() const
{
return rssi;
}
/** Get data completeness status. */
const advertising_data_status_t &getDataStatus() const
{
return dataStatus;
}
/** Get payload. */
const mbed::Span<const uint8_t> &getPayload() const
{
return payload;
}
private:
periodic_sync_handle_t syncHandle;
advertising_power_t txPower;
rssi_t rssi;
advertising_data_status_t dataStatus;
mbed::Span<const uint8_t> payload;
};
/**
* Event generated when periodic advertising sync is lost.
*
* @see ble::Gap::EventHandler::onPeriodicAdvertisingSyncLoss().
*/
struct PeriodicAdvertisingSyncLoss {
#if !defined(DOXYGEN_ONLY)
/** Create periodic advertising sync loss event.
*
* @param syncHandle Periodic advertising sync handle.
*/
PeriodicAdvertisingSyncLoss(
periodic_sync_handle_t syncHandle
) :
syncHandle(syncHandle)
{
}
#endif
/** Get periodic sync handle. */
periodic_sync_handle_t getSyncHandle() const
{
return syncHandle;
}
private:
periodic_sync_handle_t syncHandle;
};
/**
* Event generated when scan times out.
*
* @see ble::Gap::EventHandler::onScanTimeout().
*/
struct ScanTimeoutEvent { };
/**
* Event produced when advertising ends.
*
* @see ble::Gap::EventHandler::onAdvertisingEnd().
*/
struct AdvertisingEndEvent {
#if !defined(DOXYGEN_ONLY)
/** Create advertising end event.
*
* @param advHandle Advertising set handle.
* @param connection Connection handle.
* @param completed_events Number of events created during before advertising end.
* @param connected True if connection has been established.
*/
AdvertisingEndEvent(
advertising_handle_t advHandle,
connection_handle_t connection,
uint8_t completed_events,
bool connected
) :
advHandle(advHandle),
connection(connection),
completed_events(completed_events),
connected(connected)
{
}
#endif
/** Get advertising handle. */
advertising_handle_t getAdvHandle() const
{
return advHandle;
}
/** Get connection handle (valid only if connected successfully). */
connection_handle_t getConnection() const
{
return connection;
}
/** Get how many events advertising created. */
uint8_t getCompleted_events() const
{
return completed_events;
}
/** Has the advertising ended with a connection. */
bool isConnected() const
{
return connected;
}
private:
advertising_handle_t advHandle;
connection_handle_t connection;
uint8_t completed_events;
bool connected;
};
/**
* Event produced when a peer requests a scan response from the advertiser.
*
* @see ble::Gap::EventHandler::onScanRequestReceived().
*/
struct ScanRequestEvent {
#if !defined(DOXYGEN_ONLY)
/** Create scan request event.
*
* @param advHandle Advertising handle.
* @param peerAddressType Peer address type.
* @param peerAddress Peer address.
*/
ScanRequestEvent(
advertising_handle_t advHandle,
const peer_address_type_t &peerAddressType,
const address_t &peerAddress
) :
advHandle(advHandle),
peerAddressType(peerAddressType),
peerAddress(peerAddress)
{
}
#endif
/** Get advertising handle. */
advertising_handle_t getAdvHandle() const
{
return advHandle;
}
/** Get peer address type. */
const peer_address_type_t &getPeerAddressType() const
{
return peerAddressType;
}
/** Get peer address. */
const address_t &getPeerAddress() const
{
return peerAddress;
}
private:
advertising_handle_t advHandle;
peer_address_type_t peerAddressType;
const address_t &peerAddress;
};
/**
* Event produced when a disconnection is complete.
*
* @see ble::Gap::EventHandler::onDisconnectionComplete().
*/
struct DisconnectionEvent {
#if !defined(DOXYGEN_ONLY)
DisconnectionEvent(
connection_handle_t connectionHandle,
const disconnection_reason_t &reason
) :
connectionHandle(connectionHandle), reason(reason)
{
}
#endif
/**
* Get the handle of the connection that has expired.
*/
connection_handle_t getConnectionHandle() const
{
return connectionHandle;
}
/**
* Get the reason of the disconnection.
*/
const disconnection_reason_t &getReason() const
{
return reason;
}
private:
ble::connection_handle_t connectionHandle;
ble::disconnection_reason_t reason;
};
/**
* Event received when a peer wants to change the connection parameters.
*
* @see ble::Gap::EventHandler::onUpdateConnectionParametersRequest().
*/
struct UpdateConnectionParametersRequestEvent {
#if !defined(DOXYGEN_ONLY)
UpdateConnectionParametersRequestEvent(
connection_handle_t connectionHandle,
const conn_interval_t &minConnectionInterval,
const conn_interval_t &maxConnectionInterval,
const slave_latency_t &slaveLatency,
const supervision_timeout_t &supervision_timeout
) :
connectionHandle(connectionHandle),
minConnectionInterval(minConnectionInterval),
maxConnectionInterval(maxConnectionInterval),
slaveLatency(slaveLatency),
supervisionTimeout(supervision_timeout)
{
}
#endif
/**
* Get the connection handle.
*/
connection_handle_t getConnectionHandle() const
{
return connectionHandle;
}
/**
* Get the minimum connection interval requested.
*/
const conn_interval_t &getMinConnectionInterval() const
{
return minConnectionInterval;
}
/**
* Get the maximum connection interval requested.
*/
const conn_interval_t &getMaxConnectionInterval() const
{
return maxConnectionInterval;
}
/**
* Get the slave latency requested.
*/
const slave_latency_t &getSlaveLatency() const
{
return slaveLatency;
}
/**
* Get the supervision timeout requested.
*/
const supervision_timeout_t &getSupervisionTimeout() const
{
return supervisionTimeout;
}
private:
ble::connection_handle_t connectionHandle;
ble::conn_interval_t minConnectionInterval;
ble::conn_interval_t maxConnectionInterval;
ble::slave_latency_t slaveLatency;
ble::supervision_timeout_t supervisionTimeout;
};
/**
* Event received when connection parameters have been updated.
*
* @see ble::Gap::EventHandler::onConnectionParametersUpdateComplete().
*/
struct ConnectionParametersUpdateCompleteEvent {
#if !defined(DOXYGEN_ONLY)
ConnectionParametersUpdateCompleteEvent(
ble_error_t status,
connection_handle_t connectionHandle,
const conn_interval_t &connectionInterval,
const slave_latency_t &slaveLatency,
const supervision_timeout_t &supervisionTimeout
) :
status(status),
connectionHandle(connectionHandle),
connectionInterval(connectionInterval),
slaveLatency(slaveLatency),
supervisionTimeout(supervisionTimeout)
{
}
#endif
/**
* Get the status of the operation. It is equal to BLE_ERROR_NONE in case of
* success.
*/
ble_error_t getStatus() const
{
return status;
}
/**
* Get the handle of the connection that has been updated.
*/
connection_handle_t getConnectionHandle() const
{
return connectionHandle;
}
/**
* Get the new connection interval.
*/
const conn_interval_t &getConnectionInterval() const
{
return connectionInterval;
}
/**
* Get the new slave latency.
*/
const slave_latency_t &getSlaveLatency() const
{
return slaveLatency;
}
/**
* Get the new supervision timeout.
*/
const supervision_timeout_t &getSupervisionTimeout() const
{
return supervisionTimeout;
}
private:
ble_error_t status;
ble::connection_handle_t connectionHandle;
ble::conn_interval_t connectionInterval;
ble::slave_latency_t slaveLatency;
ble::supervision_timeout_t supervisionTimeout;
};
/**
* @}
* @}
*/
} // namespace ble
#endif //BLE_GAP_EVENTS_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,273 @@
/* mbed Microcontroller Library
* Copyright (c) 2018-2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_GAP_SCAN_PARAMETERS_H__
#define MBED_GAP_SCAN_PARAMETERS_H__
#include <stdint.h>
#include "ble/blecommon.h"
#include "BLETypes.h"
namespace ble {
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/**
* Parameters defining the scan process.
*
* The scan process is defined by two main parameters:
* - The scan window that defines how long the device should scan.
* - The scan window that defines how frequently the device should scan.
*
* To scan continuously, the scan window and the scan interval should have the
* same value.
*
* To get extra data from the advertising device, the scanner can send scan
* requests to the advertiser that respond with a scan response. It is possible
* to select what type of address is used to issue the scan request.
*
* With Bluetooth 5, devices can advertise on more physical channels, and by
* extension, they can scan on more physical channels. It is possible to define
* independent scan parameters for every scannable physical channel.
*/
class ScanParameters {
public:
/**
* Scan configuration of a physical channel.
*/
struct phy_configuration_t {
/**
* Construct a phy_configuration_t.
* @param scan_interval The scan interval.
* @param scan_window The scan window.
* @param active_scanning True if scan request should be sent and false
* otherwise.
*/
phy_configuration_t(
scan_interval_t scan_interval = scan_interval_t::min(),
scan_window_t scan_window = scan_window_t::min(),
bool active_scanning = false
) :
interval(scan_interval),
window(scan_window),
active_scanning(active_scanning)
{
if (window.value() > interval.value()) {
interval = window;
}
}
/**
* Get the scan interval.
*/
const scan_window_t &getInterval() const
{
return interval;
}
/**
* Get the scan window.
*/
const scan_interval_t &getWindow() const
{
return window;
}
/**
* Return if active scanning is set.
*/
bool isActiveScanningSet() const
{
return active_scanning;
}
private:
scan_window_t interval;
scan_interval_t window;
bool active_scanning;
};
/**
* Construct a ScanParameters object that operates on a selected PHY.
*
* @param phy The phy to configure.
* @param scan_interval The scan interval.
* @param scan_window The scan window.
* @param active_scanning active scanning flag.
* @param own_address_type Address type used in scan requests.
* @param scanning_filter_policy Filter applied.
*/
ScanParameters(
phy_t phy = phy_t::LE_1M,
scan_window_t scan_interval = scan_interval_t::min(),
scan_interval_t scan_window = scan_window_t::min(),
bool active_scanning = false,
own_address_type_t own_address_type = own_address_type_t::PUBLIC,
scanning_filter_policy_t scanning_filter_policy = scanning_filter_policy_t::NO_FILTER
) :
own_address_type(own_address_type),
scanning_filter_policy(scanning_filter_policy),
phys(phy),
phy_1m_configuration(),
phy_coded_configuration()
{
phy_configuration_t conf(scan_interval, scan_window, active_scanning);
if (phy == phy_t::LE_1M) {
phy_1m_configuration = conf;
} else if (phy == phy_t::LE_CODED) {
phy_coded_configuration = conf;
}
}
/**
* Set the address type used for scan requests.
* @param address The type of address to use during scan requests.
* @return A reference to this object.
*/
ScanParameters &setOwnAddressType(own_address_type_t address)
{
own_address_type = address;
return *this;
}
/**
* Get the address type used during scan requests.
*/
own_address_type_t getOwnAddressType() const
{
return own_address_type;
}
/**
* Set the filter to apply during scanning.
* @param filter_policy The filter to apply during scanning.
* @return A reference to this object.
*/
ScanParameters &setFilter(scanning_filter_policy_t filter_policy)
{
scanning_filter_policy = filter_policy;
return *this;
}
/**
* Get the filter to use during scanning
*/
scanning_filter_policy_t getFilter() const
{
return scanning_filter_policy;
}
/**
* Enable or disable PHYs that should be used during scanning.
* @param enable_1m True to enable the 1M phy and false to disable it.
* @param enable_coded True to enable the coded phy and false to disable it.
* @return A reference to this object.
*/
ScanParameters &setPhys(bool enable_1m, bool enable_coded)
{
phys.set_1m(enable_1m);
phys.set_coded(enable_coded);
return *this;
}
/**
* Get the PHYs to use during scanning.
*/
phy_set_t getPhys() const
{
return phys;
}
/**
* Set the 1M scan configuration.
* @param interval The scan interval to use.
* @param window The scan window to use.
* @param active_scanning The active scanning flag.
* @return A reference to this object.
*/
ScanParameters &set1mPhyConfiguration(
scan_interval_t interval,
scan_window_t window,
bool active_scanning
)
{
phys.set_1m(true);
phy_1m_configuration = phy_configuration_t(
interval, window, active_scanning
);
return *this;
}
/**
* Get the 1M scan configuration.
*/
phy_configuration_t get1mPhyConfiguration() const
{
return phy_1m_configuration;
}
/**
* Set the coded PHY scan configuration.
* @param interval The scan interval to use.
* @param window The scan window to use.
* @param active_scanning The active scanning flag.
* @return A reference to this object.
*/
ScanParameters &setCodedPhyConfiguration(
scan_interval_t interval,
scan_window_t window,
bool active_scanning
)
{
phys.set_coded(true);
phy_coded_configuration = phy_configuration_t(
interval, window, active_scanning
);
return *this;
}
/**
* Get the coded PHY scan configuration.
*/
phy_configuration_t getCodedPhyConfiguration() const
{
return phy_1m_configuration;
}
private:
own_address_type_t own_address_type;
scanning_filter_policy_t scanning_filter_policy;
phy_set_t phys;
phy_configuration_t phy_1m_configuration;
phy_configuration_t phy_coded_configuration;
};
/**
* @}
* @}
*/
} // namespace ble
#endif /* ifndef MBED_GAP_SCAN_PARAMETERS_H__ */

View File

@ -0,0 +1,959 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_GAP_TYPES_H
#define BLE_GAP_TYPES_H
#include "ble/common/Duration.h"
#include "ble/common/Bounded.h"
#include "ble/SafeEnum.h"
namespace ble {
/**
* @addtogroup ble
* @{
* @addtogroup gap
* @{
*/
/* BLE units, using microseconds as the common denominator */
/**
* Time interval between two advertisements.
*
* The duration is in unit of 625µs and ranges from 0x20 to 0xFFFFFF .
*
* @note before Bluetooth 5 range was 0x20 to 0xFFFF.
*/
typedef Duration<uint32_t, 625, Range<0x20, 0xFFFFFF> > adv_interval_t;
/**
* Advertising process duration.
*
* The duration is in unit of 10ms and ranges from 0x0001 to 0xFFFF. The special
* value 0x0000 means the advertising process never ends; it is accessible with
* adv_duration_t::forever().
*/
typedef Duration<uint16_t, 10000, Range<0x00, 0xFFFF>, /* forever */ Value<uint16_t, 0x0000> > adv_duration_t;
/**
* Scan process duration.
*
* The duration is in unit of 10ms and ranges from 0x0001 to 0xFFFF. The special
* value 0x0000 means the scan process never ends; it is accessible with
* scan_duration_t::forever().
*/
typedef Duration<uint16_t, 10000, Range<0x00, 0xFFFF>, /* forever */ Value<uint16_t, 0x0000> > scan_duration_t;
/**
* Time interval between two scan processes.
*
* The duration is in unit of 1.28s and ranges from 0x0001 to 0xFFFF. The special
* value 0x0000 is used to indicate that scan_period_t is not used.
*/
typedef Duration<uint16_t, 1280000, Range<0x00, 0xFFFF> > scan_period_t;
/**
* Time interval between two scans.
*
* The duration is in unit of 625µs and ranges from 0x04 to 0xFFFF.
*/
typedef Duration<uint16_t, 625, Range<0x04, 0xFFFF> > scan_interval_t;
/**
* Duration of a scan.
*
* The duration is in unit of 625µs and ranges from 0x04 to 0xFFFF.
*/
typedef Duration<uint16_t, 625, Range<0x04, 0xFFFF> > scan_window_t;
/**
* Time interval between two connection events.
*
* The interval is in unit of 1.250 milliseconds and ranges from 0x06 to 0xC80.
*/
typedef Duration<uint16_t, 1250, Range<0x06, 0x0C80> > conn_interval_t;
/**
* Time after which a connection is loss of devices have not exchanged data.
*
* The duration is in unit of 10 milliseconds and ranges from 0x0A to 0xC80.
*
* @note this time should be no larger than (1 + ConnLatency) * ConnIntervalMax * 2
*/
typedef Duration<uint16_t, 10000, Range<0x0A, 0x0C80> > supervision_timeout_t;
/**
* Duration of a connection event.
*
* The duration is in unit of 625µs and ranges from 0x0 to 0xFFFF .
*/
typedef Duration<uint16_t, 625, Range<0, 0xFFFF> > conn_event_length_t;
/**
* Time after which a periodic sync link is considered lost if the receiver hasn't
* received anything from the advertiser.
*
* The duration is in unit of 10 milliseconds and ranges from 0x0A to 0x4000.
*/
typedef Duration<uint16_t, 10000, Range<0x0A, 0x4000> > sync_timeout_t;
/**
* Interval between two periodic advertising events.
*
* The duration is in unit of 1.250ms and ranges from 0x06 to 0xFFFF.
*/
typedef Duration<uint16_t, 1250, Range<0x06, 0xFFFF> > periodic_interval_t;
/**
* Number of connection events that can be skipped by the slave.
*
* It ranges from 0 to 0x1F3.
*/
typedef Bounded<uint16_t, 0, 0x01F3> slave_latency_t;
/**
* Handle of an advertising set.
*
* @note Range of valid handle is comprised between 0x00 and 0xEF.
*/
typedef uint8_t advertising_handle_t;
/**
* Handle of a sync representing a periodic advertiser.
*
* @note Range of valid handle is comprised between 0x0000 and 0xFFFF.
*/
typedef uint16_t periodic_sync_handle_t;
/**
* Encapsulates the peripheral advertising modes.
*
* It determines how the device appears to other scanner and peripheral
* devices in the scanning range.
*/
struct advertising_type_t : SafeEnum<advertising_type_t, uint8_t> {
/// enumeration of advertising_type_t values
enum type {
/**
* Device is connectable, scannable and doesn't expect connection from a
* specific peer.
*
* @see Vol 3, Part C, Section 9.3.4 and Vol 6, Part B, Section 2.3.1.1.
*/
CONNECTABLE_UNDIRECTED = 0x00,
/**
* Device is connectable and expects connection from a specific peer.
* (3.75 ms or smaller Advertising Interval)
* @see Vol 3, Part C, Section 9.3.3 and Vol 6, Part B, Section 2.3.1.2.
*/
CONNECTABLE_DIRECTED = 0x01,
/**
* Device is scannable but not connectable.
*
* @see Vol 6, Part B, Section 2.3.1.4.
*/
SCANNABLE_UNDIRECTED = 0x02,
/**
* Device is not connectable and not scannable.
*
* @see Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3.
*/
NON_CONNECTABLE_UNDIRECTED = 0x03,
/**
* Device is connectable and expects connection from a specific peer (sent at long user set intervals).
*/
CONNECTABLE_DIRECTED_LOW_DUTY = 0x04,
#if !defined(DOXYGEN_ONLY)
// used by the PAL; naming in line with the the spec.
ADV_IND = 0x00,
ADV_DIRECT_IND = 0x01,
ADV_SCAN_IND = 0x02,
ADV_NONCONN_IND = 0x03,
ADV_DIRECT_IND_LOW_DUTY_CYCLE = 0x04
#endif
};
/**
* Construct a new advertising_type_t value.
*
* @param value The value of the advertising_type_t created.
*/
advertising_type_t(type value) : SafeEnum(value)
{
}
};
/** Used to indicate if the packet is complete and if it's truncated.
*/
struct advertising_data_status_t : SafeEnum<advertising_data_status_t, uint8_t> {
/// enumeration of advertising_data_status_t values
enum type {
COMPLETE = 0x00, /// Advertising payload complete.
INCOMPLETE_MORE_DATA = 0x01, /// Partial advertising payload, more to come.
INCOMPLETE_DATA_TRUNCATED = 0x02 /// Advertising payload incomplete, and no more is coming.
};
/**
* Construct a new advertising_data_status_t value.
*
* @param value The value of the advertising_data_status_t created.
*/
advertising_data_status_t(type value) : SafeEnum(value)
{
}
#if !defined(DOXYGEN_ONLY)
/**
* Explicit constructor from a raw value.
*/
explicit advertising_data_status_t(uint8_t raw_value) :
SafeEnum(static_cast<advertising_data_status_t>(raw_value))
{
}
#endif
};
/** Properties of an advertising event.
*/
struct advertising_event_t {
private:
// Implementation note: The object is constructed from the field Event_Type
// of an LE Extended Advertising.
// Indexes and functions of bits are defined in BLUETOOTH SPECIFICATION
// Version 5.0 | Vol 2, Part E -
// Section 7.7.65.13 LE Extended Advertising report Event
enum {
CONNECTABLE_BIT = 0,
SCANNABLE_ADVERTISING_BIT = 1,
DIRECTED_ADVERTISING_BIT = 2,
SCAN_RESPONSE_BIT = 3,
LEGACY_PDU_BIT = 4,
DATA_STATUS_INDEX = 5,
DATA_STATUS_MASK = 0x03
};
public:
#if !defined(DOXYGEN_ONLY)
/** Create based on a raw value.
*
* @param value
*/
explicit advertising_event_t(uint8_t value) : value(value)
{
}
#endif
/** Is advertising connectable.
*
* @return True if connectable.
*/
bool connectable() const
{
return static_cast<bool>(value & (1 << CONNECTABLE_BIT));
}
/** Is advertising scannable.
*
* @return True if scannable
*/
bool scannable_advertising() const
{
return static_cast<bool>(value & (1 << SCANNABLE_ADVERTISING_BIT));
}
/** Is advertising directed.
*
* @return True if directed.
*/
bool directed_advertising() const
{
return static_cast<bool>(value & (1 << DIRECTED_ADVERTISING_BIT));
}
/** Is this a scan response.
*
* @return True if scan response.
*/
bool scan_response() const
{
return static_cast<bool>(value & (1 << SCAN_RESPONSE_BIT));
}
/** Is this legacy advertising.
*
* @return True if legacy.
*/
bool legacy_advertising() const
{
return static_cast<bool>(value & (1 << LEGACY_PDU_BIT));
}
/** Payload completeness status.
*
* @return @see advertising_data_status_t for details.
*/
advertising_data_status_t data_status() const
{
return static_cast<advertising_data_status_t::type>(
(value >> DATA_STATUS_INDEX) & DATA_STATUS_MASK
);
}
/** Is payload complete.
*
* @return True if payload is coplete.
*/
bool complete() const
{
return data_status() == advertising_data_status_t::COMPLETE;
}
/** Is there more data coming.
*
* @return True if more data coming.
*/
bool more_data_to_come() const
{
return data_status() == advertising_data_status_t::INCOMPLETE_MORE_DATA;
}
/** Is the payload truncated.
*
* @return True if no more data coming.
*/
bool truncated() const
{
return data_status() == advertising_data_status_t::INCOMPLETE_DATA_TRUNCATED;
}
private:
uint8_t value;
};
/**
* Identify an advertising SID. Range: [0x00, 0x0F]
*/
typedef uint8_t advertising_sid_t;
/** Received signal strength. Range <-127, 20>.
* @note Special value 127 means RSSI is not available. */
typedef int8_t rssi_t;
/**
* Describe the advertising power.
*
* Values between -127 and +126 are considered power values in dBm while
* the special value 127 can be used as a wildcard to indicate that the host
* has no preference or if the power information is not available.
*/
typedef int8_t advertising_power_t;
/**
* Advertising policy filter modes.
*
* @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.2.
*/
struct advertising_filter_policy_t : SafeEnum<advertising_filter_policy_t, uint8_t> {
/// enumeration of advertising_filter_policy_t values
enum type {
/**
* Process connection and scan requests from all devices. The whitelist is
* not used.
*/
NO_FILTER = 0x00,
/**
* Process connection requests from all devices but filter out scan requests
* of devices that are not in the whitelist.
*/
FILTER_SCAN_REQUESTS = 0x01,
/**
* Process scan requests from all devices but filter out connection requests
* of devices that are not in the whitelist.
*/
FILTER_CONNECTION_REQUEST = 0x02,
/**
* Filter out scan or connection requests of devices that are not in the
* whitelist.
*/
FILTER_SCAN_AND_CONNECTION_REQUESTS = 0x03
};
/**
* Construct a advertising_filter_policy_t.
* @param value The value of the advertising_filter_policy_t created.
*/
advertising_filter_policy_t(type value) : SafeEnum(value)
{
}
};
/**
* Scanning policy filter mode.
*
* @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.3.
*/
struct scanning_filter_policy_t : SafeEnum<scanning_filter_policy_t, uint8_t> {
/// enumeration of scanning_filter_policy_t values
enum type {
/**
* Accept all advertising packets except directed advertising packets not
* addressed to this device.
*/
NO_FILTER = 0x00,
/**
* Accept only advertising packets from devices in the whitelist except
* directed advertising packets not addressed to this device.
*/
FILTER_ADVERTISING = 0x01,
/**
* Accept all advertising packets except directed advertising packets
* where the initiator's identity address does not address this device.
*
* @note Directed advertising packets where the initiator's address is a
* resolvable private address that cannot be resolved are also accepted.
*/
NO_FILTER_INCLUDE_UNRESOLVABLE_DIRECTED = 2,
/**
* Accept all advertising packets except:
* - Advertising packets where the advertiser's
* identity address is not in the whitelist.
* - Directed advertising packets where the initiator's identity address
* does not address this device.
*
* @note Directed advertising packets where the initiator's address is a
* resolvable private address that cannot be resolved are also accepted.
*/
FILTER_ADVERTISING_INCLUDE_UNRESOLVABLE_DIRECTED = 3
};
/**
* Construct a new instance of scanning_filter_policy_t.
*
* @param value The value of the scanning_filter_policy_t created.
*/
scanning_filter_policy_t(type value) : SafeEnum(value)
{
}
};
/**
* Filter policy that you can use during connection initiation.
*/
struct initiator_filter_policy_t : SafeEnum<initiator_filter_policy_t, uint8_t> {
/// enumeration of initiator_filter_policy_t values.
enum type {
/**
* The whitelist is not used to determine which advertiser to connect to.
*/
NO_FILTER,
/**
* The whitelist is used to determine which advertiser to connect to.
*/
USE_WHITE_LIST
};
/**
* Construct a initiator_filter_policy_t.
* @param value The value of the initiator_filter_policy_t.
*/
initiator_filter_policy_t(type value) : SafeEnum(value)
{
}
};
/**
* Scanning policy filter mode.
*
* @see Bluetooth Core Specification 4.2 (Vol. 6), Part B, Section 4.3.3.
*/
struct duplicates_filter_t : SafeEnum<duplicates_filter_t, uint8_t> {
/// enumeration of duplicates_filter_t values
enum type {
/**
* Disable duplicate filtering.
*/
DISABLE,
/**
* Enable duplicate filtering.
*/
ENABLE,
/**
* Enable duplicate filtering, and reset the cache periodically.
*/
PERIODIC_RESET
};
/**
* Construct a new duplicates_filter_t value.
* @param value The value of the duplicates_filter_t created.
*/
duplicates_filter_t(type value) : SafeEnum(value)
{
}
};
/**
* Type used to model the own address used during the following GAP operations:
* advertising, scanning and initiating
*/
struct own_address_type_t : SafeEnum<own_address_type_t, uint8_t> {
/// enumeration of own_address_type_t values.
enum type {
/**
* Use the public device address.
*/
PUBLIC = 0x00,
/**
* Use the random device address.
*/
RANDOM = 0x01,
/**
* Generated resolvable private address based on the local IRK from the
* resolving list. Use the public address if no entry match in the resolving
* list.
*/
RESOLVABLE_PRIVATE_ADDRESS_PUBLIC_FALLBACK = 0x02,
/**
* Generated resolvable private address based on the local IRK from the
* resolving list. Use the random address if no entry match in the resolving
* list.
*/
RESOLVABLE_PRIVATE_ADDRESS_RANDOM_FALLBACK = 0x03,
};
/**
* Construct a new instance of own_address_type_t.
* @param value The value of the own_address_type_t created.
*/
own_address_type_t(type value) : SafeEnum(value)
{
}
};
/**
* Type of an address to connect to.
*
* It is used to connect to a device directly with directed advertising.
*/
struct target_peer_address_type_t : SafeEnum<target_peer_address_type_t, uint8_t> {
/// enumeration of target_peer_address_type_t values.
enum type {
PUBLIC = 0x00, /**< Public Device Address or Public Identity Address. */
RANDOM = 0x01, /**< Random Device Address or Random (static) Identity Address. */
};
/**
* Create a new target_peer_address_type_t.
* @param value The value of the target_peer_address_type_t created.
*/
target_peer_address_type_t(type value) : SafeEnum(value)
{
}
};
/**
* Accuracy of the master clock.
*/
struct clock_accuracy_t : SafeEnum<clock_accuracy_t, uint8_t> {
/// enumeration of clock_accuracy_t values.
enum type {
/**
* 500 PPM
*/
PPM_500 = 0x00,
/**
* 250 PPM
*/
PPM_250 = 0x01,
/**
* 150 PPM
*/
PPM_150 = 0x02,
/**
* 100 PPM
*/
PPM_100 = 0x03,
/**
* 75 PPM
*/
PPM_75 = 0x04,
/**
* 50 PPM
*/
PPM_50 = 0x05,
/**
* 30 PPM
*/
PPM_30 = 0x06,
/**
* 20 PPM
*/
PPM_20 = 0x07
};
/** Get clock accuracy.
*
* @return Parts per million as a number.
*/
uint16_t get_ppm()
{
switch (value()) {
case PPM_500:
return 500;
case PPM_250:
return 250;
case PPM_150:
return 150;
case PPM_100:
return 100;
case PPM_75:
return 75;
case PPM_50:
return 50;
case PPM_30:
return 30;
case PPM_20:
return 20;
default:
return 0;
}
}
/**
* Construct a new clock_accuracy_t value.
* @param value The value of the clock_accuracy_t created.
*/
clock_accuracy_t(type value) : SafeEnum(value)
{
}
#if !defined(DOXYGEN_ONLY)
/**
* Construct a new clock_accuracy_t value from a raw value.
* @param raw_value The value of the clock accuracy.
*/
explicit clock_accuracy_t(uint8_t raw_value) : SafeEnum(raw_value)
{
}
#endif
};
/**
* Enumeration of GAP roles.
*
* @note The BLE API does not express the broadcaster and scanner roles.
*
* @attention A device can fulfill different roles concurrently.
*/
struct connection_role_t : SafeEnum<connection_role_t, uint8_t> {
/** struct scoped enum wrapped by the class */
enum type {
/**
* Central Role.
*
* The device can scan and initiate connection to peripherals. It
* acts as the master when a connection is established.
*
* @note A central is a scanner.
*/
CENTRAL = 0x00,
/**
* Peripheral Role.
*
* The device can advertise, and you can connect it by a central. It
* acts as a slave when connected.
*
* @note A peripheral is a broadcaster.
*/
PERIPHERAL = 0x01
};
/**
* Construct a new instance of role_t.
*
* @param value The value of the role_t created.
*/
connection_role_t(type value) : SafeEnum(value)
{
}
#if !defined(DOXYGEN_ONLY)
/**
* Explicit constructor from a raw value.
* @param raw_value The role.
*/
explicit connection_role_t(uint8_t raw_value) : SafeEnum(raw_value)
{
}
#endif
};
/**
* Enumeration of disconnection reasons that should be transmited to the peer.
*/
struct local_disconnection_reason_t : SafeEnum<local_disconnection_reason_t, uint8_t> {
/// enumeration of local_disconnection_reason_t values.
enum type {
/**
* GAP or GATT failed to authenticate the peer.
*/
AUTHENTICATION_FAILURE = 0x05,
/**
* Connection terminated by the user.
*/
USER_TERMINATION = 0x13,
/**
* Connection termination due to low resources.
*/
LOW_RESOURCES = 0x14,
/**
* Connection termination due to power off.
*/
POWER_OFF = 0x15,
/**
* Remote feature not supported.
*/
UNSUPPORTED_REMOTE_FEATURE = 0x1A,
/**
* Not possible to pai with a unit key.
*/
PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29,
/**
* Connection parameters were unacceptable.
*/
UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B
};
/**
* Construct a new instance of disconnection_reason_t.
*
* @param value The value of the local_disconnection_reason_t created.
*/
local_disconnection_reason_t(type value) : SafeEnum(value)
{
}
};
/**
* Enumeration of disconnection reasons received in a disconnection event.
*/
struct disconnection_reason_t : SafeEnum<disconnection_reason_t, uint8_t> {
/// enumeration of disconnection_reason_t values.
enum type {
/**
* GAP or GATT failed to authenticate the peer.
*/
AUTHENTICATION_FAILURE = 0x05,
/**
* The connection timed out.
*/
CONNECTION_TIMEOUT = 0x08,
/**
* Connection terminated by the user.
*/
REMOTE_USER_TERMINATED_CONNECTION = 0x13,
/**
* Remote device terminated connection due to low resources.
*/
REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14,
/**
* Remote device terminated connection due to power off.
*/
REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15,
/**
* Indicate that the local user or the internal
* Bluetooth subsystem terminated the connection.
*/
LOCAL_HOST_TERMINATED_CONNECTION = 0x16,
/**
* Connection parameters were unacceptable.
*/
UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B
};
/**
* Construct a new instance of disconnection_reason_t.
*
* @param value The value of the disconnection_reason_t created.
*/
disconnection_reason_t(type value) : SafeEnum(value)
{
}
};
/**
* Privacy Configuration of the peripheral role.
*
* @note This configuration also applies to the broadcaster role configuration.
*/
struct peripheral_privacy_configuration_t {
/**
* Indicates if nonresolvable random address should be used when the
* peripheral advertises nonconnectable packets.
*
* Resolvable random address continues to be used for connectable packets.
*/
bool use_non_resolvable_random_address;
/**
* Resolution strategy for initiator resolvable addresses when a
* connection request is received.
*/
enum resolution_strategy_t {
/**
* Do not resolve the address of the initiator and accept the
* connection request.
*/
DO_NOT_RESOLVE,
/**
* If a bond is present in the secure database and the address
* resolution fails, then reject the connection request with the error
* code AUTHENTICATION_FAILLURE.
*/
REJECT_NON_RESOLVED_ADDRESS,
/**
* Perform the pairing procedure if the initiator resolvable
* address failed the resolution process.
*/
PERFORM_PAIRING_PROCEDURE,
/**
* Perform the authentication procedure if the initiator resolvable
* address failed the resolution process.
*/
PERFORM_AUTHENTICATION_PROCEDURE
};
/**
* Connection strategy to use when a connection request contains a
* private resolvable address.
*/
resolution_strategy_t resolution_strategy;
};
/**
* Privacy configuration of the central role.
*
* @note This configuration is also used when the local device operates as
* an observer.
*/
struct central_privay_configuration_t {
/**
* Indicates if nonresolvable random address should be used when the
* central or observer sends scan request packets.
*
* Resolvable random address continues to be used for connection requests.
*/
bool use_non_resolvable_random_address;
/**
* Resolution strategy of resolvable addresses received in advertising
* packets.
*/
enum resolution_strategy_t {
/**
* Do not resolve the address received in advertising packets.
*/
DO_NOT_RESOLVE,
/**
* Resolve the resolvable addresses in the advertising packet and
* forward advertising packet to the application independently of
* the address resolution procedure result.
*/
RESOLVE_AND_FORWARD,
/**
* Filter out packets containing a resolvable address that cannot be resolved
* by this device.
*
* @note Filtering is applied if the local device contains at least
* one bond.
*/
RESOLVE_AND_FILTER
};
/**
* Resolution strategy applied to advertising packets received by the
* local device.
*/
resolution_strategy_t resolution_strategy;
};
/**
* @}
* @}
*/
} // namespace ble
#endif //BLE_GAP_TYPES_H

View File

@ -42,15 +42,20 @@ namespace generic {
* *
* @attention: Not part of the public interface of BLE API. * @attention: Not part of the public interface of BLE API.
*/ */
class GenericGap : public ::Gap, class GenericGap :
public ::Gap,
public pal::ConnectionEventMonitor, public pal::ConnectionEventMonitor,
public pal::Gap::EventHandler { public pal::Gap::EventHandler {
public: public:
/* TODO: move to config */
static const uint8_t MAX_ADVERTISING_SETS = 15;
static const size_t MAX_HCI_DATA_LENGTH = 251;
/** /**
* Construct a GenericGap instance for a given BLE instance ID. * Construct a GenericGap.
* *
* @param ble_instance_id Id of the BLE instance using this instance. * @param event_queue Event queue used to serialise execution.
* *
* @param pal_gap GAP Platform abstraction instance containing the base GAP * @param pal_gap GAP Platform abstraction instance containing the base GAP
* primitives. * primitives.
@ -73,6 +78,157 @@ public:
*/ */
virtual ~GenericGap(); virtual ~GenericGap();
/** @copydoc Gap::IsFeatureSupported
*/
virtual bool isFeatureSupported(
controller_supported_features_t feature
);
/** @copydoc Gap::getMaxAdvertisingSetNumber
*/
virtual uint8_t getMaxAdvertisingSetNumber();
/** @copydoc Gap::getMaxAdvertisingDataLength
*/
virtual uint8_t getMaxAdvertisingDataLength();
/** @copydoc Gap::createAdvertisingSet
*/
virtual ble_error_t createAdvertisingSet(
advertising_handle_t *handle,
const AdvertisingParameters &parameters
);
/** @copydoc Gap::destroyAdvertisingSet
*/
virtual ble_error_t destroyAdvertisingSet(advertising_handle_t handle);
/** @copydoc Gap::setAdvertisingParams
*/
virtual ble_error_t setAdvertisingParameters(
advertising_handle_t handle,
const AdvertisingParameters &params
);
/** @copydoc Gap::setAdvertisingPayload
*/
virtual ble_error_t setAdvertisingPayload(
advertising_handle_t handle,
mbed::Span<const uint8_t> payload
);
/** @copydoc Gap::setAdvertisingScanResponse
*/
virtual ble_error_t setAdvertisingScanResponse(
advertising_handle_t handle,
mbed::Span<const uint8_t> response
);
/** @copydoc Gap::startAdvertising
*/
virtual ble_error_t startAdvertising(
advertising_handle_t handle,
adv_duration_t maxDuration,
uint8_t maxEvents
);
/** @copydoc Gap::stopAdvertising
*/
virtual ble_error_t stopAdvertising(advertising_handle_t handle);
/** @copydoc Gap::isAdvertisingActive
*/
virtual bool isAdvertisingActive(advertising_handle_t handle);
/** @copydoc Gap::setPeriodicAdvertisingParameters
*/
virtual ble_error_t setPeriodicAdvertisingParameters(
advertising_handle_t handle,
periodic_interval_t periodicAdvertisingIntervalMin,
periodic_interval_t periodicAdvertisingIntervalMax,
bool advertiseTxPower
);
/** @copydoc Gap::setPeriodicAdvertisingPayload
*/
virtual ble_error_t setPeriodicAdvertisingPayload(
advertising_handle_t handle,
mbed::Span<const uint8_t> payload
);
/** @copydoc Gap::startPeriodicAdvertising
*/
virtual ble_error_t startPeriodicAdvertising(advertising_handle_t handle);
/** @copydoc Gap::stopPeriodicAdvertising
*/
virtual ble_error_t stopPeriodicAdvertising(advertising_handle_t handle);
/** @copydoc Gap::isPeriodicAdvertisingActive
*/
virtual bool isPeriodicAdvertisingActive(advertising_handle_t handle);
/** @copydoc Gap::setScanParameters
*/
virtual ble_error_t setScanParameters(const ScanParameters &params);
/** @copydoc Gap::startScan
*/
virtual ble_error_t startScan(
duplicates_filter_t filtering,
scan_duration_t duration,
scan_period_t period
);
/** @copydoc Gap::createSync
*/
virtual ble_error_t createSync(
peer_address_type_t peerAddressType,
const ble::address_t &peerAddress,
advertising_sid_t sid,
slave_latency_t maxPacketSkip,
sync_timeout_t timeout
);
/** @copydoc Gap::createSync
*/
virtual ble_error_t createSync(
slave_latency_t maxPacketSkip,
sync_timeout_t timeout
);
/** @copydoc Gap::cancelCreateSync
*/
virtual ble_error_t cancelCreateSync();
/** @copydoc Gap::terminateSync
*/
virtual ble_error_t terminateSync(periodic_sync_handle_t handle);
/** @copydoc Gap::addDeviceToPeriodicAdvertiserList
*/
virtual ble_error_t addDeviceToPeriodicAdvertiserList(
peer_address_type_t peerAddressType,
const ble::address_t &peerAddress,
advertising_sid_t sid
);
/** @copydoc Gap::removeDeviceFromPeriodicAdvertiserList
*/
virtual ble_error_t removeDeviceFromPeriodicAdvertiserList(
peer_address_type_t peerAddressType,
const ble::address_t &peerAddress,
advertising_sid_t sid
);
/** @copydoc Gap::clearPeriodicAdvertiserList
*/
virtual ble_error_t clearPeriodicAdvertiserList();
/** @copydoc Gap::getMaxPeriodicAdvertiserListSize
*/
virtual uint8_t getMaxPeriodicAdvertiserListSize();
/** /**
* @see Gap::setAddress * @see Gap::setAddress
*/ */
@ -134,6 +290,48 @@ public:
const GapScanningParams *scanParams const GapScanningParams *scanParams
); );
/**
* @see Gap::connect
*/
virtual ble_error_t connect(
peer_address_type_t peerAddressType,
const ble::address_t &peerAddress,
const ConnectionParameters &connectionParams
);
/**
* @see Gap::cancelConnect
*/
virtual ble_error_t cancelConnect();
virtual ble_error_t manageConnectionParametersUpdateRequest(
bool userManageConnectionUpdateRequest
);
virtual ble_error_t updateConnectionParameters(
connection_handle_t connectionHandle,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t supervisionTimeout,
conn_event_length_t minConnectionEventLength,
conn_event_length_t maxConnectionEventLength
);
virtual ble_error_t acceptConnectionParametersUpdate(
connection_handle_t connectionHandle,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t supervisionTimeout,
conn_event_length_t minConnectionEventLength,
conn_event_length_t maxConnectionEventLength
);
virtual ble_error_t rejectConnectionParametersUpdate(
connection_handle_t connectionHandle
);
/** /**
* @see Gap::readPhy * @see Gap::readPhy
*/ */
@ -143,8 +341,8 @@ public:
* @see Gap::setPreferredPhys * @see Gap::setPreferredPhys
*/ */
virtual ble_error_t setPreferredPhys( virtual ble_error_t setPreferredPhys(
const phy_set_t* txPhys, const phy_set_t *txPhys,
const phy_set_t* rxPhys const phy_set_t *rxPhys
); );
/** /**
@ -152,11 +350,16 @@ public:
*/ */
virtual ble_error_t setPhy( virtual ble_error_t setPhy(
Handle_t connection, Handle_t connection,
const phy_set_t* txPhys, const phy_set_t *txPhys,
const phy_set_t* rxPhys, const phy_set_t *rxPhys,
CodedSymbolPerBit_t codedSymbol CodedSymbolPerBit_t codedSymbol
); );
virtual ble_error_t disconnect(
connection_handle_t connectionHandle,
local_disconnection_reason_t reason
);
/** /**
* @see Gap::disconnect * @see Gap::disconnect
*/ */
@ -326,7 +529,7 @@ public:
/** /**
* @copydoc ::Gap::processConnectionEvent * @copydoc ::Gap::processConnectionEvent
*/ */
void processConnectionEvent( virtual void processConnectionEvent(
Handle_t handle, Handle_t handle,
Role_t role, Role_t role,
peer_address_type_t peerAddrType, peer_address_type_t peerAddrType,
@ -341,12 +544,19 @@ public:
/** /**
* @copydoc ::Gap::processDisconnectionEvent * @copydoc ::Gap::processDisconnectionEvent
*/ */
void processDisconnectionEvent( virtual void processDisconnectionEvent(
Handle_t handle, Handle_t handle,
DisconnectionReason_t reason DisconnectionReason_t reason
); );
private: private:
ble_error_t setAdvertisingData(
advertising_handle_t handle,
mbed::Span<const uint8_t> payload,
bool minimiseFragmentation,
bool scan_response
);
/** @note Implements ConnectionEventMonitor. /** @note Implements ConnectionEventMonitor.
* @copydoc ConnectionEventMonitor::set_connection_event_handler * @copydoc ConnectionEventMonitor::set_connection_event_handler
*/ */
@ -393,26 +603,113 @@ private:
void update_random_address(); void update_random_address();
bool getUnresolvableRandomAddress(ble::address_t &address);
void on_address_rotation_timeout(); void on_address_rotation_timeout();
virtual void useVersionOneAPI() const;
virtual void useVersionTwoAPI() const;
/* implements pal::Gap::EventHandler */ /* implements pal::Gap::EventHandler */
private: private:
virtual void on_read_phy( virtual void on_read_phy(
pal::hci_error_code_t hci_status, pal::hci_error_code_t hci_status,
Handle_t connection_handle, Handle_t connection_handle,
ble::phy_t tx_phy, phy_t tx_phy,
ble::phy_t rx_phy phy_t rx_phy
); );
virtual void on_phy_update_complete( virtual void on_phy_update_complete(
pal::hci_error_code_t hci_status, pal::hci_error_code_t hci_status,
Handle_t connection_handle, Handle_t connection_handle,
ble::phy_t tx_phy, phy_t tx_phy,
ble::phy_t rx_phy phy_t rx_phy
);
virtual void on_enhanced_connection_complete(
pal::hci_error_code_t status,
connection_handle_t connection_handle,
pal::connection_role_t own_role,
pal::connection_peer_address_type_t peer_address_type,
const ble::address_t &peer_address,
const ble::address_t &local_resolvable_private_address,
const ble::address_t &peer_resolvable_private_address,
uint16_t connection_interval,
uint16_t connection_latency,
uint16_t supervision_timeout,
pal::clock_accuracy_t master_clock_accuracy
);
virtual void on_extended_advertising_report(
advertising_event_t event_type,
const pal::connection_peer_address_type_t *address_type,
const ble::address_t &address,
phy_t primary_phy,
const phy_t *secondary_phy,
advertising_sid_t advertising_sid,
pal::advertising_power_t tx_power,
pal::rssi_t rssi,
uint16_t periodic_advertising_interval,
pal::direct_address_type_t direct_address_type,
const ble::address_t &direct_address,
uint8_t data_length,
const uint8_t *data
);
virtual void on_periodic_advertising_sync_established(
pal::hci_error_code_t error,
pal::sync_handle_t sync_handle,
advertising_sid_t advertising_sid,
pal::connection_peer_address_type_t advertiser_address_type,
const ble::address_t &advertiser_address,
phy_t advertiser_phy,
uint16_t periodic_advertising_interval,
pal::clock_accuracy_t clock_accuracy
);
virtual void on_periodic_advertising_report(
pal::sync_handle_t sync_handle,
pal::advertising_power_t tx_power,
pal::rssi_t rssi,
pal::advertising_data_status_t data_status,
uint8_t data_length,
const uint8_t *data
);
virtual void on_periodic_advertising_sync_loss(pal::sync_handle_t sync_handle);
virtual void on_advertising_set_terminated(
pal::hci_error_code_t status,
advertising_handle_t advertising_handle,
connection_handle_t connection_handle,
uint8_t number_of_completed_extended_advertising_events
);
virtual void on_scan_request_received(
advertising_handle_t advertising_handle,
pal::connection_peer_address_type_t scanner_address_type,
const ble::address_t &address
);
virtual void on_connection_update_complete(
pal::hci_error_code_t status,
connection_handle_t connection_handle,
uint16_t connection_interval,
uint16_t connection_latency,
uint16_t supervision_timeout
);
virtual void on_remote_connection_parameter(
connection_handle_t connection_handle,
uint16_t connection_interval_min,
uint16_t connection_interval_max,
uint16_t connection_latency,
uint16_t supervision_timeout
); );
private: private:
pal::EventQueue& _event_queue; pal::EventQueue &_event_queue;
pal::Gap &_pal_gap; pal::Gap &_pal_gap;
pal::GenericAccessService &_gap_service; pal::GenericAccessService &_gap_service;
pal::SecurityManager &_pal_sm; pal::SecurityManager &_pal_sm;
@ -433,6 +730,69 @@ private:
mbed::Timeout _scan_timeout; mbed::Timeout _scan_timeout;
mbed::Ticker _address_rotation_ticker; mbed::Ticker _address_rotation_ticker;
pal::ConnectionEventMonitor::EventHandler *_connection_event_handler; pal::ConnectionEventMonitor::EventHandler *_connection_event_handler;
template<size_t bit_size>
struct BitArray {
BitArray() : data()
{
}
bool get(size_t index) const
{
position p(index);
return (data[p.byte_index] >> p.bit_index) & 0x01;
}
void set(size_t index)
{
position p(index);
data[p.byte_index] |= (0x01 << p.bit_index);
}
void clear(size_t index)
{
position p(index);
data[p.byte_index] &= ~(0x01 << p.bit_index);
}
void clear()
{
for (size_t i = 0; i < (bit_size / 8 + 1); ++i) {
data[i] = 0;
}
}
private:
struct position {
position(size_t bit_number) :
byte_index(bit_number / 8),
bit_index(bit_number % 8)
{
}
size_t byte_index;
uint8_t bit_index;
};
uint8_t data[bit_size / 8 + 1];
};
BitArray<MAX_ADVERTISING_SETS> _existing_sets;
BitArray<MAX_ADVERTISING_SETS> _active_sets;
BitArray<MAX_ADVERTISING_SETS> _active_periodic_sets;
// deprecation flags
mutable bool _deprecated_scan_api_used : 1;
mutable bool _non_deprecated_scan_api_used : 1;
bool _user_manage_connection_parameter_requests : 1;
private:
ble_error_t setExtendedAdvertisingParameters(
advertising_handle_t handle,
const AdvertisingParameters &parameters
);
bool is_extended_advertising_available();
}; };
} }

View File

@ -44,7 +44,7 @@ public:
* @see GattClient::launchServiceDiscovery * @see GattClient::launchServiceDiscovery
*/ */
virtual ble_error_t launchServiceDiscovery( virtual ble_error_t launchServiceDiscovery(
Gap::Handle_t connection_handle, connection_handle_t connection_handle,
ServiceDiscovery::ServiceCallback_t service_callback, ServiceDiscovery::ServiceCallback_t service_callback,
ServiceDiscovery::CharacteristicCallback_t characteristic_callback, ServiceDiscovery::CharacteristicCallback_t characteristic_callback,
const UUID& matching_service_uuid, const UUID& matching_service_uuid,
@ -65,7 +65,7 @@ public:
* @see GattClient::read * @see GattClient::read
*/ */
virtual ble_error_t read( virtual ble_error_t read(
Gap::Handle_t connection_handle, connection_handle_t connection_handle,
GattAttribute::Handle_t attribute_handle, GattAttribute::Handle_t attribute_handle,
uint16_t offset uint16_t offset
) const; ) const;
@ -75,7 +75,7 @@ public:
*/ */
virtual ble_error_t write( virtual ble_error_t write(
GattClient::WriteOp_t cmd, GattClient::WriteOp_t cmd,
Gap::Handle_t connection_handle, connection_handle_t connection_handle,
GattAttribute::Handle_t attribute_handle, GattAttribute::Handle_t attribute_handle,
size_t length, size_t length,
const uint8_t* value const uint8_t* value
@ -128,18 +128,18 @@ private:
struct WriteControlBlock; struct WriteControlBlock;
struct DescriptorDiscoveryControlBlock; struct DescriptorDiscoveryControlBlock;
ProcedureControlBlock* get_control_block(Gap::Handle_t connection); ProcedureControlBlock* get_control_block(connection_handle_t connection);
const ProcedureControlBlock* get_control_block(Gap::Handle_t connection) const; const ProcedureControlBlock* get_control_block(connection_handle_t connection) const;
void insert_control_block(ProcedureControlBlock* cb) const; void insert_control_block(ProcedureControlBlock* cb) const;
void remove_control_block(ProcedureControlBlock* cb) const; void remove_control_block(ProcedureControlBlock* cb) const;
void on_termination(Gap::Handle_t connection_handle); void on_termination(connection_handle_t connection_handle);
void on_server_message_received(connection_handle_t, const pal::AttServerMessage&); void on_server_message_received(connection_handle_t, const pal::AttServerMessage&);
void on_server_response(connection_handle_t, const pal::AttServerMessage&); void on_server_response(connection_handle_t, const pal::AttServerMessage&);
void on_server_event(connection_handle_t, const pal::AttServerMessage&); void on_server_event(connection_handle_t, const pal::AttServerMessage&);
void on_transaction_timeout(connection_handle_t); void on_transaction_timeout(connection_handle_t);
uint16_t get_mtu(Gap::Handle_t connection) const; uint16_t get_mtu(connection_handle_t connection) const;
pal::GattClient* const _pal_client; pal::GattClient* const _pal_client;
ServiceDiscovery::TerminationCallback_t _termination_callback; ServiceDiscovery::TerminationCallback_t _termination_callback;

View File

@ -68,7 +68,7 @@ public:
virtual ble_error_t purgeAllBondingState(); virtual ble_error_t purgeAllBondingState();
virtual ble_error_t generateWhitelistFromBondTable( virtual ble_error_t generateWhitelistFromBondTable(
Gap::Whitelist_t *whitelist ::Gap::Whitelist_t *whitelist
) const; ) const;
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -398,12 +398,12 @@ private:
*/ */
virtual void on_connected( virtual void on_connected(
connection_handle_t connection, connection_handle_t connection,
Gap::Role_t role, ::Gap::Role_t role,
peer_address_type_t peer_address_type, peer_address_type_t peer_address_type,
const BLEProtocol::AddressBytes_t peer_address, const BLEProtocol::AddressBytes_t peer_address,
BLEProtocol::AddressType_t local_address_type, BLEProtocol::AddressType_t local_address_type,
const BLEProtocol::AddressBytes_t local_address, const BLEProtocol::AddressBytes_t local_address,
const Gap::ConnectionParams_t *connection_params const ::Gap::ConnectionParams_t *connection_params
); );
/** /**
@ -415,7 +415,7 @@ private:
*/ */
virtual void on_disconnected( virtual void on_disconnected(
connection_handle_t connection, connection_handle_t connection,
Gap::DisconnectionReason_t reason ::Gap::DisconnectionReason_t reason
); );
/** /**

View File

@ -0,0 +1,48 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BLE_PAL_DEPRECATED_H
#define BLE_PAL_DEPRECATED_H
/**
* Declare the beginning of a code block that uses a deprecated API
*/
#if defined(__GNUC__) && !defined(__CC_ARM)
#define BLE_DEPRECATED_API_USE_BEGIN() \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
#elif defined(__CC_ARM)
#define BLE_DEPRECATED_API_USE_BEGIN() \
_Pragma("push") \
_Pragma("diag_suppress 1361")
#else
#define BLE_DEPRECATED_API_USE_BEGIN()
#endif
/**
* Declare the end of a code block that uses a deprecated API
*/
#if defined(__GNUC__) && !defined(__CC_ARM)
#define BLE_DEPRECATED_API_USE_END() \
_Pragma("GCC diagnostic pop")
#elif defined(__CC_ARM)
#define BLE_DEPRECATED_API_USE_END() \
_Pragma("pop")
#else
#define BLE_DEPRECATED_API_USE_END()
#endif
#endif //BLE_PAL_DEPRECATED_H

View File

@ -158,7 +158,7 @@ struct GapConnectionCompleteEvent : public GapEvent {
connection_handle(connection_handle), connection_handle(connection_handle),
role(role), role(role),
peer_address_type( peer_address_type(
peer_address_type == advertising_peer_address_type_t::PUBLIC_ADDRESS ? peer_address_type == advertising_peer_address_type_t::PUBLIC ?
peer_address_type_t::PUBLIC : peer_address_type_t::PUBLIC :
peer_address_type_t::RANDOM peer_address_type_t::RANDOM
), ),

View File

@ -24,108 +24,11 @@
namespace ble { namespace ble {
namespace pal { namespace pal {
/** typedef ble::advertising_type_t advertising_type_t;
* Type of advertising the LE subsystem can use when it advertise.
*/
struct advertising_type_t : SafeEnum<advertising_type_t, uint8_t> {
enum type {
/**
* Connectable and scannable undirected advertising .
*/
ADV_IND = 0x00,
/** typedef ble::own_address_type_t own_address_type_t;
* Connectable high duty cycle directed advertising
*/
ADV_DIRECT_IND = 0x01,
/**
* Scannable undirected advertising
*/
ADV_SCAN_IND = 0x02,
/**
* Non connectable undirected advertising
*/
ADV_NONCONN_IND = 0x03,
/**
* Connectable low duty cycle directed advertising
*/
ADV_DIRECT_IND_LOW_DUTY_CYCLE = 0x04
};
/**
* Construct a new advertising_type_t value.
*/
advertising_type_t(type value) :
SafeEnum<advertising_type_t, uint8_t>(value) { }
};
/**
* Type used to model the own address used during the following GAP operations:
* advertising, scanning and initiating
*/
struct own_address_type_t : SafeEnum<own_address_type_t, uint8_t> {
enum type {
/**
* Use the public device address
*/
PUBLIC_ADDRESS = 0x00,
/**
* Use the random device address
*/
RANDOM_ADDRESS = 0x01,
/**
* Generated resolvable private address based on the local IRK from the
* resolving list. Use the public address if no entry match in the resolving
* list.
*/
RESOLVABLE_PRIVATE_ADDRESS_PUBLIC_FALLBACK = 0x02,
/**
* Generated resolvable private address based on the local IRK from the
* resolving list. Use the random address if no entry match in the resolving
* list.
*/
RESOLVABLE_PRIVATE_ADDRESS_RANDOM_FALLBACK = 0x03,
};
/**
* Construct a new instance of own_address_type_t.
*/
own_address_type_t(type value) :
SafeEnum<own_address_type_t, uint8_t>(value) { }
};
/**
* Type modeling the peer address type during direct advertising.
*/
struct advertising_peer_address_type_t :
SafeEnum<advertising_peer_address_type_t, uint8_t> {
enum type {
/**
* Public device address or identity address.
*/
PUBLIC_ADDRESS = 0x00,
/**
* Random device address or random (static) identity address.
*/
RANDOM_ADDRESS = 0x01
};
/**
* Construct a new instance of advertising_peer_address_type_t.
*/
advertising_peer_address_type_t(type value) :
SafeEnum<advertising_peer_address_type_t, uint8_t>(value) { }
};
typedef ble::target_peer_address_type_t advertising_peer_address_type_t;
/** /**
* Peer address type used during connection initiating. * Peer address type used during connection initiating.
@ -134,12 +37,12 @@ struct connection_peer_address_type_t :
SafeEnum<connection_peer_address_type_t, uint8_t> { SafeEnum<connection_peer_address_type_t, uint8_t> {
enum type { enum type {
/** /**
* Public device address * Public device address.
*/ */
PUBLIC_ADDRESS = 0x00, PUBLIC_ADDRESS = 0x00,
/** /**
* Random device address * Random device address.
*/ */
RANDOM_ADDRESS = 0x01, RANDOM_ADDRESS = 0x01,
@ -160,7 +63,14 @@ struct connection_peer_address_type_t :
* Construct a new connection_peer_address_type_t instance. * Construct a new connection_peer_address_type_t instance.
*/ */
connection_peer_address_type_t(type value) : connection_peer_address_type_t(type value) :
SafeEnum<connection_peer_address_type_t, uint8_t>(value) { } SafeEnum<connection_peer_address_type_t, uint8_t>(value)
{
}
explicit connection_peer_address_type_t(uint8_t raw_value) :
SafeEnum<connection_peer_address_type_t, uint8_t>(raw_value)
{
}
}; };
@ -180,7 +90,9 @@ struct whitelist_address_type_t : SafeEnum<whitelist_address_type_t, uint8_t> {
* Construct a new whitelist_address_type_t instance. * Construct a new whitelist_address_type_t instance.
*/ */
whitelist_address_type_t(type value) : whitelist_address_type_t(type value) :
SafeEnum<whitelist_address_type_t, uint8_t>(value) { } SafeEnum<whitelist_address_type_t, uint8_t>(value)
{
}
}; };
@ -206,7 +118,14 @@ struct advertising_channel_map_t : SafeEnum<advertising_channel_map_t, uint8_t>
* Construct a new advertising_channel_map_t instance. * Construct a new advertising_channel_map_t instance.
*/ */
advertising_channel_map_t(type value) : advertising_channel_map_t(type value) :
SafeEnum<advertising_channel_map_t, uint8_t>(value) { } SafeEnum<advertising_channel_map_t, uint8_t>(value)
{
}
advertising_channel_map_t(bool ch37, bool ch38, bool ch39) :
SafeEnum<advertising_channel_map_t, uint8_t>(ch37 | (ch38 << 1) | (ch39 << 2))
{
}
}; };
@ -295,120 +214,27 @@ struct hci_error_code_t : SafeEnum<hci_error_code_t, uint8_t> {
* Construct a new hci_error_code_t instance. * Construct a new hci_error_code_t instance.
*/ */
hci_error_code_t(type value) : hci_error_code_t(type value) :
SafeEnum<hci_error_code_t, uint8_t>(value) { } SafeEnum<hci_error_code_t, uint8_t>(value)
{
}
/**
* Construct a new hci_error_code_t from a raw value.
*/
explicit hci_error_code_t(uint8_t raw_value) :
SafeEnum<hci_error_code_t, uint8_t>(static_cast<type>(raw_value))
{
}
}; };
/** typedef ble::local_disconnection_reason_t disconnection_reason_t;
* Reasons which can be used to end a connection.
*/
struct disconnection_reason_t : SafeEnum<disconnection_reason_t, uint8_t> {
enum type {
AUTHENTICATION_FAILLURE = 0x05,
REMOTE_USER_TERMINATED_CONNECTION = 0x13,
REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES = 0x14,
REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF = 0x15,
UNSUPPORTED_REMOTE_FEATURE = 0x1A,
PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29,
UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B
};
/** typedef ble::advertising_filter_policy_t advertising_filter_policy_t;
* Construct a new disconnection_reason_t instance.
*/
disconnection_reason_t(type value) :
SafeEnum<disconnection_reason_t, uint8_t>(value) { }
};
typedef ble::scanning_filter_policy_t scanning_filter_policy_t;
/** typedef ble::initiator_filter_policy_t initiator_policy_t;
* Filter policy which can be used during advertising.
*/
struct advertising_filter_policy_t :
SafeEnum<advertising_filter_policy_t, uint8_t> {
enum type {
/**
* Process connection and scan requests from all devices. The whitelist is
* not used.
*/
NO_FILTER = 0x00,
/**
* Process connection requests from all devices but filter out scan requests
* of devices which are not in the whitelist.
*/
FILTER_SCAN_REQUESTS = 0x01,
/**
* Process scan requests from all devices but filter out connection requests
* of devices which are not in the whitelist.
*/
FILTER_CONNECTION_REQUEST = 0x02,
/**
* Filter out scan or connection requests of devices which are not in the
* whitelist.
*/
FILTER_SCAN_AND_CONNECTION_REQUESTS = 0x03
};
/**
* Construct a new instance of advertising_filter_policy_t.
*/
advertising_filter_policy_t(type value) :
SafeEnum<advertising_filter_policy_t, uint8_t>(value) { }
};
/**
* Filter policy which can be used during a scan.
*/
struct scanning_filter_policy_t : SafeEnum<scanning_filter_policy_t, uint8_t> {
enum type {
/**
* Accept all advertising packets except directed advertising packet not
* addressed to this device.
*/
NO_FILTER = 0x00,
/**
* Accept only advertising packets from devices in the whitelist except
* directed advertising packet not addressed to this device.
*/
FILTER_ADVERTISING = 0x01
// EXTENDED ADVERTISING FILTER POLICY (accept private resolvable direct advertising)
};
/**
* Construct a new instance of scanning_filter_policy_t.
*/
scanning_filter_policy_t(type value) :
SafeEnum<scanning_filter_policy_t, uint8_t>(value) { }
};
/**
* Filter policy which can be used during connection initiation.
*/
struct initiator_policy_t : SafeEnum<initiator_policy_t, uint8_t> {
enum type {
/**
* The whitelist is not used to determine which advertiser to connect to.
*/
NO_FILTER,
/**
* Whitelist is used to determine which advertiser to connect to.
*/
USE_WHITE_LIST
};
initiator_policy_t(type value) :
SafeEnum<initiator_policy_t, uint8_t>(value) { }
};
/** /**
* Hold advertising data. * Hold advertising data.
@ -419,7 +245,8 @@ struct advertising_data_t {
* *
* @param input_value Reference to the array containing the advertising data * @param input_value Reference to the array containing the advertising data
*/ */
advertising_data_t(const uint8_t (&input_value)[31]) { advertising_data_t(const uint8_t (&input_value)[31])
{
memcpy(value, input_value, sizeof(value)); memcpy(value, input_value, sizeof(value));
} }
@ -430,7 +257,8 @@ struct advertising_data_t {
* *
* @param len Length of the buffer. * @param len Length of the buffer.
*/ */
advertising_data_t(const uint8_t* input_value, size_t len) { advertising_data_t(const uint8_t *input_value, size_t len)
{
const size_t actual_len = std::min(len, sizeof(value)); const size_t actual_len = std::min(len, sizeof(value));
memcpy(value, input_value, actual_len); memcpy(value, input_value, actual_len);
memset(value + actual_len, 0x00, sizeof(value) - actual_len); memset(value + actual_len, 0x00, sizeof(value) - actual_len);
@ -440,8 +268,9 @@ struct advertising_data_t {
* Equal operator between two advertising data. * Equal operator between two advertising data.
*/ */
friend bool operator==( friend bool operator==(
const advertising_data_t& lhs, const advertising_data_t& rhs const advertising_data_t &lhs, const advertising_data_t &rhs
) { )
{
return memcmp(lhs.value, rhs.value, sizeof(lhs.value)) == 0; return memcmp(lhs.value, rhs.value, sizeof(lhs.value)) == 0;
} }
@ -449,29 +278,33 @@ struct advertising_data_t {
* Non equal operator between two advertising data. * Non equal operator between two advertising data.
*/ */
friend bool operator!=( friend bool operator!=(
const advertising_data_t& lhs, const advertising_data_t& rhs const advertising_data_t &lhs, const advertising_data_t &rhs
) { )
{
return !(lhs == rhs); return !(lhs == rhs);
} }
/** /**
* Subscript operator used to access the content of the advertising data. * Subscript operator used to access the content of the advertising data.
*/ */
uint8_t operator[](uint8_t i) const { uint8_t operator[](uint8_t i) const
{
return value[i]; return value[i];
} }
/** /**
* Return a pointer to the advertising data buffer. * Return a pointer to the advertising data buffer.
*/ */
const uint8_t* data() const { const uint8_t *data() const
{
return value; return value;
} }
/** /**
* Return (fixed) size of advertising data. * Return (fixed) size of advertising data.
*/ */
uint8_t size() const { uint8_t size() const
{
return sizeof(value); return sizeof(value);
} }
@ -515,22 +348,303 @@ struct received_advertising_type_t :
* Construct a new received_advertising_type_t value. * Construct a new received_advertising_type_t value.
*/ */
received_advertising_type_t(type value) : received_advertising_type_t(type value) :
SafeEnum<received_advertising_type_t, uint8_t>(value) { } SafeEnum<received_advertising_type_t, uint8_t>(value)
{
}
}; };
/** /**
* Model connection role. Used in GapConnectionCompleteEvent. * @see ble::connection_role_t
*/ */
struct connection_role_t : SafeEnum<connection_role_t, uint8_t> { typedef ble::connection_role_t connection_role_t;
/**
* Properties of an advertising event.
*/
struct advertising_event_properties_t {
/**
* Default constructor, all fields sets to 0.
*/
advertising_event_properties_t() :
connectable(false),
scannable(false),
directed(false),
high_duty_cycle(false),
use_legacy_pdu(false),
omit_advertiser_address(false),
include_tx_power(false)
{
}
/**
* Construct an advertising_event_properties_t with all fields defined by
* user.
* @param connectable @see advertising_event_properties_t::connectable
* @param scannable @see advertising_event_properties_t::scannable
* @param directed @see advertising_event_properties_t::directed
* @param high_duty_cycle @see advertising_event_properties_t::high_duty_cycle
* @param use_legacy_pdu @see advertising_event_properties_t::use_legacy_pdu
* @param omit_advertisser_address @see
* advertising_event_properties_t::omit_advertiser_address
* @param include_tx_power
* @see advertising_event_properties_t::include_tx_power
*/
advertising_event_properties_t(
bool connectable,
bool scannable,
bool directed,
bool high_duty_cycle,
bool use_legacy_pdu,
bool omit_advertisser_address,
bool include_tx_power
) :
connectable(connectable),
scannable(scannable),
directed(directed),
high_duty_cycle(high_duty_cycle),
use_legacy_pdu(use_legacy_pdu),
omit_advertiser_address(omit_advertisser_address),
include_tx_power(include_tx_power)
{
}
/**
* Construct an advertising_event_property_t from a legacy advertising_type_t.
*
* @param adv_type The legacy advertising type to convert into an
* advertising_event_properties_t.
*
* @note Conversion table can be found in table 7.2 of BLUETOOTH
* SPECIFICATION Version 5.0 | Vol 2, Part E - 7.8.53 .
*/
advertising_event_properties_t(advertising_type_t adv_type) :
connectable(false),
scannable(false),
directed(false),
high_duty_cycle(false),
use_legacy_pdu(true),
omit_advertiser_address(false),
include_tx_power(false)
{
switch (adv_type.value()) {
case advertising_type_t::ADV_IND:
connectable = true;
scannable = true;
break;
case advertising_type_t::ADV_DIRECT_IND:
connectable = true;
directed = true;
high_duty_cycle = true;
break;
case advertising_type_t::ADV_DIRECT_IND_LOW_DUTY_CYCLE:
connectable = true;
directed = true;
use_legacy_pdu = true;
break;
case advertising_type_t::ADV_SCAN_IND:
scannable = true;
break;
case advertising_type_t::ADV_NONCONN_IND:
break;
}
}
/**
* If set the advertising event is connectable.
*/
bool connectable :1;
/**
* If set the advertising event is scannable.
*/
bool scannable :1;
/**
* If set the advertising event targets a specific device.
*/
bool directed :1;
/**
* If set the directed advertising event operate at a high duty cycle.
*/
bool high_duty_cycle :1;
/**
* If set advertising packets use legacy advertising PDU format and the
* members omit_advertisser_address and include_tx_power are ignored.
* If not set then:
* - The advertisement can't be both connectable and scannable.
* - High duty cycle directed connectable advertising can't be use.
*/
bool use_legacy_pdu :1;
/**
* If set omit the advertiser address in all PDUs.
*/
bool omit_advertiser_address :1;
/**
* If set include the Tx power in the extended advertising header.
*/
bool include_tx_power :1;
/**
* Construct the value expected by a BT controller.
* @return All fields in a uint16_t understandable by BT stacks.
*/
uint16_t value()
{
uint16_t result = 0;
result |= connectable << 0;
result |= scannable << 1;
result |= directed << 2;
result |= high_duty_cycle << 3;
result |= use_legacy_pdu << 4;
result |= omit_advertiser_address << 5;
result |= include_tx_power << 6;
return result;
}
};
/**
* Describe advertising interval for undirected and low duty cycle directed
* advertising.
*
* The value is not expressed in seconds; one unit is equal to 0.625ms.
*
* The value range is comprised between 0x20 and 0xFFFFFF which translate into
* 20ms to 10,485.759375s .
*/
typedef uint32_t advertising_interval_t;
/**
* Describe the advertising power.
*
* Value comprised between -127 and +126 are considered power values in dBm while
* the special value 127 can be used as a wildcard to indicates that the host
* has no preference or if the power information is not available.
*/
typedef int8_t advertising_power_t;
/**
* Describe advertising interval for periodic advertising
*
* The value is not expressed in seconds; one unit is equal to 1.25ms.
*
* The value range is comprised between 0x6 and 0xFFFF which translate into
* 7.5ms to 81.91875 s .
*/
typedef uint16_t periodic_advertising_interval_t;
// Range -127 <= N <= +20
// Special value: 127
// - RSSI not available.
typedef ble::rssi_t rssi_t;
/**
* Description of an advertising fragment.
*/
struct advertising_fragment_description_t :
SafeEnum<advertising_fragment_description_t, uint8_t> {
enum type { enum type {
MASTER, /**
SLAVE * Intermediate fragment of fragmented extended advertising data.
*/
INTERMEDIATE_FRAGMENT = 0x00,
/**
* First fragment of fragmented extended advertising data.
*
* @note If use, it discard existing fragments.
*/
FIRST_FRAGMENT = 0x01,
/**
* Last fragment of fragmented extended advertising data.
*/
LAST_FRAGMENT = 0x02,
/**
* Complete extended advertising data. This is also used for legacy
* advertising data.
*
* @note If use, it discard existing fragments.
*/
COMPLETE_FRAGMENT = 0x03,
/**
* Used to update the advertising DID.
*
* @note should not be used if advertising is disabled o
*/
UNCHANGED_DATA = 0x04
}; };
connection_role_t(type value) : SafeEnum<connection_role_t, uint8_t>(value) { } /**
* Construct a new advertising_fragment_description_t value.
*/
advertising_fragment_description_t(type value) :
SafeEnum<advertising_fragment_description_t, uint8_t>(value)
{
}
}; };
typedef ble::duplicates_filter_t duplicates_filter_t;
/**
* Identify a periodic advertising sync.
*/
typedef ble::periodic_sync_handle_t sync_handle_t;
typedef ble::advertising_data_status_t advertising_data_status_t;
struct direct_address_type_t : SafeEnum<direct_address_type_t, uint8_t> {
enum type {
/**
* Public device address
*/
PUBLIC_ADDRESS = 0x00,
/**
* Random device address
*/
RANDOM_ADDRESS = 0x01,
/**
* Public identity address.
* @note remove once privacy mode is supported.
*/
PUBLIC_IDENTITY_ADDRESS = 0x02,
/**
* Random (static) identity address.
* @note remove once privacy mode is supported.
*/
RANDOM_IDENTITY_ADDRESS = 0x03,
/**
* Random device address; controller unable to resolve.
*/
RANDOM_DEVICE_ADDRESS = 0xFE
};
/**
* Construct a new direct_address_type_t instance.
*/
direct_address_type_t(type value) :
SafeEnum<direct_address_type_t, uint8_t>(value)
{
}
explicit direct_address_type_t(uint8_t raw_value) : SafeEnum(raw_value)
{
}
};
typedef ble::clock_accuracy_t clock_accuracy_t;
} // namespace pal } // namespace pal
} // namespace ble } // namespace ble

File diff suppressed because it is too large Load Diff

View File

@ -39,11 +39,16 @@ extern const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID];
extern const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)]; extern const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)];
/** /**
* @class URIBeaconConfigService * @class URIBeaconConfigService
* @brief UriBeacon Configuration Service. Can be used to set URL, adjust power levels, and set flags. * @brief UriBeacon Configuration Service. You can use this to set URL, adjust power levels and set flags.
* See http://uribeacon.org * See http://uribeacon.org
* *
*/ * @deprecated This service is deprecated, and no replacement is currently available.
*/
MBED_DEPRECATED_SINCE(
"mbed-os-5.11",
"This service is deprecated, and no replacement is currently available."
)
class URIBeaconConfigService { class URIBeaconConfigService {
public: public:
/** /**
@ -89,7 +94,13 @@ class URIBeaconConfigService {
* Default un-encoded URI. Applies only if the resetToDefaultsFlag is true. * Default un-encoded URI. Applies only if the resetToDefaultsFlag is true.
* @param[in] defaultAdvPowerLevelsIn * @param[in] defaultAdvPowerLevelsIn
* Default power-levels array. Applies only if the resetToDefaultsFlag is true. * Default power-levels array. Applies only if the resetToDefaultsFlag is true.
*
* @deprecated This service is deprecated, and no replacement is currently available.
*/ */
MBED_DEPRECATED_SINCE(
"mbed-os-5.11",
"This service is deprecated, and no replacement is currently available."
)
URIBeaconConfigService(BLE &bleIn, URIBeaconConfigService(BLE &bleIn,
Params_t &paramsIn, Params_t &paramsIn,
bool resetToDefaultsFlag, bool resetToDefaultsFlag,

View File

@ -81,7 +81,13 @@
* The licence also grant access to the iBeacons technical specification. * The licence also grant access to the iBeacons technical specification.
* *
* @note More information at https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf * @note More information at https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf
*
* @deprecated This service is deprecated, and no replacement is currently available.
*/ */
MBED_DEPRECATED_SINCE(
"mbed-os-5.11",
"This service is deprecated, and no replacement is currently available."
)
class iBeacon class iBeacon
{ {
public: public:
@ -197,7 +203,13 @@ public:
* to the beacon. * to the beacon.
* *
* @param[in] compID ID of the beacon manufacturer. * @param[in] compID ID of the beacon manufacturer.
*
* @deprecated This service is deprecated, and no replacement is currently available.
*/ */
MBED_DEPRECATED_SINCE(
"mbed-os-5.11",
"This service is deprecated, and no replacement is currently available."
)
iBeacon( iBeacon(
BLE &_ble, BLE &_ble,
LocationUUID_t uuid, LocationUUID_t uuid,

View File

@ -383,5 +383,133 @@ ble_error_t BLE::disconnect(Gap::DisconnectionReason_t reason) {
return gap().disconnect(reason); return gap().disconnect(reason);
} }
Gap::GapState_t BLE::getGapState(void) const {
return gap().getState();
}
void BLE::setAdvertisingType(GapAdvertisingParams::AdvertisingType advType) {
gap().setAdvertisingType(advType);
}
void BLE::setAdvertisingInterval(uint16_t interval) {
gap().setAdvertisingInterval(interval);
}
void BLE::setAdvertisingTimeout(uint16_t timeout) {
gap().setAdvertisingTimeout(timeout);
}
void BLE::setAdvertisingParams(const GapAdvertisingParams &advParams) {
gap().setAdvertisingParams(advParams);
}
const GapAdvertisingParams &BLE::getAdvertisingParams(void) const {
return gap().getAdvertisingParams();
}
ble_error_t BLE::accumulateAdvertisingPayload(uint8_t flags) {
return gap().accumulateAdvertisingPayload(flags);
}
ble_error_t BLE::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app) {
return gap().accumulateAdvertisingPayload(app);
}
ble_error_t BLE::accumulateAdvertisingPayloadTxPower(int8_t power) {
return gap().accumulateAdvertisingPayloadTxPower(power);
}
ble_error_t BLE::accumulateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
return gap().accumulateAdvertisingPayload(type, data, len);
}
ble_error_t BLE::setAdvertisingData(const GapAdvertisingData &advData) {
return gap().setAdvertisingPayload(advData);
}
const GapAdvertisingData &BLE::getAdvertisingData(void) const {
return gap().getAdvertisingPayload();
}
void BLE::clearAdvertisingPayload(void) {
gap().clearAdvertisingPayload();
}
ble_error_t BLE::setAdvertisingPayload(void) {
return BLE_ERROR_NONE;
}
ble_error_t BLE::accumulateScanResponse(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
return gap().accumulateScanResponse(type, data, len);
}
void BLE::clearScanResponse(void) {
gap().clearScanResponse();
}
ble_error_t BLE::startAdvertising(void) {
return gap().startAdvertising();
}
ble_error_t BLE::stopAdvertising(void) {
return gap().stopAdvertising();
}
ble_error_t BLE::setScanParams(uint16_t interval,
uint16_t window,
uint16_t timeout,
bool activeScanning) {
return gap().setScanParams(interval, window, timeout, activeScanning);
}
ble_error_t BLE::setScanInterval(uint16_t interval) {
return gap().setScanInterval(interval);
}
ble_error_t BLE::setScanWindow(uint16_t window) {
return gap().setScanWindow(window);
}
ble_error_t BLE::setScanTimeout(uint16_t timeout) {
return gap().setScanTimeout(timeout);
}
void BLE::setActiveScan(bool activeScanning) {
gap().setActiveScanning(activeScanning);
}
ble_error_t BLE::startScan(void (*callback)(const Gap::AdvertisementCallbackParams_t *params)) {
return gap().startScan(callback);
}
ble_error_t BLE::disconnect(Gap::Handle_t connectionHandle, Gap::DisconnectionReason_t reason) {
return gap().disconnect(connectionHandle, reason);
}
ble_error_t BLE::updateConnectionParams(Gap::Handle_t handle, const Gap::ConnectionParams_t *params) {
return gap().updateConnectionParams(handle, params);
}
ble_error_t BLE::setTxPower(int8_t txPower) {
return gap().setTxPower(txPower);
}
void BLE::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
gap().getPermittedTxPowerValues(valueArrayPP, countP);
}
void BLE::onTimeout(Gap::TimeoutEventCallback_t timeoutCallback) {
gap().onTimeout(timeoutCallback);
}
void BLE::onDisconnection(Gap::DisconnectionEventCallback_t disconnectionCallback) {
gap().onDisconnection(disconnectionCallback);
}
void BLE::onRadioNotification(void (*callback)(bool)) {
gap().onRadioNotification(callback);
}
BLE_DEPRECATED_API_USE_END BLE_DEPRECATED_API_USE_END

View File

@ -1,344 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ble/Gap.h"
namespace {
ble_error_t convert_address_type(
Gap::PeerAddressType_t input_type,
const BLEProtocol::AddressBytes_t address,
BLEProtocol::AddressType_t& output_type
) {
typedef Gap::RandomAddressType_t RandomAddressType_t;
typedef Gap::PeerAddressType_t PeerAddressType_t;
typedef BLEProtocol::AddressType LegacyAddressType_t;
// best effort; peerAddrTypeIn should not be used when privacy is on.
switch(input_type.value()) {
case PeerAddressType_t::PUBLIC:
case PeerAddressType_t::PUBLIC_IDENTITY:
output_type = LegacyAddressType_t::PUBLIC;
break;
case PeerAddressType_t::RANDOM: {
RandomAddressType_t random_address_type(RandomAddressType_t::STATIC);
ble_error_t err = Gap::getRandomAddressType(address, &random_address_type);
if (err) {
return err;
}
switch (random_address_type.value()) {
case RandomAddressType_t::STATIC:
output_type = LegacyAddressType_t::RANDOM_STATIC;
break;
case RandomAddressType_t::NON_RESOLVABLE_PRIVATE:
output_type = LegacyAddressType_t::RANDOM_PRIVATE_NON_RESOLVABLE;
break;
case RandomAddressType_t::RESOLVABLE_PRIVATE:
output_type = LegacyAddressType_t::RANDOM_PRIVATE_RESOLVABLE;
break;
}
break;
}
case PeerAddressType_t::RANDOM_STATIC_IDENTITY:
output_type = LegacyAddressType_t::RANDOM_STATIC;
break;
}
return BLE_ERROR_NONE;
}
Gap::PeerAddressType_t convert_legacy_address_type(
BLEProtocol::AddressType_t legacy_address
) {
if (legacy_address == BLEProtocol::AddressType::PUBLIC) {
return Gap::PeerAddressType_t::PUBLIC;
} else {
return Gap::PeerAddressType_t::RANDOM;
}
}
}
const Gap::PeripheralPrivacyConfiguration_t Gap::default_peripheral_privacy_configuration = {
/* use_non_resolvable_random_address */ false,
/* resolution_strategy */ PeripheralPrivacyConfiguration_t::PERFORM_PAIRING_PROCEDURE
};
const Gap::CentralPrivacyConfiguration_t Gap::default_central_privacy_configuration = {
/* use_non_resolvable_random_address */ false,
/* resolution_strategy */ CentralPrivacyConfiguration_t::RESOLVE_AND_FORWARD
};
void Gap::processConnectionEvent(
Handle_t handle,
Role_t role,
PeerAddressType_t peerAddrType,
const BLEProtocol::AddressBytes_t peerAddr,
BLEProtocol::AddressType_t ownAddrType,
const BLEProtocol::AddressBytes_t ownAddr,
const ConnectionParams_t *connectionParams,
const uint8_t *peerResolvableAddr,
const uint8_t *localResolvableAddr
) {
/* Update Gap state */
state.advertising = 0;
state.connected = 1;
++connectionCount;
ConnectionCallbackParams_t callbackParams(
handle,
role,
peerAddrType,
peerAddr,
ownAddrType,
ownAddr,
connectionParams,
peerResolvableAddr,
localResolvableAddr
);
connectionCallChain.call(&callbackParams);
}
void Gap::processAdvertisementReport(
const BLEProtocol::AddressBytes_t peerAddr,
int8_t rssi,
bool isScanResponse,
GapAdvertisingParams::AdvertisingType_t type,
uint8_t advertisingDataLen,
const uint8_t *advertisingData,
PeerAddressType_t addressType
) {
AdvertisementCallbackParams_t params;
memcpy(params.peerAddr, peerAddr, ADDR_LEN);
params.rssi = rssi;
params.isScanResponse = isScanResponse;
params.type = type;
params.advertisingDataLen = advertisingDataLen;
params.advertisingData = advertisingData;
params.peerAddrType = addressType;
convert_address_type(
addressType,
peerAddr,
params.addressType
);
onAdvertisementReport.call(&params);
}
#if defined(__GNUC__) && !defined(__CC_ARM)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__CC_ARM)
#pragma push
#pragma diag_suppress 1361
#endif
Gap::AdvertisementCallbackParams_t::AdvertisementCallbackParams_t() :
peerAddr(),
rssi(),
isScanResponse(),
type(),
advertisingDataLen(0),
advertisingData(NULL),
addressType(),
peerAddrType(PeerAddressType_t::PUBLIC)
{
}
ble_error_t Gap::getRandomAddressType(
const BLEProtocol::AddressBytes_t address,
RandomAddressType_t* type
) {
// see section Device address in Bluetooth Link Layer specification
// (Vol 6 - Part B)
switch (address[5] >> 6) {
case 0x03:
*type = RandomAddressType_t::STATIC;
return BLE_ERROR_NONE;
case 0x00:
*type = RandomAddressType_t::NON_RESOLVABLE_PRIVATE;
return BLE_ERROR_NONE;
case 0x01:
*type = RandomAddressType_t::RESOLVABLE_PRIVATE;
return BLE_ERROR_NONE;
default:
return BLE_ERROR_INVALID_PARAM;
}
}
Gap::ConnectionCallbackParams_t::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,
const uint8_t *peerResolvableAddrIn,
const uint8_t *localResolvableAddrIn
) : handle(handleIn),
role(roleIn),
peerAddrType(peerAddrTypeIn),
peerAddr(),
ownAddrType(ownAddrTypeIn),
ownAddr(),
connectionParams(connectionParamsIn),
peerResolvableAddr(),
localResolvableAddr(),
peerAddressType(convert_legacy_address_type(peerAddrTypeIn))
{
constructor_helper(
peerAddrIn,
ownAddrIn,
peerResolvableAddrIn,
localResolvableAddrIn
);
}
Gap::ConnectionCallbackParams_t::ConnectionCallbackParams_t(
Handle_t handleIn,
Role_t roleIn,
PeerAddressType_t peerAddrTypeIn,
const uint8_t *peerAddrIn,
BLEProtocol::AddressType_t ownAddrTypeIn,
const uint8_t *ownAddrIn,
const ConnectionParams_t *connectionParamsIn,
const uint8_t *peerResolvableAddrIn,
const uint8_t *localResolvableAddrIn
) : handle(handleIn),
role(roleIn),
peerAddrType(),
peerAddr(),
ownAddrType(ownAddrTypeIn),
ownAddr(),
connectionParams(connectionParamsIn),
peerResolvableAddr(),
localResolvableAddr(),
peerAddressType(peerAddrTypeIn)
{
constructor_helper(
peerAddrIn,
ownAddrIn,
peerResolvableAddrIn,
localResolvableAddrIn
);
convert_address_type(peerAddrTypeIn, peerAddrIn, peerAddrType);
}
void Gap::ConnectionCallbackParams_t::constructor_helper(
const uint8_t *peerAddrIn,
const uint8_t *ownAddrIn,
const uint8_t *peerResolvableAddrIn,
const uint8_t *localResolvableAddrIn
) {
memcpy(peerAddr, peerAddrIn, ADDR_LEN);
if (ownAddrIn) {
memcpy(ownAddr, ownAddrIn, ADDR_LEN);
} else {
memset(ownAddr, 0, ADDR_LEN);
}
if (peerResolvableAddrIn) {
memcpy(peerResolvableAddr, peerResolvableAddrIn, ADDR_LEN);
} else {
memset(ownAddr, 0, ADDR_LEN);
}
if (localResolvableAddrIn) {
memcpy(localResolvableAddr, localResolvableAddrIn, ADDR_LEN);
} else {
memset(ownAddr, 0, ADDR_LEN);
}
}
ble_error_t Gap::connect(
const BLEProtocol::AddressBytes_t peerAddr,
DeprecatedAddressType_t peerAddrType,
const ConnectionParams_t *connectionParams,
const GapScanningParams *scanParams
) {
return connect(
peerAddr,
(BLEProtocol::AddressType_t) peerAddrType,
connectionParams,
scanParams
);
}
void Gap::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,
const uint8_t *peerResolvableAddr,
const uint8_t *localResolvableAddr
) {
/* Update Gap state */
state.advertising = 0;
state.connected = 1;
++connectionCount;
ConnectionCallbackParams_t callbackParams(
handle,
role,
peerAddrType,
peerAddr,
ownAddrType,
ownAddr,
connectionParams,
peerResolvableAddr,
localResolvableAddr
);
connectionCallChain.call(&callbackParams);
}
void Gap::processAdvertisementReport(
const BLEProtocol::AddressBytes_t peerAddr,
int8_t rssi,
bool isScanResponse,
GapAdvertisingParams::AdvertisingType_t type,
uint8_t advertisingDataLen,
const uint8_t *advertisingData,
BLEProtocol::AddressType_t addressType
) {
AdvertisementCallbackParams_t params;
memcpy(params.peerAddr, peerAddr, ADDR_LEN);
params.rssi = rssi;
params.isScanResponse = isScanResponse;
params.type = type;
params.advertisingDataLen = advertisingDataLen;
params.advertisingData = advertisingData;
params.addressType = addressType;
params.peerAddrType = convert_legacy_address_type(addressType);
onAdvertisementReport.call(&params);
}
#if defined(__GNUC__) && !defined(__CC_ARM)
#pragma GCC diagnostic pop
#elif defined(__CC_ARM)
#pragma pop
#endif

View File

@ -0,0 +1,827 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ble/Gap.h"
namespace {
ble_error_t convert_address_type(
Gap::PeerAddressType_t input_type,
const BLEProtocol::AddressBytes_t address,
BLEProtocol::AddressType_t& output_type
) {
typedef Gap::RandomAddressType_t RandomAddressType_t;
typedef Gap::PeerAddressType_t PeerAddressType_t;
typedef BLEProtocol::AddressType LegacyAddressType_t;
// best effort; peerAddrTypeIn should not be used when privacy is on.
switch(input_type.value()) {
case PeerAddressType_t::PUBLIC:
case PeerAddressType_t::PUBLIC_IDENTITY:
output_type = LegacyAddressType_t::PUBLIC;
break;
case PeerAddressType_t::RANDOM: {
RandomAddressType_t random_address_type(RandomAddressType_t::STATIC);
ble_error_t err = Gap::getRandomAddressType(address, &random_address_type);
if (err) {
return err;
}
switch (random_address_type.value()) {
case RandomAddressType_t::STATIC:
output_type = LegacyAddressType_t::RANDOM_STATIC;
break;
case RandomAddressType_t::NON_RESOLVABLE_PRIVATE:
output_type = LegacyAddressType_t::RANDOM_PRIVATE_NON_RESOLVABLE;
break;
case RandomAddressType_t::RESOLVABLE_PRIVATE:
output_type = LegacyAddressType_t::RANDOM_PRIVATE_RESOLVABLE;
break;
}
break;
}
case PeerAddressType_t::RANDOM_STATIC_IDENTITY:
output_type = LegacyAddressType_t::RANDOM_STATIC;
break;
}
return BLE_ERROR_NONE;
}
Gap::PeerAddressType_t convert_legacy_address_type(
BLEProtocol::AddressType_t legacy_address
) {
if (legacy_address == BLEProtocol::AddressType::PUBLIC) {
return Gap::PeerAddressType_t::PUBLIC;
} else {
return Gap::PeerAddressType_t::RANDOM;
}
}
} // end of anonymous namespace
uint8_t Gap::getMaxWhitelistSize(void) const
{
return 0;
}
ble_error_t Gap::getWhitelist(Whitelist_t &whitelist) const
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setWhitelist(const Whitelist_t &whitelist)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
void Gap::processConnectionEvent(
Handle_t handle,
Role_t role,
PeerAddressType_t peerAddrType,
const BLEProtocol::AddressBytes_t peerAddr,
BLEProtocol::AddressType_t ownAddrType,
const BLEProtocol::AddressBytes_t ownAddr,
const ConnectionParams_t *connectionParams,
const uint8_t *peerResolvableAddr,
const uint8_t *localResolvableAddr
) {
/* Update Gap state */
state.advertising = 0;
state.connected = 1;
++connectionCount;
ConnectionCallbackParams_t callbackParams(
handle,
role,
peerAddrType,
peerAddr,
ownAddrType,
ownAddr,
connectionParams,
peerResolvableAddr,
localResolvableAddr
);
connectionCallChain.call(&callbackParams);
}
ble_error_t Gap::setAddress(
BLEProtocol::AddressType_t type,
const BLEProtocol::AddressBytes_t address
) {
/* avoid compiler warnings about unused variables */
(void)type;
(void)address;
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::getAddress(
BLEProtocol::AddressType_t *typeP,
BLEProtocol::AddressBytes_t address
) {
/* Avoid compiler warnings about unused variables. */
(void)typeP;
(void)address;
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::stopAdvertising(void)
{
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::connect(
const BLEProtocol::AddressBytes_t peerAddr,
PeerAddressType_t peerAddrType,
const ConnectionParams_t *connectionParams,
const GapScanningParams *scanParams
) {
/* Avoid compiler warnings about unused variables. */
(void)peerAddr;
(void)peerAddrType;
(void)connectionParams;
(void)scanParams;
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::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;
(void)connectionParams;
(void)scanParams;
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::disconnect(
Handle_t connectionHandle, DisconnectionReason_t reason
) {
/* avoid compiler warnings about unused variables */
(void)connectionHandle;
(void)reason;
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::disconnect(DisconnectionReason_t reason) {
/* Avoid compiler warnings about unused variables. */
(void)reason;
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::updateConnectionParams(
Handle_t handle,
const ConnectionParams_t *params
) {
/* avoid compiler warnings about unused variables */
(void)handle;
(void)params;
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setTxPower(int8_t txPower)
{
/* Avoid compiler warnings about unused variables. */
(void)txPower;
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
void Gap::getPermittedTxPowerValues(
const int8_t **valueArrayPP, size_t *countP
) {
/* Avoid compiler warnings about unused variables. */
(void)valueArrayPP;
/* Requesting action from porter(s): override this API if this capability
is supported. */
*countP = 0;
}
ble_error_t Gap::setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode)
{
(void) mode;
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setScanningPolicyMode(ScanningPolicyMode_t mode)
{
(void) mode;
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setInitiatorPolicyMode(InitiatorPolicyMode_t mode)
{
(void) mode;
return BLE_ERROR_NOT_IMPLEMENTED;
}
Gap::AdvertisingPolicyMode_t Gap::getAdvertisingPolicyMode(void) const
{
return ADV_POLICY_IGNORE_WHITELIST;
}
Gap::ScanningPolicyMode_t Gap::getScanningPolicyMode(void) const
{
return SCAN_POLICY_IGNORE_WHITELIST;
}
Gap::InitiatorPolicyMode_t Gap::getInitiatorPolicyMode(void) const
{
return INIT_POLICY_IGNORE_WHITELIST;
}
ble_error_t Gap::startRadioScan(const GapScanningParams &scanningParams)
{
(void)scanningParams;
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::initRadioNotification(void)
{
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
#if defined(__GNUC__) && !defined(__CC_ARM)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__CC_ARM)
#pragma push
#pragma diag_suppress 1361
#endif
Gap::GapState_t Gap::getState(void) const
{
return state;
}
void Gap::setAdvertisingType(GapAdvertisingParams::AdvertisingType_t advType)
{
_advParams.setAdvertisingType(advType);
}
void Gap::setAdvertisingInterval(uint16_t interval)
{
if (interval == 0) {
stopAdvertising();
} else if (interval < getMinAdvertisingInterval()) {
interval = getMinAdvertisingInterval();
}
_advParams.setInterval(interval);
}
void Gap::setAdvertisingTimeout(uint16_t timeout)
{
_advParams.setTimeout(timeout);
}
ble_error_t Gap::startAdvertising(void)
{
ble_error_t rc;
if ((rc = startAdvertising(_advParams)) == BLE_ERROR_NONE) {
state.advertising = 1;
}
return rc;
}
void Gap::clearAdvertisingPayload(void)
{
_advPayload.clear();
setAdvertisingData(_advPayload, _scanResponse);
}
ble_error_t Gap::accumulateAdvertisingPayload(uint8_t flags)
{
GapAdvertisingData advPayloadCopy = _advPayload;
ble_error_t rc;
if ((rc = advPayloadCopy.addFlags(flags)) != BLE_ERROR_NONE) {
return rc;
}
rc = setAdvertisingData(advPayloadCopy, _scanResponse);
if (rc == BLE_ERROR_NONE) {
_advPayload = advPayloadCopy;
}
return rc;
}
ble_error_t Gap::accumulateAdvertisingPayload(GapAdvertisingData::Appearance app)
{
GapAdvertisingData advPayloadCopy = _advPayload;
ble_error_t rc;
if ((rc = advPayloadCopy.addAppearance(app)) != BLE_ERROR_NONE) {
return rc;
}
rc = setAdvertisingData(advPayloadCopy, _scanResponse);
if (rc == BLE_ERROR_NONE) {
_advPayload = advPayloadCopy;
}
return rc;
}
ble_error_t Gap::accumulateAdvertisingPayloadTxPower(int8_t power)
{
GapAdvertisingData advPayloadCopy = _advPayload;
ble_error_t rc;
if ((rc = advPayloadCopy.addTxPower(power)) != BLE_ERROR_NONE) {
return rc;
}
rc = setAdvertisingData(advPayloadCopy, _scanResponse);
if (rc == BLE_ERROR_NONE) {
_advPayload = advPayloadCopy;
}
return rc;
}
ble_error_t Gap::accumulateAdvertisingPayload(
GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len
) {
GapAdvertisingData advPayloadCopy = _advPayload;
ble_error_t rc;
if ((rc = advPayloadCopy.addData(type, data, len)) != BLE_ERROR_NONE) {
return rc;
}
rc = setAdvertisingData(advPayloadCopy, _scanResponse);
if (rc == BLE_ERROR_NONE) {
_advPayload = advPayloadCopy;
}
return rc;
}
ble_error_t Gap::updateAdvertisingPayload(
GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len
) {
GapAdvertisingData advPayloadCopy = _advPayload;
ble_error_t rc;
if ((rc = advPayloadCopy.updateData(type, data, len)) != BLE_ERROR_NONE) {
return rc;
}
rc = setAdvertisingData(advPayloadCopy, _scanResponse);
if (rc == BLE_ERROR_NONE) {
_advPayload = advPayloadCopy;
}
return rc;
}
ble_error_t Gap::setAdvertisingPayload(const GapAdvertisingData &payload)
{
ble_error_t rc = setAdvertisingData(payload, _scanResponse);
if (rc == BLE_ERROR_NONE) {
_advPayload = payload;
}
return rc;
}
const GapAdvertisingData &Gap::getAdvertisingPayload(void) const
{
return _advPayload;
}
ble_error_t Gap::accumulateScanResponse(
GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len
) {
GapAdvertisingData scanResponseCopy = _scanResponse;
ble_error_t rc;
if ((rc = scanResponseCopy.addData(type, data, len)) != BLE_ERROR_NONE) {
return rc;
}
rc = setAdvertisingData(_advPayload, scanResponseCopy);
if (rc == BLE_ERROR_NONE) {
_scanResponse = scanResponseCopy;
}
return rc;
}
void Gap::clearScanResponse(void)
{
_scanResponse.clear();
setAdvertisingData(_advPayload, _scanResponse);
}
ble_error_t Gap::setScanParams(
uint16_t interval,
uint16_t window,
uint16_t timeout,
bool activeScanning
) {
ble_error_t rc;
if (((rc = _scanningParams.setInterval(interval)) == BLE_ERROR_NONE) &&
((rc = _scanningParams.setWindow(window)) == BLE_ERROR_NONE) &&
((rc = _scanningParams.setTimeout(timeout)) == BLE_ERROR_NONE)) {
_scanningParams.setActiveScanning(activeScanning);
return BLE_ERROR_NONE;
}
return rc;
}
ble_error_t Gap::setScanParams(const GapScanningParams& scanningParams) {
return setScanParams(
scanningParams.getInterval(),
scanningParams.getWindow(),
scanningParams.getTimeout(),
scanningParams.getActiveScanning()
);
}
ble_error_t Gap::setScanInterval(uint16_t interval)
{
return _scanningParams.setInterval(interval);
}
ble_error_t Gap::setScanWindow(uint16_t window)
{
ble_error_t rc;
if ((rc = _scanningParams.setWindow(window)) != BLE_ERROR_NONE) {
return rc;
}
/* If scanning is already active, propagate the new setting to the stack. */
if (scanningActive) {
return startRadioScan(_scanningParams);
}
return BLE_ERROR_NONE;
}
ble_error_t Gap::setScanTimeout(uint16_t timeout)
{
ble_error_t rc;
if ((rc = _scanningParams.setTimeout(timeout)) != BLE_ERROR_NONE) {
return rc;
}
/* If scanning is already active, propagate the new settings to the stack. */
if (scanningActive) {
return startRadioScan(_scanningParams);
}
return BLE_ERROR_NONE;
}
ble_error_t Gap::setActiveScanning(bool activeScanning)
{
_scanningParams.setActiveScanning(activeScanning);
/* If scanning is already active, propagate the new settings to the stack. */
if (scanningActive) {
return startRadioScan(_scanningParams);
}
return BLE_ERROR_NONE;
}
ble_error_t Gap::startScan(
void (*callback)(const AdvertisementCallbackParams_t *params)
) {
ble_error_t err = BLE_ERROR_NONE;
if (callback) {
if ((err = startRadioScan(_scanningParams)) == BLE_ERROR_NONE) {
scanningActive = true;
onAdvertisementReport.attach(callback);
}
}
return err;
}
GapAdvertisingParams &Gap::getAdvertisingParams(void)
{
return _advParams;
}
const GapAdvertisingParams &Gap::getAdvertisingParams(void) const
{
return _advParams;
}
void Gap::setAdvertisingParams(const GapAdvertisingParams &newParams)
{
_advParams = newParams;
}
void Gap::onTimeout(TimeoutEventCallback_t callback)
{
timeoutCallbackChain.add(callback);
}
Gap::TimeoutEventCallbackChain_t& Gap::onTimeout()
{
return timeoutCallbackChain;
}
void Gap::onConnection(ConnectionEventCallback_t callback)
{
connectionCallChain.add(callback);
}
Gap::ConnectionEventCallbackChain_t& Gap::onConnection()
{
return connectionCallChain;
}
void Gap::onDisconnection(DisconnectionEventCallback_t callback)
{
disconnectionCallChain.add(callback);
}
Gap::DisconnectionEventCallbackChain_t& Gap::onDisconnection()
{
return disconnectionCallChain;
}
void Gap::onRadioNotification(void (*callback)(bool param))
{
radioNotificationCallback.attach(callback);
}
void Gap::onShutdown(const GapShutdownCallback_t& callback)
{
shutdownCallChain.add(callback);
}
Gap::GapShutdownCallbackChain_t& Gap::onShutdown()
{
return shutdownCallChain;
}
Gap::AdvertisementCallbackParams_t::AdvertisementCallbackParams_t() :
peerAddr(),
rssi(),
isScanResponse(),
type(),
advertisingDataLen(0),
advertisingData(NULL),
addressType(),
peerAddrType(PeerAddressType_t::PUBLIC)
{
}
ble_error_t Gap::getRandomAddressType(
const BLEProtocol::AddressBytes_t address,
RandomAddressType_t* type
) {
// see section Device address in Bluetooth Link Layer specification
// (Vol 6 - Part B)
switch (address[5] >> 6) {
case 0x03:
*type = RandomAddressType_t::STATIC;
return BLE_ERROR_NONE;
case 0x00:
*type = RandomAddressType_t::NON_RESOLVABLE_PRIVATE;
return BLE_ERROR_NONE;
case 0x01:
*type = RandomAddressType_t::RESOLVABLE_PRIVATE;
return BLE_ERROR_NONE;
default:
return BLE_ERROR_INVALID_PARAM;
}
}
Gap::ConnectionCallbackParams_t::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,
const uint8_t *peerResolvableAddrIn,
const uint8_t *localResolvableAddrIn
) : handle(handleIn),
role(roleIn),
peerAddrType(peerAddrTypeIn),
peerAddr(),
ownAddrType(ownAddrTypeIn),
ownAddr(),
connectionParams(connectionParamsIn),
peerResolvableAddr(),
localResolvableAddr(),
peerAddressType(convert_legacy_address_type(peerAddrTypeIn))
{
constructor_helper(
peerAddrIn,
ownAddrIn,
peerResolvableAddrIn,
localResolvableAddrIn
);
}
Gap::ConnectionCallbackParams_t::ConnectionCallbackParams_t(
Handle_t handleIn,
Role_t roleIn,
PeerAddressType_t peerAddrTypeIn,
const uint8_t *peerAddrIn,
BLEProtocol::AddressType_t ownAddrTypeIn,
const uint8_t *ownAddrIn,
const ConnectionParams_t *connectionParamsIn,
const uint8_t *peerResolvableAddrIn,
const uint8_t *localResolvableAddrIn
) : handle(handleIn),
role(roleIn),
peerAddrType(),
peerAddr(),
ownAddrType(ownAddrTypeIn),
ownAddr(),
connectionParams(connectionParamsIn),
peerResolvableAddr(),
localResolvableAddr(),
peerAddressType(peerAddrTypeIn)
{
constructor_helper(
peerAddrIn,
ownAddrIn,
peerResolvableAddrIn,
localResolvableAddrIn
);
convert_address_type(peerAddrTypeIn, peerAddrIn, peerAddrType);
}
void Gap::ConnectionCallbackParams_t::constructor_helper(
const uint8_t *peerAddrIn,
const uint8_t *ownAddrIn,
const uint8_t *peerResolvableAddrIn,
const uint8_t *localResolvableAddrIn
) {
memcpy(peerAddr, peerAddrIn, ADDR_LEN);
if (ownAddrIn) {
memcpy(ownAddr, ownAddrIn, ADDR_LEN);
} else {
memset(ownAddr, 0, ADDR_LEN);
}
if (peerResolvableAddrIn) {
memcpy(peerResolvableAddr, peerResolvableAddrIn, ADDR_LEN);
} else {
memset(ownAddr, 0, ADDR_LEN);
}
if (localResolvableAddrIn) {
memcpy(localResolvableAddr, localResolvableAddrIn, ADDR_LEN);
} else {
memset(ownAddr, 0, ADDR_LEN);
}
}
ble_error_t Gap::connect(
const BLEProtocol::AddressBytes_t peerAddr,
DeprecatedAddressType_t peerAddrType,
const ConnectionParams_t *connectionParams,
const GapScanningParams *scanParams
) {
return connect(
peerAddr,
(BLEProtocol::AddressType_t) peerAddrType,
connectionParams,
scanParams
);
}
void Gap::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,
const uint8_t *peerResolvableAddr,
const uint8_t *localResolvableAddr
) {
/* Update Gap state */
state.advertising = 0;
state.connected = 1;
++connectionCount;
ConnectionCallbackParams_t callbackParams(
handle,
role,
peerAddrType,
peerAddr,
ownAddrType,
ownAddr,
connectionParams,
peerResolvableAddr,
localResolvableAddr
);
connectionCallChain.call(&callbackParams);
}
void Gap::processAdvertisementReport(
const BLEProtocol::AddressBytes_t peerAddr,
int8_t rssi,
bool isScanResponse,
GapAdvertisingParams::AdvertisingType_t type,
uint8_t advertisingDataLen,
const uint8_t *advertisingData,
BLEProtocol::AddressType_t addressType
) {
AdvertisementCallbackParams_t params;
memcpy(params.peerAddr, peerAddr, ADDR_LEN);
params.rssi = rssi;
params.isScanResponse = isScanResponse;
params.type = type;
params.advertisingDataLen = advertisingDataLen;
params.advertisingData = advertisingData;
params.addressType = addressType;
params.peerAddrType = convert_legacy_address_type(addressType);
onAdvertisementReport.call(&params);
}
void Gap::processAdvertisementReport(
const BLEProtocol::AddressBytes_t peerAddr,
int8_t rssi,
bool isScanResponse,
GapAdvertisingParams::AdvertisingType_t type,
uint8_t advertisingDataLen,
const uint8_t *advertisingData,
PeerAddressType_t addressType
) {
AdvertisementCallbackParams_t params;
memcpy(params.peerAddr, peerAddr, ADDR_LEN);
params.rssi = rssi;
params.isScanResponse = isScanResponse;
params.type = type;
params.advertisingDataLen = advertisingDataLen;
params.advertisingData = advertisingData;
params.peerAddrType = addressType;
convert_address_type(
addressType,
peerAddr,
params.addressType
);
onAdvertisementReport.call(&params);
}
#if defined(__GNUC__) && !defined(__CC_ARM)
#pragma GCC diagnostic pop
#elif defined(__CC_ARM)
#pragma pop
#endif

View File

@ -0,0 +1,535 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ble/gap/AdvertisingDataBuilder.h"
// Implementation notes
// Advertising data are organized as follow:
// - byte 0: Size of the rest of the field
// - byte 1: type of the field
// - byte 2 to the last byte: field value.
// An advertising data can contain at most a single instance of a field type.
#define FIELD_TYPE_INDEX 1
#define COMPANY_IDENTIFIER_SIZE 2
// A field is represented by a type and a value. The size of the field
// must fit in a byte therefore, the size of DATA cannot be larger than
// 0xFE
#define MAX_DATA_FIELD_SIZE 0xFE
#define FIELD_HEADER_SIZE 2
namespace ble {
namespace {
mbed::Span<const uint8_t> as_span(const int8_t& v) {
return mbed::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(&v), sizeof(v));
}
mbed::Span<const uint8_t> as_span(const uint8_t& v) {
return mbed::Span<const uint8_t>(static_cast<const uint8_t*>(&v), sizeof(v));
}
template<typename Rep, uint32_t TB, typename Range, typename F>
mbed::Span<const uint8_t> as_span(const Duration<Rep, TB, Range, F>& d) {
return mbed::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(d.storage()), sizeof(d.value()));
}
template<typename T, typename Rep>
mbed::Span<const uint8_t> as_span(const SafeEnum<T, Rep>& v) {
return mbed::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(v.storage()), sizeof(v.value()));
}
}
AdvertisingDataBuilder::AdvertisingDataBuilder(mbed::Span<uint8_t> buffer) :
_buffer(buffer),
_payload_length(0)
{
}
AdvertisingDataBuilder::AdvertisingDataBuilder(uint8_t *buffer, size_t buffer_size) :
_buffer(buffer, buffer_size),
_payload_length(0)
{
}
mbed::Span<const uint8_t> AdvertisingDataBuilder::getAdvertisingData() const
{
return _buffer.first(_payload_length);
}
ble_error_t AdvertisingDataBuilder::addData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
)
{
if (findField(advDataType) != NULL) {
return BLE_ERROR_OPERATION_NOT_PERMITTED;
} else {
return addField(advDataType, fieldData);
}
}
ble_error_t AdvertisingDataBuilder::replaceData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
)
{
uint8_t *field = findField(advDataType);
if (field == NULL) {
return BLE_ERROR_NOT_FOUND;
}
return replaceField(advDataType, fieldData, field);
}
ble_error_t AdvertisingDataBuilder::appendData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
)
{
uint8_t *field = findField(advDataType);
if (field == NULL) {
return BLE_ERROR_NOT_FOUND;
}
return appendToField(fieldData, field);
}
ble_error_t AdvertisingDataBuilder::removeData(
adv_data_type_t advDataType
)
{
uint8_t *field = findField(advDataType);
if (field == NULL) {
return BLE_ERROR_NOT_FOUND;
}
return removeField(field);
}
ble_error_t AdvertisingDataBuilder::addOrReplaceData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
)
{
uint8_t *field = findField(advDataType);
if (field != NULL) {
return replaceField(advDataType, fieldData, field);
} else {
return addField(advDataType, fieldData);
}
}
ble_error_t AdvertisingDataBuilder::addOrAppendData(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
)
{
uint8_t *field = findField(advDataType);
if (field != NULL) {
return appendToField(fieldData, field);
} else {
return addField(advDataType, fieldData);
}
}
void AdvertisingDataBuilder::clear()
{
memset(_buffer.data(), 0, _buffer.size());
_payload_length = 0;
}
ble_error_t AdvertisingDataBuilder::setAppearance(
adv_data_appearance_t appearance
)
{
return addOrReplaceData(adv_data_type_t::APPEARANCE, as_span(appearance));
}
ble_error_t AdvertisingDataBuilder::setFlags(adv_data_flags_t flags)
{
uint8_t flags_byte = flags.value();
return addOrReplaceData(adv_data_type_t::FLAGS, as_span(flags_byte));
}
ble_error_t AdvertisingDataBuilder::setTxPowerAdvertised(
advertising_power_t txPower
)
{
return addOrReplaceData(adv_data_type_t::TX_POWER_LEVEL, as_span(txPower));
}
ble_error_t AdvertisingDataBuilder::setName(
const char *name,
bool complete
)
{
mbed::Span<const uint8_t> name_span((const uint8_t *) name, strlen(name));
if (complete) {
return addOrReplaceData(adv_data_type_t::COMPLETE_LOCAL_NAME, name_span);
} else {
return addOrReplaceData(adv_data_type_t::SHORTENED_LOCAL_NAME, name_span);
}
}
ble_error_t AdvertisingDataBuilder::setManufacturerSpecificData(
mbed::Span<const uint8_t> data
)
{
// manufacturer specific data should at least contain the vendor ID.
if (data.size() < COMPANY_IDENTIFIER_SIZE) {
return BLE_ERROR_INVALID_PARAM;
}
return addOrReplaceData(adv_data_type_t::MANUFACTURER_SPECIFIC_DATA, data);
}
ble_error_t AdvertisingDataBuilder::setAdvertisingInterval(
adv_interval_t interval
)
{
// Note: Advertising interval in advertisement MUST be represented in a 16bit
// value.
if (interval.value() > 0xFFFF) {
return BLE_ERROR_INVALID_PARAM;
}
return addOrReplaceData(
adv_data_type_t::ADVERTISING_INTERVAL,
as_span(interval)
);
}
ble_error_t AdvertisingDataBuilder::setConnectionIntervalPreference(
conn_interval_t min,
conn_interval_t max
)
{
uint8_t interval[2 * sizeof(conn_interval_t::representation_t)];
memcpy(interval, max.storage(), sizeof(max.value()));
memcpy(interval + sizeof(max.value()), min.storage(), sizeof(min.value()));
return addOrReplaceData(
adv_data_type_t::SLAVE_CONNECTION_INTERVAL_RANGE,
interval
);
}
ble_error_t AdvertisingDataBuilder::setServiceData(
UUID service,
mbed::Span<const uint8_t> data
)
{
if (service.getLen() + data.size() > MAX_DATA_FIELD_SIZE) {
return BLE_ERROR_INVALID_PARAM;
}
adv_data_type_t short_type = adv_data_type_t::SERVICE_DATA_16BIT_ID;
adv_data_type_t long_type = adv_data_type_t::SERVICE_DATA_128BIT_ID;
size_t total_size = FIELD_HEADER_SIZE + service.getLen() + data.size();
size_t old_size = getFieldSize(
(service.shortOrLong() == UUID::UUID_TYPE_SHORT) ? short_type : long_type
);
/* if we can't fit the new data do not proceed */
if (total_size > data.size() - (_payload_length - old_size)) {
return BLE_ERROR_BUFFER_OVERFLOW;
}
/* this will insert only the UUID (and remove old data) */
ble_error_t status = setUUIDData(
mbed::make_Span(&service, 1),
short_type,
long_type
);
if (status != BLE_ERROR_NONE) {
/* we already checked for size so this must not happen */
return BLE_ERROR_INTERNAL_STACK_FAILURE;
}
status = appendData(
(service.shortOrLong() == UUID::UUID_TYPE_SHORT) ? short_type : long_type,
data
);
if (status != BLE_ERROR_NONE) {
return BLE_ERROR_INTERNAL_STACK_FAILURE;
}
return BLE_ERROR_NONE;
}
ble_error_t AdvertisingDataBuilder::setLocalServiceList(
mbed::Span<const UUID> data,
bool complete
)
{
adv_data_type_t short_type = complete ?
adv_data_type_t::COMPLETE_LIST_16BIT_SERVICE_IDS :
adv_data_type_t::INCOMPLETE_LIST_16BIT_SERVICE_IDS;
adv_data_type_t long_type = complete ?
adv_data_type_t::COMPLETE_LIST_128BIT_SERVICE_IDS :
adv_data_type_t::INCOMPLETE_LIST_128BIT_SERVICE_IDS;
return setUUIDData(data, short_type, long_type);
}
ble_error_t AdvertisingDataBuilder::setRequestedServiceList(
mbed::Span<const UUID> data
)
{
adv_data_type_t short_type = adv_data_type_t::LIST_16BIT_SOLICITATION_IDS;
adv_data_type_t long_type = adv_data_type_t::LIST_128BIT_SOLICITATION_IDS;
return setUUIDData(data, short_type, long_type);
}
ble_error_t AdvertisingDataBuilder::getData(
mbed::Span<const uint8_t> &data,
adv_data_type_t advDataType
)
{
uint8_t *field = findField(advDataType);
if (field) {
uint8_t data_length = field[0] - 1 /* skip type */;
data = mbed::make_Span((const uint8_t *) (field + FIELD_HEADER_SIZE), data_length);
return BLE_ERROR_NONE;
} else {
return BLE_ERROR_NOT_FOUND;
}
}
uint8_t *AdvertisingDataBuilder::findField(adv_data_type_t type)
{
/* Scan through advertisement data */
for (uint8_t idx = 0; idx < _payload_length;) {
uint8_t fieldType = _buffer[idx + FIELD_TYPE_INDEX];
if (fieldType == type) {
return _buffer.data() + idx;
}
/* Advance to next field */
idx += _buffer[idx] + 1;
}
return NULL;
}
uint8_t AdvertisingDataBuilder::getFieldSize(adv_data_type_t type)
{
uint8_t *field = findField(type);
if (field) {
return field[0] + 1 /* field size is not included so we add it */;
} else {
return 0;
}
}
ble_error_t AdvertisingDataBuilder::addField(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData
)
{
if (fieldData.size() > MAX_DATA_FIELD_SIZE) {
return BLE_ERROR_INVALID_PARAM;
}
/* Make sure we don't exceed the buffer size */
if (_payload_length + fieldData.size() + FIELD_HEADER_SIZE > _buffer.size()) {
return BLE_ERROR_BUFFER_OVERFLOW;
}
/* Field length (includes field ID byte) */
_buffer[_payload_length] = fieldData.size() + /* type */ 1;
++_payload_length;
/* Field ID. */
_buffer[_payload_length] = advDataType.value();
++_payload_length;
/* Payload. */
memcpy(&_buffer[_payload_length], fieldData.data(), fieldData.size());
_payload_length += fieldData.size();
return BLE_ERROR_NONE;
}
ble_error_t AdvertisingDataBuilder::appendToField(
mbed::Span<const uint8_t> fieldData,
uint8_t *field
)
{
if (fieldData.size() + field[0] > 0xFF /* field[0] already includes the type byte */) {
return BLE_ERROR_INVALID_PARAM;
}
/* Check if data fits */
if ((_payload_length + fieldData.size()) <= _buffer.size()) {
uint8_t old_data_length = field[0];
/* get the size of bytes in the payload after the field */
size_t remainder_size = _payload_length -
(field - _buffer.data()) - /* length of all data before the field */
(old_data_length + 1) /* length of the old field */;
/* move data after the field to fit new data */
if (remainder_size) {
memmove(
field + old_data_length + 1 + fieldData.size(),
field + old_data_length + 1,
remainder_size
);
}
/* append new data */
memcpy(field + old_data_length + 1, fieldData.data(), fieldData.size());
/* Increment lengths */
field[0] += fieldData.size();
_payload_length += fieldData.size();
return BLE_ERROR_NONE;
} else {
return BLE_ERROR_BUFFER_OVERFLOW;
}
}
ble_error_t AdvertisingDataBuilder::replaceField(
adv_data_type_t advDataType,
mbed::Span<const uint8_t> fieldData,
uint8_t *field
)
{
if (fieldData.size() > MAX_DATA_FIELD_SIZE) {
return BLE_ERROR_INVALID_PARAM;
}
uint8_t old_data_length = field[0] - 1;
/* New data has same length, do in-order replacement */
if (fieldData.size() == old_data_length) {
memcpy(field + 2, fieldData.data(), old_data_length);
return BLE_ERROR_NONE;
} else {
/* Check if data fits */
if ((_payload_length - old_data_length + fieldData.size()) <= _buffer.size()) {
removeField(field);
/* Add new field */
return addField(advDataType, fieldData);
} else {
return BLE_ERROR_BUFFER_OVERFLOW;
}
}
}
ble_error_t AdvertisingDataBuilder::removeField(uint8_t *field)
{
/* stored length + the byte containing length */
uint8_t old_field_length = field[0] + 1;
memmove(field, field + old_field_length, old_field_length);
_payload_length -= old_field_length;
return BLE_ERROR_NONE;
}
ble_error_t AdvertisingDataBuilder::setUUIDData(
mbed::Span<const UUID> data,
adv_data_type_t shortType,
adv_data_type_t longType
)
{
ble_error_t status = BLE_ERROR_NONE;
/* first count all the bytes we need to store all the UUIDs */
size_t size_long = 0;
size_t size_short = 0;
for (size_t i = 0, end = data.size(); i < end; ++i) {
if (data[i].shortOrLong() == UUID::UUID_TYPE_SHORT) {
size_short += data[i].getLen();
} else {
size_long += data[i].getLen();
}
}
if ((size_long > MAX_DATA_FIELD_SIZE) || (size_short > MAX_DATA_FIELD_SIZE)) {
return BLE_ERROR_INVALID_PARAM;
}
/* UUID data consists of a type byte, size byte and the list UUIDs itself, we include
* the header (type and size bytes) size only if the size of the UUIDs is non-zero
* (!!non_zero_variable) == 1 */
size_t long_uuid_data_size = (!!size_long) * FIELD_HEADER_SIZE + size_long;
size_t short_uuid_data_size = (!!size_short) * FIELD_HEADER_SIZE + size_short;
size_t new_size = long_uuid_data_size + short_uuid_data_size;
/* count all the bytes of existing data */
size_t old_size = getFieldSize(shortType) + getFieldSize(longType);
/* if we can't fit the new data do not proceed */
if (new_size > data.size() - (_payload_length - old_size)) {
return BLE_ERROR_BUFFER_OVERFLOW;
}
/* otherwise wipe old data */
removeData(shortType);
removeData(longType);
/* and insert individual UUIDs into appropriate fields */
for (size_t i = 0, end = data.size(); i < end; ++i) {
adv_data_type_t field_type = (data[i].shortOrLong() == UUID::UUID_TYPE_SHORT) ? shortType : longType;
mbed::Span<const uint8_t> span(data[i].getBaseUUID(), data[i].getLen());
uint8_t *field = findField(field_type);
if (field) {
status = appendToField(span, field);
if (status != BLE_ERROR_NONE) {
/* we already checked for size so this must not happen */
return BLE_ERROR_INTERNAL_STACK_FAILURE;
}
} else {
status = addField(field_type, span);
if (status != BLE_ERROR_NONE) {
/* we already checked for size so this must not happen */
return BLE_ERROR_INTERNAL_STACK_FAILURE;
}
}
}
return status;
}
} // end of namespace ble

View File

@ -0,0 +1,25 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ble/gap/AdvertisingParameters.h"
namespace ble {
const uint32_t AdvertisingParameters::DEFAULT_ADVERTISING_INTERVAL_MIN;
const uint32_t AdvertisingParameters::DEFAULT_ADVERTISING_INTERVAL_MAX;
const uint32_t AdvertisingParameters::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON;
} // namespace ble

View File

@ -0,0 +1,134 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "gap/ConnectionParameters.h"
namespace ble {
ConnectionParameters::ConnectionParameters(
phy_t phy,
scan_interval_t scanInterval,
scan_window_t scanWindow,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t connectionSupervisionTimeout,
conn_event_length_t minEventLength,
conn_event_length_t maxEventLength
) :
_filterPolicy(initiator_filter_policy_t::NO_FILTER),
_ownAddressType(own_address_type_t::PUBLIC)
{
for (uint8_t i = 0; i < MAX_PARAM_PHYS; ++i) {
_enabledPhy[i] = false;
}
if (phy != phy_t::NONE) {
uint8_t phy_index = phyToIndex(phy);
if (phy_index < MAX_PARAM_PHYS) {
_scanInterval[phy_index] = scanInterval.value();
_scanWindow[phy_index] = scanWindow.value();
_minConnectionInterval[phy_index] = minConnectionInterval.value();
_maxConnectionInterval[phy_index] = maxConnectionInterval.value();
_slaveLatency[phy_index] = slaveLatency.value();
_connectionSupervisionTimeout[phy_index] = connectionSupervisionTimeout.value();
_enabledPhy[phy_index] = true;
_minEventLength[phy_index] = minEventLength.value();
_maxEventLength[phy_index] = maxEventLength.value();
}
}
}
/* setters */
ConnectionParameters &ConnectionParameters::setScanParameters(
phy_t phy,
scan_interval_t scanInterval,
scan_window_t scanWindow
)
{
uint8_t phy_index = handlePhyToggle(phy, true);
if (phy_index < MAX_PARAM_PHYS) {
_scanInterval[phy_index] = scanInterval.value();
_scanWindow[phy_index] = scanWindow.value();
}
return *this;
}
ConnectionParameters &ConnectionParameters::setConnectionParameters(
phy_t phy,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t connectionSupervisionTimeout,
conn_event_length_t minEventLength,
conn_event_length_t maxEventLength
)
{
uint8_t phy_index = handlePhyToggle(phy, true);
if (phy_index < MAX_PARAM_PHYS) {
_minConnectionInterval[phy_index] = minConnectionInterval.value();
_maxConnectionInterval[phy_index] = maxConnectionInterval.value();
_slaveLatency[phy_index] = slaveLatency.value();
_connectionSupervisionTimeout[phy_index] = connectionSupervisionTimeout.value();
/* avoid overflows and truncation */
if (minEventLength.value() > maxEventLength.value()) {
minEventLength = maxEventLength;
}
_minEventLength[phy_index] = minEventLength.value();
_maxEventLength[phy_index] = maxEventLength.value();
}
return *this;
}
/** Handle the swapping of 2M and CODED so that the array is ready for the pal call. */
void ConnectionParameters::swapCodedAnd2M()
{
uint16_t scanInterval = _scanInterval[LE_2M_INDEX];
uint16_t scanWindow = _scanWindow[LE_2M_INDEX];
uint16_t minConnectionInterval = _minConnectionInterval[LE_2M_INDEX];
uint16_t maxConnectionInterval = _maxConnectionInterval[LE_2M_INDEX];
uint16_t slaveLatency = _slaveLatency[LE_2M_INDEX];
uint16_t connectionSupervisionTimeout = _connectionSupervisionTimeout[LE_2M_INDEX];
uint16_t minEventLength = _minEventLength[LE_2M_INDEX];
uint16_t maxEventLength = _maxEventLength[LE_2M_INDEX];
_scanInterval[LE_2M_INDEX] = _scanInterval[LE_CODED_INDEX];
_scanWindow[LE_2M_INDEX] = _scanWindow[LE_CODED_INDEX];
_minConnectionInterval[LE_2M_INDEX] = _minConnectionInterval[LE_CODED_INDEX];
_maxConnectionInterval[LE_2M_INDEX] = _maxConnectionInterval[LE_CODED_INDEX];
_slaveLatency[LE_2M_INDEX] = _slaveLatency[LE_CODED_INDEX];
_connectionSupervisionTimeout[LE_2M_INDEX] = _connectionSupervisionTimeout[LE_CODED_INDEX];
_minEventLength[LE_2M_INDEX] = _minEventLength[LE_CODED_INDEX];
_maxEventLength[LE_2M_INDEX] = _maxEventLength[LE_CODED_INDEX];
_scanInterval[LE_CODED_INDEX] = scanInterval;
_scanWindow[LE_CODED_INDEX] = scanWindow;
_minConnectionInterval[LE_CODED_INDEX] = minConnectionInterval;
_maxConnectionInterval[LE_CODED_INDEX] = maxConnectionInterval;
_slaveLatency[LE_CODED_INDEX] = slaveLatency;
_connectionSupervisionTimeout[LE_CODED_INDEX] = connectionSupervisionTimeout;
_minEventLength[LE_CODED_INDEX] = minEventLength;
_maxEventLength[LE_CODED_INDEX] = maxEventLength;
}
} // namespace ble

View File

@ -0,0 +1,365 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ble/gap/Gap.h"
namespace ble {
bool Gap::isFeatureSupported(controller_supported_features_t feature)
{
return false;
}
uint8_t Gap::getMaxAdvertisingSetNumber()
{
/* Requesting action from porter(s): override this API if this capability is supported. */
// There is at least one advertising set available: the legacy advertising set
return 1;
}
uint8_t Gap::getMaxAdvertisingDataLength()
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return LEGACY_ADVERTISING_MAX_SIZE;
}
ble_error_t Gap::createAdvertisingSet(
advertising_handle_t *handle,
const AdvertisingParameters &parameters
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::destroyAdvertisingSet(advertising_handle_t handle)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setAdvertisingParameters(
advertising_handle_t handle,
const AdvertisingParameters &params
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setAdvertisingPayload(
advertising_handle_t handle,
mbed::Span<const uint8_t> payload
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setAdvertisingScanResponse(
advertising_handle_t handle,
mbed::Span<const uint8_t> response
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::startAdvertising(
advertising_handle_t handle,
adv_duration_t maxDuration,
uint8_t maxEvents
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::stopAdvertising(advertising_handle_t handle)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
bool Gap::isAdvertisingActive(advertising_handle_t handle)
{
return false;
}
ble_error_t Gap::setPeriodicAdvertisingParameters(
advertising_handle_t handle,
periodic_interval_t periodicAdvertisingIntervalMin,
periodic_interval_t periodicAdvertisingIntervalMax,
bool advertiseTxPower
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setPeriodicAdvertisingPayload(
advertising_handle_t handle,
mbed::Span<const uint8_t> payload
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::startPeriodicAdvertising(advertising_handle_t handle)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::stopPeriodicAdvertising(advertising_handle_t handle)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
bool Gap::isPeriodicAdvertisingActive(advertising_handle_t handle)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return false;
}
ble_error_t Gap::setScanParameters(const ScanParameters &params)
{
useVersionTwoAPI();
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
};
ble_error_t Gap::startScan(
duplicates_filter_t filtering,
scan_duration_t duration,
scan_period_t period
)
{
useVersionTwoAPI();
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
};
ble_error_t Gap::stopScan()
{
/* Requesting action from porter(s): override this API if this capability
is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::createSync(
peer_address_type_t peerAddressType,
const address_t &peerAddress,
uint8_t sid,
slave_latency_t maxPacketSkip,
sync_timeout_t timeout
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::createSync(
slave_latency_t maxPacketSkip,
sync_timeout_t timeout
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::cancelCreateSync()
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::terminateSync(periodic_sync_handle_t handle)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::addDeviceToPeriodicAdvertiserList(
peer_address_type_t peerAddressType,
const address_t &peerAddress,
advertising_sid_t sid
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::removeDeviceFromPeriodicAdvertiserList(
peer_address_type_t peerAddressType,
const address_t &peerAddress,
advertising_sid_t sid
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::clearPeriodicAdvertiserList()
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
uint8_t Gap::getMaxPeriodicAdvertiserListSize()
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return 0;
}
ble_error_t Gap::connect(
peer_address_type_t peerAddressType,
const address_t &peerAddress,
const ConnectionParameters &connectionParams
)
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::cancelConnect()
{
/* Requesting action from porter(s): override this API if this capability is supported. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::updateConnectionParameters(
connection_handle_t connectionHandle,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t supervision_timeout,
conn_event_length_t minConnectionEventLength,
conn_event_length_t maxConnectionEventLength
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::manageConnectionParametersUpdateRequest(
bool userManageConnectionUpdateRequest
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::acceptConnectionParametersUpdate(
connection_handle_t connectionHandle,
conn_interval_t minConnectionInterval,
conn_interval_t maxConnectionInterval,
slave_latency_t slaveLatency,
supervision_timeout_t supervision_timeout,
conn_event_length_t minConnectionEventLength,
conn_event_length_t maxConnectionEventLength
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::rejectConnectionParametersUpdate(
connection_handle_t connectionHandle
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::disconnect(
connection_handle_t connectionHandle,
local_disconnection_reason_t reason
)
{
// Forward to the old implementation for now.
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::readPhy(connection_handle_t connection)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setPreferredPhys(
const phy_set_t *txPhys,
const phy_set_t *rxPhys
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setPhy(
connection_handle_t connection,
const phy_set_t *txPhys,
const phy_set_t *rxPhys,
coded_symbol_per_bit_t codedSymbol
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
/* -------------------- Future deprecation ------------------------- */
const peripheral_privacy_configuration_t Gap::default_peripheral_privacy_configuration = {
/* use_non_resolvable_random_address */ false,
/* resolution_strategy */ peripheral_privacy_configuration_t::PERFORM_PAIRING_PROCEDURE
};
const central_privay_configuration_t Gap::default_central_privacy_configuration = {
/* use_non_resolvable_random_address */ false,
/* resolution_strategy */ central_privay_configuration_t::RESOLVE_AND_FORWARD
};
ble_error_t Gap::enablePrivacy(bool enable)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setPeripheralPrivacyConfiguration(
const peripheral_privacy_configuration_t *configuration
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::getPeripheralPrivacyConfiguration(
peripheral_privacy_configuration_t *configuration
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::setCentralPrivacyConfiguration(
const central_privay_configuration_t *configuration
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::getCentralPrivacyConfiguration(
central_privay_configuration_t *configuration
)
{
return BLE_ERROR_NOT_IMPLEMENTED;
}
} // namespace ble

File diff suppressed because it is too large Load Diff

View File

@ -66,7 +66,7 @@ struct GenericGattClient::ProcedureControlBlock {
/* /*
* Base constructor for procedure control block. * Base constructor for procedure control block.
*/ */
ProcedureControlBlock(procedure_type_t type, Gap::Handle_t handle) : ProcedureControlBlock(procedure_type_t type, connection_handle_t handle) :
type(type), connection_handle(handle), next(NULL) { } type(type), connection_handle(handle), next(NULL) { }
virtual ~ProcedureControlBlock() { } virtual ~ProcedureControlBlock() { }
@ -87,7 +87,7 @@ struct GenericGattClient::ProcedureControlBlock {
virtual void abort(GenericGattClient *client) = 0; virtual void abort(GenericGattClient *client) = 0;
procedure_type_t type; procedure_type_t type;
Gap::Handle_t connection_handle; connection_handle_t connection_handle;
ProcedureControlBlock* next; ProcedureControlBlock* next;
}; };
@ -97,7 +97,7 @@ struct GenericGattClient::ProcedureControlBlock {
*/ */
struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock { struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock {
DiscoveryControlBlock( DiscoveryControlBlock(
Gap::Handle_t handle, connection_handle_t handle,
ServiceDiscovery::ServiceCallback_t service_callback, ServiceDiscovery::ServiceCallback_t service_callback,
ServiceDiscovery::CharacteristicCallback_t characteristic_callback, ServiceDiscovery::CharacteristicCallback_t characteristic_callback,
UUID matching_service_uuid, UUID matching_service_uuid,
@ -307,7 +307,7 @@ struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock {
void terminate(GenericGattClient* client) { void terminate(GenericGattClient* client) {
// unknown error, terminate the procedure immediately // unknown error, terminate the procedure immediately
client->remove_control_block(this); client->remove_control_block(this);
Gap::Handle_t handle = connection_handle; connection_handle_t handle = connection_handle;
delete this; delete this;
client->on_termination(handle); client->on_termination(handle);
} }
@ -356,7 +356,7 @@ struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock {
characteristic_t( characteristic_t(
GattClient* client, GattClient* client,
Gap::Handle_t connection_handle, connection_handle_t connection_handle,
uint16_t decl_handle, uint16_t decl_handle,
const ArrayView<const uint8_t> value const ArrayView<const uint8_t> value
) : DiscoveredCharacteristic() { ) : DiscoveredCharacteristic() {
@ -428,7 +428,7 @@ struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock {
struct GenericGattClient::ReadControlBlock : public ProcedureControlBlock { struct GenericGattClient::ReadControlBlock : public ProcedureControlBlock {
ReadControlBlock( ReadControlBlock(
Gap::Handle_t connection_handle, uint16_t attribute_handle, uint16_t offset connection_handle_t connection_handle, uint16_t attribute_handle, uint16_t offset
) : ProcedureControlBlock(READ_PROCEDURE, connection_handle), ) : ProcedureControlBlock(READ_PROCEDURE, connection_handle),
attribute_handle(attribute_handle), attribute_handle(attribute_handle),
offset(offset), current_offset(offset), data(NULL) { offset(offset), current_offset(offset), data(NULL) {
@ -625,7 +625,7 @@ struct GenericGattClient::ReadControlBlock : public ProcedureControlBlock {
*/ */
struct GenericGattClient::WriteControlBlock : public ProcedureControlBlock { struct GenericGattClient::WriteControlBlock : public ProcedureControlBlock {
WriteControlBlock( WriteControlBlock(
Gap::Handle_t connection_handle, uint16_t attribute_handle, connection_handle_t connection_handle, uint16_t attribute_handle,
uint8_t* data, uint16_t len uint8_t* data, uint16_t len
) : ProcedureControlBlock(WRITE_PROCEDURE, connection_handle), ) : ProcedureControlBlock(WRITE_PROCEDURE, connection_handle),
attribute_handle(attribute_handle), len(len), offset(0), data(data), attribute_handle(attribute_handle), len(len), offset(0), data(data),
@ -949,7 +949,7 @@ GenericGattClient::GenericGattClient(pal::GattClient* pal_client) :
} }
ble_error_t GenericGattClient::launchServiceDiscovery( ble_error_t GenericGattClient::launchServiceDiscovery(
Gap::Handle_t connection_handle, connection_handle_t connection_handle,
ServiceDiscovery::ServiceCallback_t service_callback, ServiceDiscovery::ServiceCallback_t service_callback,
ServiceDiscovery::CharacteristicCallback_t characteristic_callback, ServiceDiscovery::CharacteristicCallback_t characteristic_callback,
const UUID& matching_service_uuid, const UUID& matching_service_uuid,
@ -1030,7 +1030,7 @@ void GenericGattClient::terminateServiceDiscovery()
} }
ble_error_t GenericGattClient::read( ble_error_t GenericGattClient::read(
Gap::Handle_t connection_handle, connection_handle_t connection_handle,
GattAttribute::Handle_t attribute_handle, GattAttribute::Handle_t attribute_handle,
uint16_t offset) const uint16_t offset) const
{ {
@ -1073,7 +1073,7 @@ ble_error_t GenericGattClient::read(
ble_error_t GenericGattClient::write( ble_error_t GenericGattClient::write(
GattClient::WriteOp_t cmd, GattClient::WriteOp_t cmd,
Gap::Handle_t connection_handle, connection_handle_t connection_handle,
GattAttribute::Handle_t attribute_handle, GattAttribute::Handle_t attribute_handle,
size_t length, size_t length,
const uint8_t* value const uint8_t* value
@ -1279,7 +1279,7 @@ void GenericGattClient::set_signing_event_handler(
_signing_event_handler = signing_event_handler; _signing_event_handler = signing_event_handler;
} }
void GenericGattClient::on_termination(Gap::Handle_t connection_handle) { void GenericGattClient::on_termination(connection_handle_t connection_handle) {
if (_termination_callback) { if (_termination_callback) {
_termination_callback(connection_handle); _termination_callback(connection_handle);
} }
@ -1330,7 +1330,7 @@ void GenericGattClient::on_server_response(
void GenericGattClient::on_server_event(connection_handle_t connection, const AttServerMessage& message) { void GenericGattClient::on_server_event(connection_handle_t connection, const AttServerMessage& message) {
GattHVXCallbackParams callbacks_params = { GattHVXCallbackParams callbacks_params = {
(Gap::Handle_t) connection, 0 (connection_handle_t) connection, 0
}; };
switch (message.opcode) { switch (message.opcode) {
@ -1368,7 +1368,7 @@ void GenericGattClient::on_transaction_timeout(connection_handle_t connection) {
pcb->handle_timeout_error(this); pcb->handle_timeout_error(this);
} }
GenericGattClient::ProcedureControlBlock* GenericGattClient::get_control_block(Gap::Handle_t connection) { GenericGattClient::ProcedureControlBlock* GenericGattClient::get_control_block(connection_handle_t connection) {
ProcedureControlBlock* it = control_blocks; ProcedureControlBlock* it = control_blocks;
while (it && it->connection_handle != connection) { while (it && it->connection_handle != connection) {
it = it->next; it = it->next;
@ -1376,7 +1376,7 @@ GenericGattClient::ProcedureControlBlock* GenericGattClient::get_control_block(G
return it; return it;
} }
const GenericGattClient::ProcedureControlBlock* GenericGattClient::get_control_block(Gap::Handle_t connection) const { const GenericGattClient::ProcedureControlBlock* GenericGattClient::get_control_block(connection_handle_t connection) const {
ProcedureControlBlock* it = control_blocks; ProcedureControlBlock* it = control_blocks;
while (it && it->connection_handle != connection) { while (it && it->connection_handle != connection) {
it = it->next; it = it->next;
@ -1420,7 +1420,7 @@ void GenericGattClient::remove_control_block(ProcedureControlBlock* cb) const {
cb->next = NULL; cb->next = NULL;
} }
uint16_t GenericGattClient::get_mtu(Gap::Handle_t connection) const { uint16_t GenericGattClient::get_mtu(connection_handle_t connection) const {
uint16_t result = 23; uint16_t result = 23;
if(_pal_client->get_mtu_size((connection_handle_t) connection, result) != BLE_ERROR_NONE) { if(_pal_client->get_mtu_size((connection_handle_t) connection, result) != BLE_ERROR_NONE) {
result = 23; result = 23;

View File

@ -139,7 +139,7 @@ ble_error_t GenericSecurityManager::purgeAllBondingState(void) {
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t GenericSecurityManager::generateWhitelistFromBondTable(Gap::Whitelist_t *whitelist) const { ble_error_t GenericSecurityManager::generateWhitelistFromBondTable(::Gap::Whitelist_t *whitelist) const {
if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE; if (!_db) return BLE_ERROR_INITIALIZATION_INCOMPLETE;
if (eventHandler) { if (eventHandler) {
if (!whitelist) { if (!whitelist) {
@ -1033,12 +1033,12 @@ void GenericSecurityManager::set_mitm_performed(connection_handle_t connection,
void GenericSecurityManager::on_connected( void GenericSecurityManager::on_connected(
connection_handle_t connection, connection_handle_t connection,
Gap::Role_t role, ::Gap::Role_t role,
peer_address_type_t peer_address_type, peer_address_type_t peer_address_type,
const BLEProtocol::AddressBytes_t peer_address, const BLEProtocol::AddressBytes_t peer_address,
BLEProtocol::AddressType_t local_address_type, BLEProtocol::AddressType_t local_address_type,
const BLEProtocol::AddressBytes_t local_address, const BLEProtocol::AddressBytes_t local_address,
const Gap::ConnectionParams_t *connection_params const ::Gap::ConnectionParams_t *connection_params
) { ) {
MBED_ASSERT(_db); MBED_ASSERT(_db);
ControlBlock_t *cb = acquire_control_block(connection); ControlBlock_t *cb = acquire_control_block(connection);
@ -1048,7 +1048,7 @@ void GenericSecurityManager::on_connected(
// setup the control block // setup the control block
cb->local_address = local_address; cb->local_address = local_address;
cb->is_master = (role == Gap::CENTRAL); cb->is_master = (role == ::Gap::CENTRAL);
// get the associated db handle and the distribution flags if any // get the associated db handle and the distribution flags if any
cb->db_entry = _db->open_entry(peer_address_type, peer_address); cb->db_entry = _db->open_entry(peer_address_type, peer_address);
@ -1074,7 +1074,7 @@ void GenericSecurityManager::on_connected(
void GenericSecurityManager::on_disconnected( void GenericSecurityManager::on_disconnected(
connection_handle_t connection, connection_handle_t connection,
Gap::DisconnectionReason_t reason ::Gap::DisconnectionReason_t reason
) { ) {
MBED_ASSERT(_db); MBED_ASSERT(_db);
ControlBlock_t *cb = get_control_block(connection); ControlBlock_t *cb = get_control_block(connection);
@ -1100,8 +1100,8 @@ void GenericSecurityManager::on_security_entry_retrieved(
_pal.add_device_to_resolving_list( _pal.add_device_to_resolving_list(
identity->identity_address_is_public ? identity->identity_address_is_public ?
address_type_t::PUBLIC_ADDRESS : address_type_t::PUBLIC :
address_type_t::RANDOM_ADDRESS, address_type_t::RANDOM,
identity->identity_address, identity->identity_address,
identity->irk identity->irk
); );
@ -1117,8 +1117,8 @@ void GenericSecurityManager::on_identity_list_retrieved(
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
_pal.add_device_to_resolving_list( _pal.add_device_to_resolving_list(
identity_list[i].identity_address_is_public ? identity_list[i].identity_address_is_public ?
address_type_t::PUBLIC_ADDRESS : address_type_t::PUBLIC :
address_type_t::RANDOM_ADDRESS, address_type_t::RANDOM,
identity_list[i].identity_address, identity_list[i].identity_address,
identity_list[i].irk identity_list[i].irk
); );
@ -1564,7 +1564,7 @@ void GenericSecurityManager::on_keys_distributed_bdaddr(
_db->set_entry_peer_bdaddr( _db->set_entry_peer_bdaddr(
cb->db_entry, cb->db_entry,
(peer_address_type == advertising_peer_address_type_t::PUBLIC_ADDRESS), (peer_address_type == advertising_peer_address_type_t::PUBLIC),
peer_identity_address peer_identity_address
); );
} }

View File

@ -86,7 +86,7 @@ public:
* @see ::GattServer::read * @see ::GattServer::read
*/ */
virtual ble_error_t read( virtual ble_error_t read(
Gap::Handle_t connectionHandle, connection_handle_t connectionHandle,
GattAttribute::Handle_t attributeHandle, GattAttribute::Handle_t attributeHandle,
uint8_t buffer[], uint16_t *lengthP uint8_t buffer[], uint16_t *lengthP
); );
@ -104,7 +104,7 @@ public:
* @see ::GattServer::write * @see ::GattServer::write
*/ */
virtual ble_error_t write( virtual ble_error_t write(
Gap::Handle_t connectionHandle, connection_handle_t connectionHandle,
GattAttribute::Handle_t, GattAttribute::Handle_t,
const uint8_t[], const uint8_t[],
uint16_t, uint16_t,
@ -122,7 +122,7 @@ public:
* @see ::GattServer::areUpdatesEnabled * @see ::GattServer::areUpdatesEnabled
*/ */
virtual ble_error_t areUpdatesEnabled( virtual ble_error_t areUpdatesEnabled(
Gap::Handle_t connectionHandle, connection_handle_t connectionHandle,
const GattCharacteristic &characteristic, const GattCharacteristic &characteristic,
bool *enabledP bool *enabledP
); );
@ -224,7 +224,7 @@ private:
GattCharacteristic* get_auth_char(uint16_t value_handle); GattCharacteristic* get_auth_char(uint16_t value_handle);
bool get_cccd_index_by_cccd_handle(GattAttribute::Handle_t cccd_handle, uint8_t& idx) const; bool get_cccd_index_by_cccd_handle(GattAttribute::Handle_t cccd_handle, uint8_t& idx) const;
bool get_cccd_index_by_value_handle(GattAttribute::Handle_t char_handle, uint8_t& idx) const; bool get_cccd_index_by_value_handle(GattAttribute::Handle_t char_handle, uint8_t& idx) const;
bool is_update_authorized(Gap::Handle_t connection, GattAttribute::Handle_t value_handle); bool is_update_authorized(connection_handle_t connection, GattAttribute::Handle_t value_handle);
struct alloc_block_t { struct alloc_block_t {
alloc_block_t* next; alloc_block_t* next;

View File

@ -15,7 +15,7 @@ namespace cordio {
class Gap : public ::ble::pal::Gap { class Gap : public ::ble::pal::Gap {
public: public:
virtual bool is_feature_supported( virtual bool is_feature_supported(
Gap::ControllerSupportedFeatures_t feature ble::controller_supported_features_t feature
); );
virtual ble_error_t initialize(); virtual ble_error_t initialize();
@ -153,6 +153,145 @@ public:
*/ */
static void gap_handler(const wsfMsgHdr_t* msg); static void gap_handler(const wsfMsgHdr_t* msg);
virtual ble_error_t set_advertising_set_random_address(
advertising_handle_t advertising_handle,
const address_t &address
);
virtual ble_error_t set_extended_advertising_parameters(
advertising_handle_t advertising_handle,
advertising_event_properties_t event_properties,
advertising_interval_t primary_advertising_interval_min,
advertising_interval_t primary_advertising_interval_max,
advertising_channel_map_t primary_advertising_channel_map,
own_address_type_t own_address_type,
advertising_peer_address_type_t peer_address_type,
const address_t &peer_address,
advertising_filter_policy_t advertising_filter_policy,
advertising_power_t advertising_power,
phy_t primary_advertising_phy,
uint8_t secondary_advertising_max_skip,
phy_t secondary_phy,
uint8_t advertising_sid,
bool scan_request_notification
);
virtual ble_error_t set_periodic_advertising_parameters(
advertising_handle_t advertising_handle,
periodic_advertising_interval_t periodic_advertising_min,
periodic_advertising_interval_t periodic_advertising_max,
bool advertise_power
);
virtual ble_error_t set_extended_advertising_data(
advertising_handle_t advertising_handle,
advertising_fragment_description_t operation,
bool minimize_fragmentation,
uint8_t advertising_data_size,
const uint8_t *advertising_data
);
virtual ble_error_t set_periodic_advertising_data(
advertising_handle_t advertising_handle,
advertising_fragment_description_t fragment_description,
uint8_t advertising_data_size,
const uint8_t *advertising_data
);
virtual ble_error_t set_extended_scan_response_data(
advertising_handle_t advertising_handle,
advertising_fragment_description_t operation,
bool minimize_fragmentation,
uint8_t scan_response_data_size,
const uint8_t *scan_response_data
);
virtual ble_error_t extended_advertising_enable(
bool enable,
uint8_t number_of_sets,
const advertising_handle_t *handles,
const uint16_t *durations,
const uint8_t *max_extended_advertising_events
);
virtual ble_error_t periodic_advertising_enable(
bool enable,
advertising_handle_t advertising_handle
);
virtual uint16_t get_maximum_advertising_data_length();
virtual uint8_t get_max_number_of_advertising_sets();
virtual ble_error_t remove_advertising_set(
advertising_handle_t advertising_handle
);
virtual ble_error_t clear_advertising_sets();
virtual ble_error_t set_extended_scan_parameters(
own_address_type_t own_address_type,
scanning_filter_policy_t filter_policy,
phy_set_t scanning_phys,
const bool *active_scanning,
const uint16_t *scan_interval,
const uint16_t *scan_window
);
virtual ble_error_t extended_scan_enable(
bool enable,
duplicates_filter_t filter_duplicates,
uint16_t duration,
uint16_t period
);
virtual ble_error_t periodic_advertising_create_sync(
bool use_periodic_advertiser_list,
uint8_t advertising_sid,
peer_address_type_t peer_address_type,
const address_t &peer_address,
uint16_t allowed_skip,
uint16_t sync_timeout
);
virtual ble_error_t cancel_periodic_advertising_create_sync();
virtual ble_error_t periodic_advertising_terminate_sync(
sync_handle_t sync_handle
);
virtual ble_error_t add_device_to_periodic_advertiser_list(
advertising_peer_address_type_t advertiser_address_type,
const address_t &advertiser_address,
uint8_t advertising_sid
);
virtual ble_error_t remove_device_from_periodic_advertiser_list(
advertising_peer_address_type_t advertiser_address_type,
const address_t &advertiser_address,
uint8_t advertising_sid
);
virtual ble_error_t clear_periodic_advertiser_list();
virtual uint8_t read_periodic_advertiser_list_size();
virtual ble_error_t extended_create_connection(
initiator_policy_t initiator_policy,
own_address_type_t own_address_type,
peer_address_type_t peer_address_type,
const address_t &peer_address,
phy_set_t initiating_phys,
const uint16_t *scan_intervals,
const uint16_t *scan_windows,
const uint16_t *connection_intervals_min,
const uint16_t *connection_intervals_max,
const uint16_t *connection_latencies,
const uint16_t *supervision_timeouts,
const uint16_t *minimum_connection_event_lengths,
const uint16_t *maximum_connection_event_lengths
);
private: private:
/** /**
* T shall define a can_convert and convert function and a type * T shall define a can_convert and convert function and a type
@ -270,6 +409,8 @@ private:
private: private:
address_t device_random_address; address_t device_random_address;
bool use_active_scanning; bool use_active_scanning;
uint8_t extended_scan_type[3];
phy_set_t scanning_phys;
}; };
} // cordio } // cordio

View File

@ -259,6 +259,15 @@ void BLE::processEvents()
::BLE::Instance(::BLE::DEFAULT_INSTANCE), ::BLE::Instance(::BLE::DEFAULT_INSTANCE),
BLE_ERROR_NONE BLE_ERROR_NONE
}; };
// initialize extended module if supported
if (HciGetLeSupFeat() & HCI_LE_SUP_FEAT_LE_EXT_ADV) {
DmExtAdvInit();
DmExtScanInit();
DmExtConnMasterInit();
DmExtConnSlaveInit();
}
deviceInstance().getGattServer().initialize(); deviceInstance().getGattServer().initialize();
deviceInstance().initialization_status = INITIALIZED; deviceInstance().initialization_status = INITIALIZED;
_init_callback.call(&context); _init_callback.call(&context);

View File

@ -553,7 +553,7 @@ ble_error_t GattServer::read(
} }
ble_error_t GattServer::read( ble_error_t GattServer::read(
Gap::Handle_t connection, connection_handle_t connection,
GattAttribute::Handle_t att_handle, GattAttribute::Handle_t att_handle,
uint8_t buffer[], uint8_t buffer[],
uint16_t *buffer_length uint16_t *buffer_length
@ -652,7 +652,7 @@ ble_error_t GattServer::write(
} }
ble_error_t GattServer::write( ble_error_t GattServer::write(
Gap::Handle_t connection, connection_handle_t connection,
GattAttribute::Handle_t att_handle, GattAttribute::Handle_t att_handle,
const uint8_t buffer[], const uint8_t buffer[],
uint16_t len, uint16_t len,
@ -733,7 +733,7 @@ ble_error_t GattServer::areUpdatesEnabled(
} }
ble_error_t GattServer::areUpdatesEnabled( ble_error_t GattServer::areUpdatesEnabled(
Gap::Handle_t connectionHandle, connection_handle_t connectionHandle,
const GattCharacteristic &characteristic, const GattCharacteristic &characteristic,
bool *enabled bool *enabled
) { ) {
@ -1232,7 +1232,7 @@ bool GattServer::get_cccd_index_by_value_handle(GattAttribute::Handle_t char_han
} }
bool GattServer::is_update_authorized( bool GattServer::is_update_authorized(
Gap::Handle_t connection, connection_handle_t connection,
GattAttribute::Handle_t value_handle GattAttribute::Handle_t value_handle
) { ) {
GattCharacteristic* auth_char = get_auth_char(value_handle); GattCharacteristic* auth_char = get_auth_char(value_handle);

View File

@ -16,6 +16,7 @@
#include "CordioPalGap.h" #include "CordioPalGap.h"
#include "hci_api.h" #include "hci_api.h"
#include "dm_api.h"
namespace ble { namespace ble {
namespace pal { namespace pal {
@ -23,30 +24,36 @@ namespace vendor {
namespace cordio { namespace cordio {
bool Gap::is_feature_supported( bool Gap::is_feature_supported(
Gap::ControllerSupportedFeatures_t feature ble::controller_supported_features_t feature
) { )
{
return (HciGetLeSupFeat() & (1 << feature.value())); return (HciGetLeSupFeat() & (1 << feature.value()));
} }
ble_error_t Gap::initialize() { ble_error_t Gap::initialize()
{
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t Gap::terminate() { ble_error_t Gap::terminate()
{
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
address_t Gap::get_device_address() { address_t Gap::get_device_address()
{
return address_t(HciGetBdAddr()); return address_t(HciGetBdAddr());
} }
address_t Gap::get_random_address() { address_t Gap::get_random_address()
{
return device_random_address; return device_random_address;
} }
ble_error_t Gap::set_random_address(const address_t& address) { ble_error_t Gap::set_random_address(const address_t &address)
{
device_random_address = address; device_random_address = address;
DmDevSetRandAddr(const_cast<uint8_t*>(address.data())); DmDevSetRandAddr(const_cast<uint8_t *>(address.data()));
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -56,10 +63,11 @@ ble_error_t Gap::set_advertising_parameters(
advertising_type_t advertising_type, advertising_type_t advertising_type,
own_address_type_t own_address_type, own_address_type_t own_address_type,
advertising_peer_address_type_t peer_address_type, advertising_peer_address_type_t peer_address_type,
const address_t& peer_address, const address_t &peer_address,
advertising_channel_map_t advertising_channel_map, advertising_channel_map_t advertising_channel_map,
advertising_filter_policy_t advertising_filter_policy advertising_filter_policy_t advertising_filter_policy
) { )
{
DmAdvSetInterval( DmAdvSetInterval(
DM_ADV_HANDLE_DEFAULT, DM_ADV_HANDLE_DEFAULT,
advertising_interval_min, advertising_interval_min,
@ -82,7 +90,7 @@ ble_error_t Gap::set_advertising_parameters(
DM_ADV_HANDLE_DEFAULT, DM_ADV_HANDLE_DEFAULT,
advertising_type.value(), advertising_type.value(),
peer_address_type.value(), peer_address_type.value(),
const_cast<uint8_t*>(peer_address.data()) const_cast<uint8_t *>(peer_address.data())
); );
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
@ -90,40 +98,43 @@ ble_error_t Gap::set_advertising_parameters(
ble_error_t Gap::set_advertising_data( ble_error_t Gap::set_advertising_data(
uint8_t advertising_data_length, uint8_t advertising_data_length,
const advertising_data_t& advertising_data const advertising_data_t &advertising_data
) { )
{
DmAdvSetData( DmAdvSetData(
DM_ADV_HANDLE_DEFAULT, DM_ADV_HANDLE_DEFAULT,
HCI_ADV_DATA_OP_COMP_FRAG, HCI_ADV_DATA_OP_COMP_FRAG,
DM_DATA_LOC_ADV, DM_DATA_LOC_ADV,
advertising_data_length, advertising_data_length,
const_cast<uint8_t*>(advertising_data.data()) const_cast<uint8_t *>(advertising_data.data())
); );
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t Gap::set_scan_response_data( ble_error_t Gap::set_scan_response_data(
uint8_t scan_response_data_length, uint8_t scan_response_data_length,
const advertising_data_t& scan_response_data const advertising_data_t &scan_response_data
) { )
{
DmAdvSetData( DmAdvSetData(
DM_ADV_HANDLE_DEFAULT, DM_ADV_HANDLE_DEFAULT,
HCI_ADV_DATA_OP_COMP_FRAG, HCI_ADV_DATA_OP_COMP_FRAG,
DM_DATA_LOC_SCAN, DM_DATA_LOC_SCAN,
scan_response_data_length, scan_response_data_length,
const_cast<uint8_t*>(scan_response_data.data()) const_cast<uint8_t *>(scan_response_data.data())
); );
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t Gap::advertising_enable(bool enable) { ble_error_t Gap::advertising_enable(bool enable)
{
if (enable) { if (enable) {
uint8_t adv_handles[] = { DM_ADV_HANDLE_DEFAULT }; uint8_t adv_handles[] = {DM_ADV_HANDLE_DEFAULT};
uint16_t adv_durations[] = { /* infinite */ 0 }; uint16_t adv_durations[] = { /* infinite */ 0};
uint8_t max_ea_events[] = { 0 }; uint8_t max_ea_events[] = {0};
DmAdvStart(1, adv_handles, adv_durations, max_ea_events); DmAdvStart(1, adv_handles, adv_durations, max_ea_events);
} else { } else {
uint8_t adv_handles[] = { DM_ADV_HANDLE_DEFAULT }; uint8_t adv_handles[] = {DM_ADV_HANDLE_DEFAULT};
DmAdvStop(1, adv_handles); DmAdvStop(1, adv_handles);
} }
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
@ -135,7 +146,8 @@ ble_error_t Gap::set_scan_parameters(
uint16_t scan_window, uint16_t scan_window,
own_address_type_t own_address_type, own_address_type_t own_address_type,
scanning_filter_policy_t filter_policy scanning_filter_policy_t filter_policy
) { )
{
use_active_scanning = active_scanning; use_active_scanning = active_scanning;
DmScanSetInterval(HCI_INIT_PHY_LE_1M_BIT, &scan_interval, &scan_window); DmScanSetInterval(HCI_INIT_PHY_LE_1M_BIT, &scan_interval, &scan_window);
DmScanSetAddrType(own_address_type.value()); DmScanSetAddrType(own_address_type.value());
@ -149,7 +161,8 @@ ble_error_t Gap::set_scan_parameters(
ble_error_t Gap::scan_enable( ble_error_t Gap::scan_enable(
bool enable, bool enable,
bool filter_duplicates bool filter_duplicates
) { )
{
if (enable) { if (enable) {
uint8_t scanType = use_active_scanning ? DM_SCAN_TYPE_ACTIVE : DM_SCAN_TYPE_PASSIVE; uint8_t scanType = use_active_scanning ? DM_SCAN_TYPE_ACTIVE : DM_SCAN_TYPE_PASSIVE;
DmScanStart( DmScanStart(
@ -171,7 +184,7 @@ ble_error_t Gap::create_connection(
uint16_t scan_window, uint16_t scan_window,
initiator_policy_t initiator_policy, initiator_policy_t initiator_policy,
connection_peer_address_type_t peer_address_type, connection_peer_address_type_t peer_address_type,
const address_t& peer_address, const address_t &peer_address,
own_address_type_t own_address_type, own_address_type_t own_address_type,
uint16_t connection_interval_min, uint16_t connection_interval_min,
uint16_t connection_interval_max, uint16_t connection_interval_max,
@ -179,7 +192,8 @@ ble_error_t Gap::create_connection(
uint16_t supervision_timeout, uint16_t supervision_timeout,
uint16_t minimum_connection_event_length, uint16_t minimum_connection_event_length,
uint16_t maximum_connection_event_length uint16_t maximum_connection_event_length
) { )
{
DmConnSetScanInterval(scan_interval, scan_window); DmConnSetScanInterval(scan_interval, scan_window);
DmDevSetFilterPolicy(DM_FILT_POLICY_MODE_INIT, initiator_policy.value()); DmDevSetFilterPolicy(DM_FILT_POLICY_MODE_INIT, initiator_policy.value());
DmConnSetAddrType(own_address_type.value()); DmConnSetAddrType(own_address_type.value());
@ -198,7 +212,7 @@ ble_error_t Gap::create_connection(
DM_CLIENT_ID_APP, DM_CLIENT_ID_APP,
HCI_INIT_PHY_LE_1M_BIT, HCI_INIT_PHY_LE_1M_BIT,
peer_address_type.value(), peer_address_type.value(),
const_cast<uint8_t*>(peer_address.data()) const_cast<uint8_t *>(peer_address.data())
); );
if (connection_id == DM_CONN_ID_NONE) { if (connection_id == DM_CONN_ID_NONE) {
@ -208,7 +222,8 @@ ble_error_t Gap::create_connection(
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t Gap::cancel_connection_creation() { ble_error_t Gap::cancel_connection_creation()
{
DmConnClose( DmConnClose(
DM_CLIENT_ID_APP, DM_CLIENT_ID_APP,
/* connection handle - invalid */ DM_CONN_ID_NONE, /* connection handle - invalid */ DM_CONN_ID_NONE,
@ -217,11 +232,13 @@ ble_error_t Gap::cancel_connection_creation() {
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
uint8_t Gap::read_white_list_capacity() { uint8_t Gap::read_white_list_capacity()
{
return HciGetWhiteListSize(); return HciGetWhiteListSize();
} }
ble_error_t Gap::clear_whitelist() { ble_error_t Gap::clear_whitelist()
{
DmDevWhiteListClear(); DmDevWhiteListClear();
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -229,10 +246,11 @@ ble_error_t Gap::clear_whitelist() {
ble_error_t Gap::add_device_to_whitelist( ble_error_t Gap::add_device_to_whitelist(
whitelist_address_type_t address_type, whitelist_address_type_t address_type,
address_t address address_t address
) { )
{
DmDevWhiteListAdd( DmDevWhiteListAdd(
address_type.value(), address_type.value(),
const_cast<uint8_t*>(address.data()) const_cast<uint8_t *>(address.data())
); );
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -240,10 +258,11 @@ ble_error_t Gap::add_device_to_whitelist(
ble_error_t Gap::remove_device_from_whitelist( ble_error_t Gap::remove_device_from_whitelist(
whitelist_address_type_t address_type, whitelist_address_type_t address_type,
address_t address address_t address
) { )
{
DmDevWhiteListRemove( DmDevWhiteListRemove(
address_type.value(), address_type.value(),
const_cast<uint8_t*>(address.data()) const_cast<uint8_t *>(address.data())
); );
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -256,7 +275,8 @@ ble_error_t Gap::connection_parameters_update(
uint16_t supervision_timeout, uint16_t supervision_timeout,
uint16_t minimum_connection_event_length, uint16_t minimum_connection_event_length,
uint16_t maximum_connection_event_length uint16_t maximum_connection_event_length
) { )
{
if (DmConnCheckIdle(connection) != 0) { if (DmConnCheckIdle(connection) != 0) {
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
@ -285,7 +305,8 @@ ble_error_t Gap::accept_connection_parameter_request(
uint16_t supervision_timeout, uint16_t supervision_timeout,
uint16_t minimum_connection_event_length, uint16_t minimum_connection_event_length,
uint16_t maximum_connection_event_length uint16_t maximum_connection_event_length
) { )
{
hciConnSpec_t connection_spec = { hciConnSpec_t connection_spec = {
interval_min, interval_min,
interval_max, interval_max,
@ -301,7 +322,8 @@ ble_error_t Gap::accept_connection_parameter_request(
ble_error_t Gap::reject_connection_parameter_request( ble_error_t Gap::reject_connection_parameter_request(
connection_handle_t connection_handle, connection_handle_t connection_handle,
hci_error_code_t rejection_reason hci_error_code_t rejection_reason
) { )
{
DmRemoteConnParamReqNegReply( DmRemoteConnParamReqNegReply(
connection_handle, connection_handle,
rejection_reason.value() rejection_reason.value()
@ -312,7 +334,8 @@ ble_error_t Gap::reject_connection_parameter_request(
ble_error_t Gap::disconnect( ble_error_t Gap::disconnect(
connection_handle_t connection, connection_handle_t connection,
disconnection_reason_t disconnection_reason disconnection_reason_t disconnection_reason
) { )
{
DmConnClose( DmConnClose(
DM_CLIENT_ID_APP, DM_CLIENT_ID_APP,
connection, connection,
@ -321,21 +344,24 @@ ble_error_t Gap::disconnect(
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
bool Gap::is_privacy_supported() { bool Gap::is_privacy_supported()
{
// We only support controller-based privacy, so return whether the controller supports it // We only support controller-based privacy, so return whether the controller supports it
return HciLlPrivacySupported(); return HciLlPrivacySupported();
} }
ble_error_t Gap::set_address_resolution( ble_error_t Gap::set_address_resolution(
bool enable bool enable
) { )
{
DmPrivSetAddrResEnable(enable); DmPrivSetAddrResEnable(enable);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
ble_error_t Gap::read_phy(connection_handle_t connection) { ble_error_t Gap::read_phy(connection_handle_t connection)
if (is_feature_supported(ControllerSupportedFeatures_t::LE_2M_PHY) {
|| is_feature_supported(ControllerSupportedFeatures_t::LE_CODED_PHY)) { if (is_feature_supported(controller_supported_features_t::LE_2M_PHY)
|| is_feature_supported(controller_supported_features_t::LE_CODED_PHY)) {
DmReadPhy(connection); DmReadPhy(connection);
return BLE_ERROR_NONE; return BLE_ERROR_NONE;
} }
@ -343,9 +369,10 @@ ble_error_t Gap::read_phy(connection_handle_t connection) {
} }
ble_error_t Gap::set_preferred_phys( ble_error_t Gap::set_preferred_phys(
const phy_set_t& tx_phys, const phy_set_t &tx_phys,
const phy_set_t& rx_phys const phy_set_t &rx_phys
) { )
{
DmSetDefaultPhy( DmSetDefaultPhy(
create_all_phys_value(tx_phys, rx_phys), create_all_phys_value(tx_phys, rx_phys),
tx_phys.value(), tx_phys.value(),
@ -357,10 +384,11 @@ ble_error_t Gap::set_preferred_phys(
ble_error_t Gap::set_phy( ble_error_t Gap::set_phy(
connection_handle_t connection, connection_handle_t connection,
const phy_set_t& tx_phys, const phy_set_t &tx_phys,
const phy_set_t& rx_phys, const phy_set_t &rx_phys,
coded_symbol_per_bit_t coded_symbol coded_symbol_per_bit_t coded_symbol
) { )
{
/* if phy set is empty set corresponding all_phys bit to 1 */ /* if phy set is empty set corresponding all_phys bit to 1 */
uint8_t all_phys = 0; uint8_t all_phys = 0;
if (tx_phys.value() == 0) { if (tx_phys.value() == 0) {
@ -382,7 +410,8 @@ ble_error_t Gap::set_phy(
} }
// singleton of the ARM Cordio client // singleton of the ARM Cordio client
Gap& Gap::get_gap() { Gap &Gap::get_gap()
{
static Gap _gap; static Gap _gap;
return _gap; return _gap;
} }
@ -390,37 +419,215 @@ Gap& Gap::get_gap() {
/** /**
* Callback which handle wsfMsgHdr_t and forward them to emit_gap_event. * Callback which handle wsfMsgHdr_t and forward them to emit_gap_event.
*/ */
void Gap::gap_handler(const wsfMsgHdr_t* msg) { void Gap::gap_handler(const wsfMsgHdr_t *msg)
typedef bool (*event_handler_t)(const wsfMsgHdr_t* msg); {
typedef bool (*event_handler_t)(const wsfMsgHdr_t *msg);
if (msg == NULL) { if (msg == NULL) {
return; return;
} }
connection_handle_t handle = (connection_handle_t)msg->param; connection_handle_t handle = (connection_handle_t) msg->param;
EventHandler *handler = get_gap()._pal_event_handler;
switch(msg->event) {
case DM_PHY_READ_IND:
if (get_gap()._pal_event_handler) {
const hciLeReadPhyCmdCmplEvt_t* evt = (const hciLeReadPhyCmdCmplEvt_t*)msg;
get_gap()._pal_event_handler->on_read_phy( switch (msg->event) {
(hci_error_code_t::type)msg->status, case DM_PHY_READ_IND: {
if (!handler) {
break;
}
const hciLeReadPhyCmdCmplEvt_t *evt = (const hciLeReadPhyCmdCmplEvt_t *) msg;
handler->on_read_phy(
(hci_error_code_t::type) msg->status,
handle, handle,
(ble::phy_t::type)evt->txPhy, (ble::phy_t::type) evt->txPhy,
(ble::phy_t::type)evt->rxPhy (ble::phy_t::type) evt->rxPhy
); );
} }
break; break;
case DM_PHY_UPDATE_IND:
if (get_gap()._pal_event_handler) {
const hciLePhyUpdateEvt_t* evt = (const hciLePhyUpdateEvt_t*)msg;
get_gap()._pal_event_handler->on_phy_update_complete( case DM_PHY_UPDATE_IND: {
(hci_error_code_t::type)msg->status, if (!handler) {
break;
}
const hciLePhyUpdateEvt_t *evt = (const hciLePhyUpdateEvt_t *) msg;
handler->on_phy_update_complete(
(hci_error_code_t::type) msg->status,
handle, handle,
(ble::phy_t::type)evt->txPhy, (ble::phy_t::type) evt->txPhy,
(ble::phy_t::type)evt->rxPhy (ble::phy_t::type) evt->rxPhy
);
}
break;
case DM_PER_ADV_SYNC_EST_IND: {
if (!handler) {
break;
}
const hciLePerAdvSyncEstEvt_t *evt = (const hciLePerAdvSyncEstEvt_t *) msg;
handler->on_periodic_advertising_sync_established(
hci_error_code_t(evt->status),
evt->syncHandle,
evt->advSid,
connection_peer_address_type_t(evt->advAddrType),
evt->advAddr,
phy_t(evt->advPhy),
evt->perAdvInterval,
clock_accuracy_t(evt->clockAccuracy)
);
}
break;
case DM_PER_ADV_REPORT_IND: {
if (!handler) {
break;
}
const hciLePerAdvReportEvt_t *evt = (const hciLePerAdvReportEvt_t *) msg;
handler->on_periodic_advertising_report(
evt->syncHandle,
evt->txPower,
evt->rssi,
advertising_data_status_t(evt->status),
evt->len,
evt->pData
);
}
break;
case DM_PER_ADV_SYNC_LOST_IND: {
if (!handler) {
break;
}
const hciLePerAdvSyncLostEvt_t *evt = (const hciLePerAdvSyncLostEvt_t *) msg;
handler->on_periodic_advertising_sync_loss(evt->syncHandle);
}
break;
case DM_CONN_OPEN_IND: {
if (!handler) {
break;
}
// TODO: filter with old event ...
const hciLeConnCmplEvt_t *evt = (const hciLeConnCmplEvt_t *) msg;
handler->on_enhanced_connection_complete(
hci_error_code_t(evt->status),
evt->handle,
connection_role_t(evt->role),
connection_peer_address_type_t(evt->addrType),
evt->peerAddr,
evt->localRpa,
evt->peerRpa,
evt->connInterval,
evt->connLatency,
evt->supTimeout,
clock_accuracy_t(evt->clockAccuracy)
);
}
break;
case DM_SCAN_REQ_RCVD_IND: {
if (!handler) {
break;
}
const hciLeScanReqRcvdEvt_t *evt = (const hciLeScanReqRcvdEvt_t *) msg;
handler->on_scan_request_received(
evt->advHandle,
connection_peer_address_type_t(evt->scanAddrType),
evt->scanAddr
);
}
break;
case DM_ADV_SET_STOP_IND: {
if (!handler) {
break;
}
const hciLeAdvSetTermEvt_t *evt = (const hciLeAdvSetTermEvt_t *) msg;
handler->on_advertising_set_terminated(
hci_error_code_t(evt->status),
evt->advHandle,
evt->handle,
evt->numComplEvts
);
}
break;
case DM_EXT_SCAN_STOP_IND: {
if (!handler) {
break;
}
const hciLeScanTimeoutEvt_t *evt = (const hciLeScanTimeoutEvt_t *) msg;
handler->on_scan_timeout();
}
break;
case DM_EXT_SCAN_REPORT_IND: {
if (!handler) {
break;
}
const hciLeExtAdvReportEvt_t *evt = (const hciLeExtAdvReportEvt_t *) msg;
connection_peer_address_type_t addr_type(evt->addrType);
phy_t sec_phy(evt->secPhy);
handler->on_extended_advertising_report(
advertising_event_t(evt->eventType),
(evt->addrType == HCI_ADDR_TYPE_ANONYMOUS) ? NULL : &addr_type,
evt->addr,
phy_t(evt->priPhy),
evt->secPhy == HCI_ADV_RPT_PHY_SEC_NONE ? NULL : &sec_phy,
evt->advSid,
evt->txPower,
evt->rssi,
evt->perAdvInter,
direct_address_type_t(evt->directAddrType),
evt->directAddr,
evt->len,
evt->pData
);
}
break;
case DM_CONN_UPDATE_IND: {
if (!handler) {
break;
}
const hciLeConnUpdateCmplEvt_t *evt = (const hciLeConnUpdateCmplEvt_t *) msg;
handler->on_connection_update_complete(
(hci_error_code_t::type) evt->status,
evt->hdr.param,
evt->connInterval,
evt->connLatency,
evt->supTimeout
);
}
break;
case DM_REM_CONN_PARAM_REQ_IND: {
if (!handler) {
break;
}
const hciLeRemConnParamReqEvt_t *evt = (const hciLeRemConnParamReqEvt_t *) msg;
handler->on_remote_connection_parameter(
evt->hdr.param,
evt->intervalMin,
evt->intervalMax,
evt->latency,
evt->timeout
); );
} }
break; break;
@ -439,7 +646,7 @@ void Gap::gap_handler(const wsfMsgHdr_t* msg) {
// traverse all handlers and execute them with the event in input. // traverse all handlers and execute them with the event in input.
// exit if an handler has handled the event. // exit if an handler has handled the event.
for(size_t i = 0; i < (sizeof(handlers)/sizeof(handlers[0])); ++i) { for (size_t i = 0; i < (sizeof(handlers) / sizeof(handlers[0])); ++i) {
if (handlers[i](msg)) { if (handlers[i](msg)) {
return; return;
} }
@ -450,14 +657,430 @@ void Gap::gap_handler(const wsfMsgHdr_t* msg) {
* T shall define a can_convert and convert function and a type * T shall define a can_convert and convert function and a type
*/ */
template<typename T> template<typename T>
bool Gap::event_handler(const wsfMsgHdr_t* msg) { bool Gap::event_handler(const wsfMsgHdr_t *msg)
{
if (T::can_convert(msg)) { if (T::can_convert(msg)) {
get_gap().emit_gap_event(T::convert((const typename T::type*)msg)); get_gap().emit_gap_event(T::convert((const typename T::type *) msg));
return true; return true;
} }
return false; return false;
} }
ble_error_t Gap::set_advertising_set_random_address(
advertising_handle_t advertising_handle,
const address_t &address
)
{
DmAdvSetRandAddr(advertising_handle, address.data());
return BLE_ERROR_NONE;
}
ble_error_t Gap::set_extended_advertising_parameters(
advertising_handle_t advertising_handle,
advertising_event_properties_t event_properties,
advertising_interval_t primary_advertising_interval_min,
advertising_interval_t primary_advertising_interval_max,
advertising_channel_map_t primary_advertising_channel_map,
own_address_type_t own_address_type,
advertising_peer_address_type_t peer_address_type,
const address_t &peer_address,
advertising_filter_policy_t advertising_filter_policy,
advertising_power_t advertising_power,
phy_t primary_advertising_phy,
uint8_t secondary_advertising_max_skip,
phy_t secondary_phy,
uint8_t advertising_sid,
bool scan_request_notification
)
{
DmAdvSetInterval(
advertising_handle,
primary_advertising_interval_min,
primary_advertising_interval_max
);
DmAdvSetAddrType(own_address_type.value());
DmAdvSetChannelMap(
advertising_handle,
primary_advertising_channel_map.value()
);
DmDevSetExtFilterPolicy(
advertising_handle,
DM_FILT_POLICY_MODE_ADV,
advertising_filter_policy.value()
);
DmAdvScanReqNotifEnable(advertising_handle, scan_request_notification);
DmAdvSetPhyParam(
advertising_handle,
primary_advertising_phy.value(),
secondary_advertising_max_skip,
secondary_phy.value()
);
DmAdvIncTxPwr(
advertising_handle,
event_properties.include_tx_power,
advertising_power
);
DmAdvUseLegacyPdu(advertising_handle, event_properties.use_legacy_pdu);
DmAdvOmitAdvAddr(advertising_handle, event_properties.omit_advertiser_address);
DmAdvConfig(
advertising_handle,
event_properties.value(), // TODO: use the raw value here ???
peer_address_type.value(),
const_cast<uint8_t *>(peer_address.data())
);
return BLE_ERROR_NONE;
}
ble_error_t Gap::set_periodic_advertising_parameters(
advertising_handle_t advertising_handle,
periodic_advertising_interval_t periodic_advertising_min,
periodic_advertising_interval_t periodic_advertising_max,
bool advertise_power
)
{
DmPerAdvIncTxPwr(advertising_handle, advertise_power);
DmPerAdvSetInterval(
advertising_handle,
periodic_advertising_min,
periodic_advertising_max
);
DmPerAdvConfig(advertising_handle);
return BLE_ERROR_NONE;
}
ble_error_t Gap::set_extended_advertising_data(
advertising_handle_t advertising_handle,
advertising_fragment_description_t operation,
bool minimize_fragmentation,
uint8_t advertising_data_size,
const uint8_t *advertising_data
)
{
uint8_t frag_pref = minimize_fragmentation ?
HCI_ADV_DATA_FRAG_PREF_NO_FRAG :
HCI_ADV_DATA_FRAG_PREF_FRAG;
DmAdvSetFragPref(advertising_handle, frag_pref);
DmAdvSetData(
advertising_handle,
operation.value(),
DM_DATA_LOC_ADV,
advertising_data_size,
const_cast<uint8_t *>(advertising_data)
);
return BLE_ERROR_NONE;
}
ble_error_t Gap::set_periodic_advertising_data(
advertising_handle_t advertising_handle,
advertising_fragment_description_t fragment_description,
uint8_t advertising_data_size,
const uint8_t *advertising_data
)
{
DmPerAdvSetData(
advertising_handle,
fragment_description.value(),
advertising_data_size,
const_cast<uint8_t *>(advertising_data)
);
return BLE_ERROR_NONE;
}
ble_error_t Gap::set_extended_scan_response_data(
advertising_handle_t advertising_handle,
advertising_fragment_description_t operation,
bool minimize_fragmentation,
uint8_t scan_response_data_size,
const uint8_t *scan_response_data
)
{
uint8_t frag_pref = minimize_fragmentation ?
HCI_ADV_DATA_FRAG_PREF_NO_FRAG :
HCI_ADV_DATA_FRAG_PREF_FRAG;
DmAdvSetFragPref(advertising_handle, frag_pref);
DmAdvSetData(
advertising_handle,
operation.value(),
DM_DATA_LOC_SCAN,
scan_response_data_size,
const_cast<uint8_t *>(scan_response_data)
);
return BLE_ERROR_NONE;
}
ble_error_t Gap::extended_advertising_enable(
bool enable,
uint8_t number_of_sets,
const advertising_handle_t *handles,
const uint16_t *durations,
const uint8_t *max_extended_advertising_events
)
{
if (enable) {
uint16_t *durations_ms = new uint16_t[number_of_sets];
for (size_t i = 0; i < number_of_sets; ++i) {
uint32_t r = durations[i] * 10;
durations_ms[i] = r > 0xFFFF ? 0xFFFF : r;
}
DmAdvStart(
number_of_sets,
const_cast<uint8_t *>(handles),
durations_ms,
const_cast<uint8_t *>(max_extended_advertising_events)
);
delete[] durations_ms;
} else {
DmAdvStop(
number_of_sets,
const_cast<uint8_t *>(handles)
);
}
return BLE_ERROR_NONE;
}
ble_error_t Gap::periodic_advertising_enable(
bool enable,
advertising_handle_t advertising_handle
)
{
if (enable) {
DmPerAdvStart(advertising_handle);
} else {
DmPerAdvStop(advertising_handle);
}
return BLE_ERROR_NONE;
}
uint16_t Gap::get_maximum_advertising_data_length()
{
return HciGetMaxAdvDataLen();
}
uint8_t Gap::get_max_number_of_advertising_sets()
{
return HciGetNumSupAdvSets();
}
ble_error_t Gap::remove_advertising_set(advertising_handle_t advertising_handle)
{
DmAdvRemoveAdvSet(advertising_handle);
return BLE_ERROR_NONE;
}
ble_error_t Gap::clear_advertising_sets()
{
DmAdvClearAdvSets();
return BLE_ERROR_NONE;
}
ble_error_t Gap::set_extended_scan_parameters(
own_address_type_t own_address_type,
scanning_filter_policy_t filter_policy,
phy_set_t scanning_phys,
const bool *active_scanning,
const uint16_t *scan_interval,
const uint16_t *scan_window
)
{
DmScanSetAddrType(own_address_type.value());
for (size_t i = 0, count = scanning_phys.count(); i < count; ++i) {
extended_scan_type[i] = active_scanning[i] ?
DM_SCAN_TYPE_ACTIVE :
DM_SCAN_TYPE_PASSIVE;
}
this->scanning_phys = scanning_phys;
DmScanSetInterval(
scanning_phys.value(),
const_cast<uint16_t *>(scan_interval),
const_cast<uint16_t *>(scan_window)
);
DmDevSetFilterPolicy(
DM_FILT_POLICY_MODE_SCAN,
filter_policy.value()
);
return BLE_ERROR_NONE;
}
ble_error_t Gap::extended_scan_enable(
bool enable,
duplicates_filter_t filter_duplicates,
uint16_t duration,
uint16_t period
)
{
if (enable) {
uint32_t duration_ms = duration * 10;
DmScanModeExt();
DmScanStart(
scanning_phys.value(),
DM_DISC_MODE_NONE,
extended_scan_type,
filter_duplicates.value(), // TODO: cordio API incomplete ???
duration_ms > 0xFFFF ? 0xFFFF : duration_ms,
period
);
} else {
DmScanStop();
}
return BLE_ERROR_NONE;
}
ble_error_t Gap::periodic_advertising_create_sync(
bool use_periodic_advertiser_list,
uint8_t advertising_sid,
peer_address_type_t peer_address_type,
const address_t &peer_address,
uint16_t allowed_skip,
uint16_t sync_timeout
)
{
if (use_periodic_advertiser_list) {
DmDevSetExtFilterPolicy(
DM_ADV_HANDLE_DEFAULT,
DM_FILT_POLICY_MODE_SYNC,
HCI_FILT_PER_ADV_LIST
);
}
DmSyncStart(
advertising_sid,
peer_address_type.value(),
peer_address.data(),
allowed_skip,
sync_timeout
);
return BLE_ERROR_INVALID_PARAM;
}
ble_error_t Gap::cancel_periodic_advertising_create_sync()
{
// FIXME: Find a way to use it!
// Function not directly exposed by the cordio stack.
return BLE_ERROR_NOT_IMPLEMENTED;
}
ble_error_t Gap::periodic_advertising_terminate_sync(sync_handle_t sync_handle)
{
DmSyncStop(sync_handle);
return BLE_ERROR_NONE;
}
ble_error_t Gap::add_device_to_periodic_advertiser_list(
advertising_peer_address_type_t advertiser_address_type,
const address_t &advertiser_address,
uint8_t advertising_sid
)
{
DmAddDeviceToPerAdvList(
advertiser_address_type.value(),
const_cast<uint8_t *>(advertiser_address.data()),
advertising_sid
);
return BLE_ERROR_NONE;
}
ble_error_t Gap::remove_device_from_periodic_advertiser_list(
advertising_peer_address_type_t advertiser_address_type,
const address_t &advertiser_address,
uint8_t advertising_sid
)
{
DmRemoveDeviceFromPerAdvList(
advertiser_address_type.value(),
const_cast<uint8_t *>(advertiser_address.data()),
advertising_sid
);
return BLE_ERROR_NONE;
}
ble_error_t Gap::clear_periodic_advertiser_list()
{
DmClearPerAdvList();
return BLE_ERROR_NONE;
}
uint8_t Gap::read_periodic_advertiser_list_size()
{
return HciGetPerAdvListSize();
}
ble_error_t Gap::extended_create_connection(
initiator_policy_t initiator_policy,
own_address_type_t own_address_type,
peer_address_type_t peer_address_type,
const address_t &peer_address,
phy_set_t initiating_phys,
const uint16_t *scan_intervals,
const uint16_t *scan_windows,
const uint16_t *connection_intervals_min,
const uint16_t *connection_intervals_max,
const uint16_t *connection_latencies,
const uint16_t *supervision_timeouts,
const uint16_t *minimum_connection_event_lengths,
const uint16_t *maximum_connection_event_lengths
)
{
DmExtConnSetScanInterval(
initiating_phys.value(),
const_cast<uint16_t *>(scan_intervals),
const_cast<uint16_t *>(scan_windows)
);
DmDevSetFilterPolicy(DM_FILT_POLICY_MODE_INIT, initiator_policy.value());
DmConnSetAddrType(own_address_type.value());
// At most 3 phys are in used
hciConnSpec_t conn_specs[3];
for (size_t i = 0, count = initiating_phys.count(); i < count; ++i) {
conn_specs[i].connIntervalMin = connection_intervals_min[i];
conn_specs[i].connIntervalMax = connection_intervals_max[i];
conn_specs[i].connLatency = connection_latencies[i];
conn_specs[i].supTimeout = supervision_timeouts[i];
conn_specs[i].minCeLen = minimum_connection_event_lengths[i];
conn_specs[i].maxCeLen = maximum_connection_event_lengths[i];
}
DmExtConnSetConnSpec(initiating_phys.value(), conn_specs);
dmConnId_t connection_id = DmConnOpen(
DM_CLIENT_ID_APP,
initiating_phys.value(),
peer_address_type.value(),
const_cast<uint8_t *>(peer_address.data())
);
if (connection_id == DM_CONN_ID_NONE) {
return BLE_ERROR_INTERNAL_STACK_FAILURE;
}
return BLE_ERROR_NONE;
}
} // cordio } // cordio
} // vendor } // vendor

View File

@ -443,7 +443,7 @@ ble_error_t CordioSecurityManager::cancel_pairing(
ble_error_t CordioSecurityManager::get_random_data(byte_array_t<8> &random_data) ble_error_t CordioSecurityManager::get_random_data(byte_array_t<8> &random_data)
{ {
SecRand(random_data.data(), random_data.size()); SecRand(random_data.data(), random_data.size());
return BLE_ERROR_NOT_IMPLEMENTED; return BLE_ERROR_NONE;
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////

View File

@ -79,7 +79,7 @@ peer_address_type_t convert_nordic_address(uint8_t address) {
} }
peer_address_type_t convert_identity_address(advertising_peer_address_type_t address) { peer_address_type_t convert_identity_address(advertising_peer_address_type_t address) {
if (address == advertising_peer_address_type_t::PUBLIC_ADDRESS) { if (address == advertising_peer_address_type_t::PUBLIC) {
return peer_address_type_t::PUBLIC_IDENTITY; return peer_address_type_t::PUBLIC_IDENTITY;
} else { } else {
return peer_address_type_t::RANDOM_STATIC_IDENTITY; return peer_address_type_t::RANDOM_STATIC_IDENTITY;

View File

@ -988,10 +988,10 @@ bool nRF5xSecurityManager::sm_handler(const ble_evt_t *evt)
); );
advertising_peer_address_type_t advertising_peer_address_type_t
address_type(advertising_peer_address_type_t::PUBLIC_ADDRESS); address_type(advertising_peer_address_type_t::PUBLIC);
if (pairing_cb->peer_id_key.id_addr_info.addr_type) { if (pairing_cb->peer_id_key.id_addr_info.addr_type) {
address_type = advertising_peer_address_type_t::RANDOM_ADDRESS; address_type = advertising_peer_address_type_t::RANDOM;
} }
handler->on_keys_distributed_bdaddr( handler->on_keys_distributed_bdaddr(

View File

@ -90,7 +90,7 @@ public:
struct resolving_list_entry_t { struct resolving_list_entry_t {
resolving_list_entry_t() : resolving_list_entry_t() :
peer_identity_address_type( peer_identity_address_type(
advertising_peer_address_type_t::PUBLIC_ADDRESS advertising_peer_address_type_t::PUBLIC
) )
{ } { }

View File

@ -108,7 +108,7 @@ peer_address_type_t convert_nordic_address(bool identity, uint8_t address) {
} }
peer_address_type_t convert_identity_address(advertising_peer_address_type_t address) { peer_address_type_t convert_identity_address(advertising_peer_address_type_t address) {
if (address == advertising_peer_address_type_t::PUBLIC_ADDRESS) { if (address == advertising_peer_address_type_t::PUBLIC) {
return peer_address_type_t::PUBLIC_IDENTITY; return peer_address_type_t::PUBLIC_IDENTITY;
} else { } else {
return peer_address_type_t::RANDOM_STATIC_IDENTITY; return peer_address_type_t::RANDOM_STATIC_IDENTITY;

View File

@ -1022,10 +1022,10 @@ bool nRF5xSecurityManager::sm_handler(const ble_evt_t *evt)
); );
advertising_peer_address_type_t advertising_peer_address_type_t
address_type(advertising_peer_address_type_t::PUBLIC_ADDRESS); address_type(advertising_peer_address_type_t::PUBLIC);
if (pairing_cb->peer_id_key.id_addr_info.addr_type) { if (pairing_cb->peer_id_key.id_addr_info.addr_type) {
address_type = advertising_peer_address_type_t::RANDOM_ADDRESS; address_type = advertising_peer_address_type_t::RANDOM;
} }
handler->on_keys_distributed_bdaddr( handler->on_keys_distributed_bdaddr(

View File

@ -790,6 +790,7 @@ typedef enum _mbed_error_code {
MBED_DEFINE_SYSTEM_ERROR(ASSERTION_FAILED, 68), /* 324 Assertion Failed */ MBED_DEFINE_SYSTEM_ERROR(ASSERTION_FAILED, 68), /* 324 Assertion Failed */
MBED_DEFINE_SYSTEM_ERROR(AUTHENTICATION_FAILED, 69), /* 325 Authentication Failed */ MBED_DEFINE_SYSTEM_ERROR(AUTHENTICATION_FAILED, 69), /* 325 Authentication Failed */
MBED_DEFINE_SYSTEM_ERROR(RBP_AUTHENTICATION_FAILED, 70), /* 326 Rollback Protection Authentication Failed */ MBED_DEFINE_SYSTEM_ERROR(RBP_AUTHENTICATION_FAILED, 70), /* 326 Rollback Protection Authentication Failed */
MBED_DEFINE_SYSTEM_ERROR(BLE_USE_INCOMPATIBLE_API, 71), /* 327 Concurrent use of incompatible versions of a BLE API */
//Everytime you add a new system error code, you must update //Everytime you add a new system error code, you must update
//Error documentation under Handbook to capture the info on //Error documentation under Handbook to capture the info on