From ca72f5a28987749b34f8503dfd502f64fd5a18cc Mon Sep 17 00:00:00 2001 From: paul-szczepanek-arm <33840200+paul-szczepanek-arm@users.noreply.github.com> Date: Fri, 9 Nov 2018 13:43:20 +0000 Subject: [PATCH] merged adv param types --- features/FEATURE_BLE/ble/Gap.h | 14 +- features/FEATURE_BLE/ble/GapAdvertisingData.h | 29 ++- .../FEATURE_BLE/ble/GapAdvertisingParams.h | 227 +++++++++++------- features/FEATURE_BLE/ble/generic/GenericGap.h | 2 - .../FEATURE_BLE/source/generic/GenericGap.cpp | 65 ++--- 5 files changed, 187 insertions(+), 150 deletions(-) diff --git a/features/FEATURE_BLE/ble/Gap.h b/features/FEATURE_BLE/ble/Gap.h index c953f0a5fd..b4fc4cb6f4 100644 --- a/features/FEATURE_BLE/ble/Gap.h +++ b/features/FEATURE_BLE/ble/Gap.h @@ -1169,13 +1169,6 @@ public: return BLE_ERROR_NOT_IMPLEMENTED; } - virtual ble_error_t setAdvertisingParams(AdvHandle_t handle, const GapExtendedAdvertisingParams* params) { - (void) handle; - (void) params; - /* Requesting action from porter(s): override this API if this capability is supported. */ - return BLE_ERROR_NOT_IMPLEMENTED; - } - virtual ble_error_t setAdvertisingPayload(AdvHandle_t handle, const AdvertisingData* payload, bool minimiseFragmentation = false) { (void) handle; (void) payload; @@ -1203,6 +1196,7 @@ public: } ble_error_t status = setAdvertisingData(getLegacyAdvertisingPayload(), getLegacyAdvertisingScanResponse()); + if (status != BLE_ERROR_NONE) { return status; } @@ -2461,6 +2455,8 @@ protected: _advParams = new GapAdvertisingParams(); } MBED_ASSERT(_advParams); + /* this setting is now read from the params */ + _advParams->setPolicyMode(getAdvertisingPolicyMode()); return *_advParams; } @@ -2909,7 +2905,7 @@ public: MBED_DEPRECATED_SINCE( "mbed-os-5.11.0", "Deprecated since addition of extended advertising support." - "Use createAdvertisingSet() and use the resulting object's interface." + "This setting is now part of advertising paramters." ) virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode) { @@ -2928,7 +2924,7 @@ public: MBED_DEPRECATED_SINCE( "mbed-os-5.11.0", "Deprecated since addition of extended advertising support." - "Use createAdvertisingSet() and use the resulting object's interface." + "This setting is now part of advertising paramters." ) virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const { diff --git a/features/FEATURE_BLE/ble/GapAdvertisingData.h b/features/FEATURE_BLE/ble/GapAdvertisingData.h index aaaac71909..562a072946 100644 --- a/features/FEATURE_BLE/ble/GapAdvertisingData.h +++ b/features/FEATURE_BLE/ble/GapAdvertisingData.h @@ -534,16 +534,31 @@ public: */ typedef enum Appearance_t Appearance; + /** 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. + */ AdvertisingData(mbed::Span buffer) : _buffer(buffer), _payloadLen(0) { } + /** 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. + */ AdvertisingData(uint8_t* buffer, size_t buffer_size) : _buffer(buffer, buffer_size), _payloadLen(0) { } + /** Return maximum size of the data that can be stored. + * + * @return Size of the buffer used to store the data. + */ size_t getBufferSize() const { return _buffer.size(); } @@ -936,16 +951,16 @@ protected: } protected: + /** The memory backing the the data provided by the user. */ mbed::Span _buffer; - /** - * Length of the data added to the advertising buffer. - */ + /** Length of the data added to the advertising buffer. */ uint8_t _payloadLen; }; -/** - * @deprecated Use AdvertisingData; +/** @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 : public AdvertisingData { @@ -961,9 +976,7 @@ public: } private: - /** - * Advertising data buffer. - */ + /** Advertising data buffer. */ uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD]; }; diff --git a/features/FEATURE_BLE/ble/GapAdvertisingParams.h b/features/FEATURE_BLE/ble/GapAdvertisingParams.h index f1499b5402..c96d7646b5 100644 --- a/features/FEATURE_BLE/ble/GapAdvertisingParams.h +++ b/features/FEATURE_BLE/ble/GapAdvertisingParams.h @@ -22,6 +22,14 @@ #include "blecommon.h" #include "SafeEnum.h" +/* TODO: std::clamp */ +#define CLAMP(value, min, max) \ + if (value > max) { \ + value = max; \ + } else if (value < min) { \ + value = min; \ + } + /** * @addtogroup ble * @{ @@ -87,6 +95,28 @@ public: static const ble::advertising_type_t ADV_SCANNABLE_UNDIRECTED = ble::ADV_SCANNABLE_UNDIRECTED; static const ble::advertising_type_t ADV_NON_CONNECTABLE_UNDIRECTED = ble::ADV_NON_CONNECTABLE_UNDIRECTED; + struct own_address_type_t : ble::SafeEnum { + enum type { + PUBLIC = 0, /**< Public Device Address. */ + RANDOM, /**< Random Device Address. */ + RANDOM_RESOLVABLE_PUBLIC_FALLBACK, /**< Controller generates the Resolvable Private Address based on + the local IRK from the resolving list. If the resolving list + contains no matching entry, use the public address. */ + RANDOM_RESOLVABLE_RANDOM_FALLBACK /**< Controller generates the Resolvable Private Address based on + the local IRK from the resolving list. If the resolving list + contains no matching entry, use previously set random address. */ + }; + own_address_type_t(type value) : ble::SafeEnum(value) { } + }; + + struct peer_address_type_t : ble::SafeEnum { + enum type { + PUBLIC = 0, /**< Public Device Address or Public Identity Address. */ + RANDOM /**< Random Device Address or Random (static) Identity Address. */ + }; + peer_address_type_t(type value) : ble::SafeEnum(value) { } + }; + public: /** * Construct an instance of GapAdvertisingParams. @@ -106,28 +136,36 @@ public: ) : _advType(advType), _interval(interval), - _timeout(timeout) + _maxInterval(0), + _timeout(timeout), + _peerAddressType(peer_address_type_t::PUBLIC), + _ownAddressType(own_address_type_t::PUBLIC), + _policy(ble::ADV_POLICY_IGNORE_WHITELIST), + _primaryPhy(ble::phy_t::LE_1M), + _secondaryPhy(ble::phy_t::LE_1M), + _peerAddress(), + _txPower(127), + _eventNumber(0), + _channel37(1), + _channel38(1), + _channel39(1), + _anonymous(0), + _notifyOnScan(0), + _legacyPDU(1), + _includeHeaderTxPower(0) { /* Interval checks. */ if (_advType == ble::ADV_CONNECTABLE_DIRECTED) { /* Interval must be 0 in directed connectable mode. */ _interval = 0; + _maxInterval = 0; } else if (_advType == ble::ADV_NON_CONNECTABLE_UNDIRECTED) { /* Min interval is slightly larger than in other modes. */ - if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) { - _interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON; - } - if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) { - _interval = GAP_ADV_PARAMS_INTERVAL_MAX; - } + CLAMP(_interval, GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, GAP_ADV_PARAMS_INTERVAL_MAX); + CLAMP(_maxInterval, GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, GAP_ADV_PARAMS_INTERVAL_MAX); } else { - /* Stay within interval limits. */ - if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN) { - _interval = GAP_ADV_PARAMS_INTERVAL_MIN; - } - if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) { - _interval = GAP_ADV_PARAMS_INTERVAL_MAX; - } + CLAMP(_interval, GAP_ADV_PARAMS_INTERVAL_MIN, GAP_ADV_PARAMS_INTERVAL_MAX); + CLAMP(_maxInterval, GAP_ADV_PARAMS_INTERVAL_MIN, GAP_ADV_PARAMS_INTERVAL_MAX); } /* Timeout checks. */ @@ -139,6 +177,7 @@ public: } } +public: /** * Number of microseconds in 0.625 milliseconds. */ @@ -241,68 +280,6 @@ public: _timeout = newTimeout; } -private: - /** - * The advertising type. - */ - ble::advertising_type_t _advType; - - /** - * The advertising interval in ADV duration units (in other words, 0.625ms). - */ - uint16_t _interval; - - /** - * The advertising timeout in seconds. - */ - uint16_t _timeout; -}; - -class GapExtendedAdvertisingParams { -public: - struct own_address_type_t : ble::SafeEnum { - enum type { - PUBLIC = 0, /**< Public Device Address. */ - RANDOM, /**< Random Device Address. */ - RANDOM_RESOLVABLE_PUBLIC_FALLBACK, /**< Controller generates the Resolvable Private Address based on - the local IRK from the resolving list. If the resolving list - contains no matching entry, use the public address. */ - RANDOM_RESOLVABLE_RANDOM_FALLBACK /**< Controller generates the Resolvable Private Address based on - the local IRK from the resolving list. If the resolving list - contains no matching entry, use previously set random address. */ - }; - own_address_type_t(type value) : ble::SafeEnum(value) { } - }; - - struct peer_address_type_t : ble::SafeEnum { - enum type { - PUBLIC = 0, /**< Public Device Address or Public Identity Address. */ - RANDOM /**< Random Device Address or Random (static) Identity Address. */ - }; - peer_address_type_t(type value) : ble::SafeEnum(value) { } - }; - -public: - GapExtendedAdvertisingParams() : - _advType(ble::ADV_CONNECTABLE_UNDIRECTED), - _minInterval(0), - _maxInterval(0), - _peerAddressType(peer_address_type_t::PUBLIC), - _ownAddressType(own_address_type_t::PUBLIC), - _policy(ble::ADV_POLICY_IGNORE_WHITELIST), - _primaryPhy(ble::phy_t::LE_1M), - _secondaryPhy(ble::phy_t::LE_1M), - _peerAddress(), - _txPower(0), - _eventNumber(0), - _channel37(1), - _channel38(1), - _channel39(1), - _anonymous(0), - _notifyOnScan(1), - _legacyPDU(0), - _includeHeaderTxPower(0) { } - /** * Update the advertising type. * @@ -323,16 +300,30 @@ public: return _advType; } + /** + * + * @return + */ bool getAnonymousAdvertising() const { return _anonymous; } + /** Advertise without your own address. + * + * @param enable Advertising anonymous if true. + */ void setAnonymousAdvertising( bool enable ) { _anonymous = enable; } + /** Get the advertising intervals on the primary channels. + * + * @param min Minimum interval in milliseconds. + * @param max Maximum interval in milliseconds. + * @return Error if pointers are invalid. + */ ble_error_t getPrimaryInterval( uint32_t *min /* ms */, uint32_t *max /* ms */ @@ -340,19 +331,31 @@ public: if (!min || !max) { return BLE_ERROR_INVALID_PARAM; } - *min = _minInterval; - *max = _maxInterval; + *min = ADVERTISEMENT_DURATION_UNITS_TO_MS(_interval); + *max = ADVERTISEMENT_DURATION_UNITS_TO_MS(_maxInterval); return BLE_ERROR_NONE; } + /** Set the advertising intervals on the primary channels. + * + * @param min Minimum interval in milliseconds. + * @param max Maximum interval in milliseconds. + */ void setPrimaryInterval( uint32_t min /* ms */, uint32_t max /* ms */ ) { - _minInterval = min; - _maxInterval = max; + _interval = MSEC_TO_ADVERTISEMENT_DURATION_UNITS(min); + _maxInterval = MSEC_TO_ADVERTISEMENT_DURATION_UNITS(max); } + /** Get channels set for primary advertising. + * + * @param channel37 Use channel 37. + * @param channel38 Use channel 38. + * @param channel39 Use channel 39. + * @return Error if pointers are invalid. + */ ble_error_t getPrimaryChannels( bool *channel37, bool *channel38, @@ -367,26 +370,48 @@ public: return BLE_ERROR_NONE; } + /** 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. + */ void setPrimaryChannels( bool channel37, bool channel38, bool channel39 ) { + if (!channel37 && !channel38 && !channel39) { + channel37 = channel38 = channel39 = true; + } _channel37 = channel37; _channel38 = channel38; _channel39 = channel39; } + /** 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; } + /** Get what type of address is to be used as your own address during advertising. + */ void setOwnAddressType( own_address_type_t addressType ) { _ownAddressType = addressType; } + /** Get peer address and type used during directed advertising. + * + * @param address Address that will have the peer address written to. + * @param addressType Pointer to type which will have the address type written to. + * @return Error if pointers are invalid. + */ ble_error_t getPeer( BLEProtocol::AddressBytes_t *address, peer_address_type_t *addressType @@ -399,6 +424,11 @@ public: return BLE_ERROR_NONE; }; + /** Set peer address and type used during directed advertising. + * + * @param address Peer's address bytes. + * @param addressType Peer's address type. + */ void setPeer( const BLEProtocol::AddressBytes_t address, peer_address_type_t addressType @@ -407,26 +437,46 @@ public: _peerAddressType = addressType; }; + /** Get the policy of whitelist use during advertising; + * + * @return Policy used. + */ ble::advertising_policy_mode_t getPolicyMode() const { return _policy; } - + /** Set the policy of whitelist use during advertising; + * + * @param Policy to use. + */ void setPolicyMode( ble::advertising_policy_mode_t mode ) { _policy = mode; } + /** Get the advertising TX power. + * + * @return Advertising TX power. + */ int8_t getTxPower() const { return _txPower; } + /** Set the advertising TX power. + * + * @param txPower Advertising TX power. + */ void setTxPower( int8_t txPower ) { _txPower = txPower; } + /** Get PHYs used on primary and secondary advertising channels. + * + * @param primaryPhy,secondaryPhy Pointer where the result is written to. + * @return Error if pointers are invalid. + */ ble_error_t getPhy( ble::phy_t *primaryPhy, ble::phy_t *secondaryPhy @@ -439,6 +489,11 @@ public: return BLE_ERROR_NONE; } + /** Get PHYs used on primary and secondary advertising channels. + * + * @param primaryPhy Primary advertising channles PHY. + * @param secondaryPhy Secondary advertising channles PHY. + */ void setPhy( ble::phy_t primaryPhy, ble::phy_t secondaryPhy @@ -490,7 +545,7 @@ public: /* helper get functions */ uint32_t getMinPrimaryInterval() const { - return _minInterval; + return _interval; } uint32_t getMaxPrimaryInterval() const { @@ -527,8 +582,12 @@ public: private: ble::advertising_type_t _advType; - uint32_t _minInterval; - uint32_t _maxInterval; + /** + * The advertising interval in ADV duration units (in other words, 0.625ms). + */ + uint16_t _interval; + uint16_t _timeout; + uint16_t _maxInterval; peer_address_type_t _peerAddressType; own_address_type_t _ownAddressType; ble::advertising_policy_mode_t _policy; diff --git a/features/FEATURE_BLE/ble/generic/GenericGap.h b/features/FEATURE_BLE/ble/generic/GenericGap.h index 1fc9747a09..d9e41192b9 100644 --- a/features/FEATURE_BLE/ble/generic/GenericGap.h +++ b/features/FEATURE_BLE/ble/generic/GenericGap.h @@ -86,8 +86,6 @@ public: ble_error_t setAdvertisingParams(AdvHandle_t handle, const GapAdvertisingParams* params); - ble_error_t setAdvertisingParams(AdvHandle_t handle, const GapExtendedAdvertisingParams* params); - ble_error_t setAdvertisingPayload(AdvHandle_t handle, const AdvertisingData* payload, bool minimiseFragmentation = false); ble_error_t setAdvertisingScanResponse(AdvHandle_t handle, const AdvertisingData* response, bool minimiseFragmentation = false); diff --git a/features/FEATURE_BLE/source/generic/GenericGap.cpp b/features/FEATURE_BLE/source/generic/GenericGap.cpp index 7215c3f55f..0d464efd8a 100644 --- a/features/FEATURE_BLE/source/generic/GenericGap.cpp +++ b/features/FEATURE_BLE/source/generic/GenericGap.cpp @@ -1610,65 +1610,36 @@ ble_error_t GenericGap::destroyAdvertisingSet(AdvHandle_t handle) { } ble_error_t GenericGap::setAdvertisingParams(AdvHandle_t handle, const GapAdvertisingParams* params) { - if (handle != Gap::LEGACY_ADVERTISING_HANDLE || !params) { - return BLE_ERROR_INVALID_PARAM; - } - - if (!is_extended_advertising_enabled()) { - memcpy(&getLegacyAdvertisingParams(), params, sizeof(GapAdvertisingParams)); - return BLE_ERROR_NONE; - } - - ble::advertising_type_t adv_type = params->getAdvertisingType(); - - AddressUseType_t use_type; - switch(adv_type) { - case ADV_SCANNABLE_UNDIRECTED: - case ADV_NON_CONNECTABLE_UNDIRECTED: - use_type = PERIPHERAL_NON_CONNECTABLE; - break; - default: - use_type = PERIPHERAL_CONNECTABLE; - } - - address_t dummy_peer_address; - - pal::advertising_event_properties_t event_properties((pal::advertising_type_t::type)adv_type); - - return _pal_gap.set_extended_advertising_parameters( - Gap::LEGACY_ADVERTISING_HANDLE, - event_properties, - (pal::advertising_interval_t) params->getIntervalInADVUnits(), - (pal::advertising_interval_t) params->getIntervalInADVUnits(), - pal::advertising_channel_map_t::ALL_ADVERTISING_CHANNELS, - (pal::own_address_type_t) get_own_address_type(use_type), - pal::advertising_peer_address_type_t::PUBLIC_ADDRESS, - dummy_peer_address, - (pal::advertising_filter_policy_t)_advertising_filter_policy, - /* TX power : no preference */ 127, - /* primary phy */ phy_t::LE_1M, - /* max skip */ 0x00, - /* secondary phy */ phy_t::LE_1M, - /* SID */ 0x00, - false - ); -} - -ble_error_t GenericGap::setAdvertisingParams(AdvHandle_t handle, const GapExtendedAdvertisingParams* params) { if (!get_adv_set_bit(_existing_sets, handle) || !params) { return BLE_ERROR_INVALID_PARAM; } - pal::advertising_channel_map_t channel_map(params->getChannel37(), params->getChannel38(), params->getChannel39()); pal::advertising_event_properties_t event_properties((pal::advertising_type_t::type)params->getType()); + event_properties.include_tx_power = params->getTxPowerInHeader(); + event_properties.omit_advertisser_address = params->getAnonymousAdvertising(); + event_properties.use_legacy_pdu = params->getUseLegacyPDU(); + + pal::advertising_channel_map_t channel_map(params->getChannel37(), params->getChannel38(), params->getChannel39()); + pal::own_address_type_t own_address_type = (pal::own_address_type_t::type)params->getOwnAddressType().value(); + + if (handle == Gap::LEGACY_ADVERTISING_HANDLE) { + AddressUseType_t use_type = PERIPHERAL_CONNECTABLE; + if ((params->getAdvertisingType() == ADV_SCANNABLE_UNDIRECTED) || + (params->getAdvertisingType() == ADV_NON_CONNECTABLE_UNDIRECTED)) { + use_type = PERIPHERAL_NON_CONNECTABLE; + } + + own_address_type = (pal::own_address_type_t) get_own_address_type(use_type); + } + return _pal_gap.set_extended_advertising_parameters( handle, event_properties, (pal::advertising_interval_t)params->getMinPrimaryInterval(), (pal::advertising_interval_t)params->getMaxPrimaryInterval(), channel_map, - (pal::own_address_type_t::type)params->getOwnAddressType().value(), + own_address_type, (pal::advertising_peer_address_type_t::type)params->getPeerAddressType().value(), params->getPeerAddress(), (pal::advertising_filter_policy_t::type) params->getPolicyMode(),