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

View File

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

View File

@ -22,6 +22,7 @@
#include <string.h>
#include "ble/SafeEnum.h"
#include "ble/ArrayView.h"
#include "ble/gap/Types.h"
/**
* @addtogroup ble
@ -32,6 +33,43 @@
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.
*
@ -48,7 +86,6 @@ typedef uintptr_t connection_handle_t;
*/
typedef uint16_t attribute_handle_t;
/**
* 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());
}
/**
* Model fixed size array values.
* @tparam array_size The size of the array.
*/
template <size_t array_size>
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.
*/
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 scoped enum wrapped by the class */
enum type {
/**
* No phy selected.
*
* @note This value can be used to indicate the absence of phy
*/
NONE = 0,
/**
* 1Mbit/s LE.
*
@ -625,6 +678,8 @@ struct phy_t : SafeEnum<phy_t, uint8_t> {
*/
phy_t(type 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_coded Prefer coded modulation if avaiable
*/
phy_set_t(
bool phy_1m,
bool phy_2m,
bool phy_coded
) {
phy_set_t(bool phy_1m, bool phy_2m, bool phy_coded) :
_value()
{
set_1m(phy_1m);
set_2m(phy_2m);
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. */
void set_1m(bool enabled = true) {
if (enabled) {
@ -715,6 +790,10 @@ public:
return _value;
}
uint8_t count() const {
return (get_1m() ? 1 : 0) + (get_2m() ? 1 : 0) + (get_coded() ? 1 : 0);
}
private:
uint8_t _value;
};

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef MBED_GAP_ADVERTISING_DATA_H__
#define MBED_GAP_ADVERTISING_DATA_H__
#ifndef MBED_GAP_ADVERTISING_DATA__LEGACY_H__
#define MBED_GAP_ADVERTISING_DATA__LEGACY_H__
#include <stdint.h>
#include <string.h>
@ -109,6 +109,10 @@
* some basic checks on the payload length and tries to avoid common
* errors such as adding an exclusive AD field twice in the advertising
* 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
{
@ -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__
#define __GATT_CHARACTERISTIC_H__
#include "Gap.h"
#include "ble/Gap.h"
#include "SecurityManager.h"
#include "GattAttribute.h"
#include "GattCallbackParamTypes.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -210,6 +210,11 @@ enum ble_error_t {
* The platform-specific stack failed.
*/
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,22 +42,27 @@ namespace generic {
*
* @attention: Not part of the public interface of BLE API.
*/
class GenericGap : public ::Gap,
public pal::ConnectionEventMonitor,
public pal::Gap::EventHandler {
class GenericGap :
public ::Gap,
public pal::ConnectionEventMonitor,
public pal::Gap::EventHandler {
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
* primitives.
*
* @param generic_access_service Platform abstraction instance managing
* the GATT generic access service.
*
*
* @param pal_sm Security Manager Platform abstraction instance containing the base
* Security Manager primitives.
*/
@ -73,6 +78,157 @@ public:
*/
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
*/
@ -134,6 +290,48 @@ public:
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
*/
@ -143,18 +341,23 @@ public:
* @see Gap::setPreferredPhys
*/
virtual ble_error_t setPreferredPhys(
const phy_set_t* txPhys,
const phy_set_t* rxPhys
const phy_set_t *txPhys,
const phy_set_t *rxPhys
);
/**
* @see Gap::setPhy
*/
virtual ble_error_t setPhy(
Handle_t connection,
const phy_set_t* txPhys,
const phy_set_t* rxPhys,
CodedSymbolPerBit_t codedSymbol
Handle_t connection,
const phy_set_t *txPhys,
const phy_set_t *rxPhys,
CodedSymbolPerBit_t codedSymbol
);
virtual ble_error_t disconnect(
connection_handle_t connectionHandle,
local_disconnection_reason_t reason
);
/**
@ -326,7 +529,7 @@ public:
/**
* @copydoc ::Gap::processConnectionEvent
*/
void processConnectionEvent(
virtual void processConnectionEvent(
Handle_t handle,
Role_t role,
peer_address_type_t peerAddrType,
@ -341,12 +544,19 @@ public:
/**
* @copydoc ::Gap::processDisconnectionEvent
*/
void processDisconnectionEvent(
virtual void processDisconnectionEvent(
Handle_t handle,
DisconnectionReason_t reason
);
private:
ble_error_t setAdvertisingData(
advertising_handle_t handle,
mbed::Span<const uint8_t> payload,
bool minimiseFragmentation,
bool scan_response
);
/** @note Implements ConnectionEventMonitor.
* @copydoc ConnectionEventMonitor::set_connection_event_handler
*/
@ -393,26 +603,113 @@ private:
void update_random_address();
bool getUnresolvableRandomAddress(ble::address_t &address);
void on_address_rotation_timeout();
virtual void useVersionOneAPI() const;
virtual void useVersionTwoAPI() const;
/* implements pal::Gap::EventHandler */
private:
virtual void on_read_phy(
pal::hci_error_code_t hci_status,
Handle_t connection_handle,
ble::phy_t tx_phy,
ble::phy_t rx_phy
phy_t tx_phy,
phy_t rx_phy
);
virtual void on_phy_update_complete(
pal::hci_error_code_t hci_status,
Handle_t connection_handle,
ble::phy_t tx_phy,
ble::phy_t rx_phy
phy_t tx_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:
pal::EventQueue& _event_queue;
pal::EventQueue &_event_queue;
pal::Gap &_pal_gap;
pal::GenericAccessService &_gap_service;
pal::SecurityManager &_pal_sm;
@ -422,17 +719,80 @@ private:
pal::scanning_filter_policy_t _scanning_filter_policy;
pal::advertising_filter_policy_t _advertising_filter_policy;
mutable Whitelist_t _whitelist;
bool _privacy_enabled;
PeripheralPrivacyConfiguration_t _peripheral_privacy_configuration;
CentralPrivacyConfiguration_t _central_privacy_configuration;
ble::address_t _random_static_identity_address;
bool _random_address_rotating;
mbed::Timeout _advertising_timeout;
mbed::Timeout _scan_timeout;
mbed::Ticker _address_rotation_ticker;
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
*/
virtual ble_error_t launchServiceDiscovery(
Gap::Handle_t connection_handle,
connection_handle_t connection_handle,
ServiceDiscovery::ServiceCallback_t service_callback,
ServiceDiscovery::CharacteristicCallback_t characteristic_callback,
const UUID& matching_service_uuid,
@ -65,7 +65,7 @@ public:
* @see GattClient::read
*/
virtual ble_error_t read(
Gap::Handle_t connection_handle,
connection_handle_t connection_handle,
GattAttribute::Handle_t attribute_handle,
uint16_t offset
) const;
@ -75,7 +75,7 @@ public:
*/
virtual ble_error_t write(
GattClient::WriteOp_t cmd,
Gap::Handle_t connection_handle,
connection_handle_t connection_handle,
GattAttribute::Handle_t attribute_handle,
size_t length,
const uint8_t* value
@ -128,18 +128,18 @@ private:
struct WriteControlBlock;
struct DescriptorDiscoveryControlBlock;
ProcedureControlBlock* get_control_block(Gap::Handle_t connection);
const ProcedureControlBlock* get_control_block(Gap::Handle_t connection) const;
ProcedureControlBlock* get_control_block(connection_handle_t connection);
const ProcedureControlBlock* get_control_block(connection_handle_t connection) const;
void insert_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_response(connection_handle_t, const pal::AttServerMessage&);
void on_server_event(connection_handle_t, const pal::AttServerMessage&);
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;
ServiceDiscovery::TerminationCallback_t _termination_callback;

View File

@ -68,7 +68,7 @@ public:
virtual ble_error_t purgeAllBondingState();
virtual ble_error_t generateWhitelistFromBondTable(
Gap::Whitelist_t *whitelist
::Gap::Whitelist_t *whitelist
) const;
////////////////////////////////////////////////////////////////////////////
@ -398,12 +398,12 @@ private:
*/
virtual void on_connected(
connection_handle_t connection,
Gap::Role_t role,
::Gap::Role_t role,
peer_address_type_t peer_address_type,
const BLEProtocol::AddressBytes_t peer_address,
BLEProtocol::AddressType_t local_address_type,
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(
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),
role(role),
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::RANDOM
),

View File

@ -24,108 +24,11 @@
namespace ble {
namespace pal {
/**
* 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::advertising_type_t advertising_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::own_address_type_t own_address_type_t;
typedef ble::target_peer_address_type_t advertising_peer_address_type_t;
/**
* 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> {
enum type {
/**
* Public device address
* Public device address.
*/
PUBLIC_ADDRESS = 0x00,
/**
* Random device address
* Random device address.
*/
RANDOM_ADDRESS = 0x01,
@ -160,7 +63,14 @@ struct connection_peer_address_type_t :
* Construct a new connection_peer_address_type_t instance.
*/
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.
*/
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.
*/
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.
*/
hci_error_code_t(type value) :
SafeEnum<hci_error_code_t, uint8_t>(value) { }
};
/**
* 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
};
SafeEnum<hci_error_code_t, uint8_t>(value)
{
}
/**
* Construct a new disconnection_reason_t instance.
* Construct a new hci_error_code_t from a raw value.
*/
disconnection_reason_t(type value) :
SafeEnum<disconnection_reason_t, uint8_t>(value) { }
explicit hci_error_code_t(uint8_t raw_value) :
SafeEnum<hci_error_code_t, uint8_t>(static_cast<type>(raw_value))
{
}
};
/**
* 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,
typedef ble::local_disconnection_reason_t disconnection_reason_t;
/**
* Process connection requests from all devices but filter out scan requests
* of devices which are not in the whitelist.
*/
FILTER_SCAN_REQUESTS = 0x01,
typedef ble::advertising_filter_policy_t advertising_filter_policy_t;
/**
* 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) { }
};
typedef ble::scanning_filter_policy_t scanning_filter_policy_t;
typedef ble::initiator_filter_policy_t initiator_policy_t;
/**
* Hold advertising data.
@ -419,7 +245,8 @@ struct advertising_data_t {
*
* @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));
}
@ -430,7 +257,8 @@ struct advertising_data_t {
*
* @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));
memcpy(value, input_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.
*/
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;
}
@ -449,29 +278,33 @@ struct advertising_data_t {
* Non equal operator between two advertising data.
*/
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);
}
/**
* 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 a pointer to the advertising data buffer.
*/
const uint8_t* data() const {
const uint8_t *data() const
{
return value;
}
/**
* Return (fixed) size of advertising data.
*/
uint8_t size() const {
uint8_t size() const
{
return sizeof(value);
}
@ -515,22 +348,303 @@ struct received_advertising_type_t :
* Construct a new received_advertising_type_t 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 {
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 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)];
/**
* @class URIBeaconConfigService
* @brief UriBeacon Configuration Service. Can be used to set URL, adjust power levels, and set flags.
* See http://uribeacon.org
*
*/
* @class URIBeaconConfigService
* @brief UriBeacon Configuration Service. You can use this to set URL, adjust power levels and set flags.
* 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 {
public:
/**
@ -89,7 +94,13 @@ class URIBeaconConfigService {
* Default un-encoded URI. Applies only if the resetToDefaultsFlag is true.
* @param[in] defaultAdvPowerLevelsIn
* 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,
Params_t &paramsIn,
bool resetToDefaultsFlag,

View File

@ -81,7 +81,13 @@
* The licence also grant access to the iBeacons technical specification.
*
* @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
{
public:
@ -197,7 +203,13 @@ public:
* to the beacon.
*
* @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(
BLE &_ble,
LocationUUID_t uuid,

View File

@ -383,5 +383,133 @@ ble_error_t BLE::disconnect(Gap::DisconnectionReason_t 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

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.
*/
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) { }
virtual ~ProcedureControlBlock() { }
@ -87,7 +87,7 @@ struct GenericGattClient::ProcedureControlBlock {
virtual void abort(GenericGattClient *client) = 0;
procedure_type_t type;
Gap::Handle_t connection_handle;
connection_handle_t connection_handle;
ProcedureControlBlock* next;
};
@ -97,7 +97,7 @@ struct GenericGattClient::ProcedureControlBlock {
*/
struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock {
DiscoveryControlBlock(
Gap::Handle_t handle,
connection_handle_t handle,
ServiceDiscovery::ServiceCallback_t service_callback,
ServiceDiscovery::CharacteristicCallback_t characteristic_callback,
UUID matching_service_uuid,
@ -307,7 +307,7 @@ struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock {
void terminate(GenericGattClient* client) {
// unknown error, terminate the procedure immediately
client->remove_control_block(this);
Gap::Handle_t handle = connection_handle;
connection_handle_t handle = connection_handle;
delete this;
client->on_termination(handle);
}
@ -356,7 +356,7 @@ struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock {
characteristic_t(
GattClient* client,
Gap::Handle_t connection_handle,
connection_handle_t connection_handle,
uint16_t decl_handle,
const ArrayView<const uint8_t> value
) : DiscoveredCharacteristic() {
@ -428,7 +428,7 @@ struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock {
struct GenericGattClient::ReadControlBlock : public ProcedureControlBlock {
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),
attribute_handle(attribute_handle),
offset(offset), current_offset(offset), data(NULL) {
@ -625,7 +625,7 @@ struct GenericGattClient::ReadControlBlock : public ProcedureControlBlock {
*/
struct GenericGattClient::WriteControlBlock : public ProcedureControlBlock {
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
) : ProcedureControlBlock(WRITE_PROCEDURE, connection_handle),
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(
Gap::Handle_t connection_handle,
connection_handle_t connection_handle,
ServiceDiscovery::ServiceCallback_t service_callback,
ServiceDiscovery::CharacteristicCallback_t characteristic_callback,
const UUID& matching_service_uuid,
@ -1030,7 +1030,7 @@ void GenericGattClient::terminateServiceDiscovery()
}
ble_error_t GenericGattClient::read(
Gap::Handle_t connection_handle,
connection_handle_t connection_handle,
GattAttribute::Handle_t attribute_handle,
uint16_t offset) const
{
@ -1073,7 +1073,7 @@ ble_error_t GenericGattClient::read(
ble_error_t GenericGattClient::write(
GattClient::WriteOp_t cmd,
Gap::Handle_t connection_handle,
connection_handle_t connection_handle,
GattAttribute::Handle_t attribute_handle,
size_t length,
const uint8_t* value
@ -1279,7 +1279,7 @@ void GenericGattClient::set_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) {
_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) {
GattHVXCallbackParams callbacks_params = {
(Gap::Handle_t) connection, 0
(connection_handle_t) connection, 0
};
switch (message.opcode) {
@ -1368,7 +1368,7 @@ void GenericGattClient::on_transaction_timeout(connection_handle_t connection) {
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;
while (it && it->connection_handle != connection) {
it = it->next;
@ -1376,7 +1376,7 @@ GenericGattClient::ProcedureControlBlock* GenericGattClient::get_control_block(G
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;
while (it && it->connection_handle != connection) {
it = it->next;
@ -1420,7 +1420,7 @@ void GenericGattClient::remove_control_block(ProcedureControlBlock* cb) const {
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;
if(_pal_client->get_mtu_size((connection_handle_t) connection, result) != BLE_ERROR_NONE) {
result = 23;

View File

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

View File

@ -86,7 +86,7 @@ public:
* @see ::GattServer::read
*/
virtual ble_error_t read(
Gap::Handle_t connectionHandle,
connection_handle_t connectionHandle,
GattAttribute::Handle_t attributeHandle,
uint8_t buffer[], uint16_t *lengthP
);
@ -104,7 +104,7 @@ public:
* @see ::GattServer::write
*/
virtual ble_error_t write(
Gap::Handle_t connectionHandle,
connection_handle_t connectionHandle,
GattAttribute::Handle_t,
const uint8_t[],
uint16_t,
@ -122,7 +122,7 @@ public:
* @see ::GattServer::areUpdatesEnabled
*/
virtual ble_error_t areUpdatesEnabled(
Gap::Handle_t connectionHandle,
connection_handle_t connectionHandle,
const GattCharacteristic &characteristic,
bool *enabledP
);
@ -224,7 +224,7 @@ private:
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_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 {
alloc_block_t* next;

View File

@ -15,7 +15,7 @@ namespace cordio {
class Gap : public ::ble::pal::Gap {
public:
virtual bool is_feature_supported(
Gap::ControllerSupportedFeatures_t feature
ble::controller_supported_features_t feature
);
virtual ble_error_t initialize();
@ -153,6 +153,145 @@ public:
*/
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:
/**
* T shall define a can_convert and convert function and a type
@ -270,6 +409,8 @@ private:
private:
address_t device_random_address;
bool use_active_scanning;
uint8_t extended_scan_type[3];
phy_set_t scanning_phys;
};
} // cordio

View File

@ -259,6 +259,15 @@ void BLE::processEvents()
::BLE::Instance(::BLE::DEFAULT_INSTANCE),
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().initialization_status = INITIALIZED;
_init_callback.call(&context);

View File

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

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)
{
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) {
if (address == advertising_peer_address_type_t::PUBLIC_ADDRESS) {
if (address == advertising_peer_address_type_t::PUBLIC) {
return peer_address_type_t::PUBLIC_IDENTITY;
} else {
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
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) {
address_type = advertising_peer_address_type_t::RANDOM_ADDRESS;
address_type = advertising_peer_address_type_t::RANDOM;
}
handler->on_keys_distributed_bdaddr(

View File

@ -90,7 +90,7 @@ public:
struct resolving_list_entry_t {
resolving_list_entry_t() :
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) {
if (address == advertising_peer_address_type_t::PUBLIC_ADDRESS) {
if (address == advertising_peer_address_type_t::PUBLIC) {
return peer_address_type_t::PUBLIC_IDENTITY;
} else {
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
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) {
address_type = advertising_peer_address_type_t::RANDOM_ADDRESS;
address_type = advertising_peer_address_type_t::RANDOM;
}
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(AUTHENTICATION_FAILED, 69), /* 325 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
//Error documentation under Handbook to capture the info on