diff --git a/features/FEATURE_BLE/ble/gap/AdvertisingParameters.h b/features/FEATURE_BLE/ble/gap/AdvertisingParameters.h index 304abddaad..0141b9164a 100644 --- a/features/FEATURE_BLE/ble/gap/AdvertisingParameters.h +++ b/features/FEATURE_BLE/ble/gap/AdvertisingParameters.h @@ -124,6 +124,9 @@ public: * 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 CONNECTABLE_UNDIRECTED or CONNECTABLE_DIRECTED advertising is used + * you must use legacy PDU. + * * @note If values in input are out of range, they will be normalized. */ AdvertisingParameters( @@ -162,6 +165,9 @@ public: /** * Update the advertising type. * + * @note If legacy PDU is not used then you cannot use + * CONNECTABLE_UNDIRECTED nor CONNECTABLE_DIRECTED. + * * @param[in] newAdvType The new advertising type. * * @return reference to this object. @@ -448,6 +454,9 @@ public: * * @param enable If true, legacy PDU will be used. * + * @note If CONNECTABLE_UNDIRECTED or CONNECTABLE_DIRECTED advertising is used + * you must use legacy PDU. + * * @return A reference to this object. */ AdvertisingParameters &setUseLegacyPDU(bool enable = true) @@ -490,6 +499,8 @@ public: * * @param enable Advertising anonymous if true. * + * @note You may not use anonymous advertising with periodic advertising on the same set. + * * @return reference to this object. */ AdvertisingParameters &setAnonymousAdvertising(bool enable) diff --git a/features/FEATURE_BLE/ble/gap/Gap.h b/features/FEATURE_BLE/ble/gap/Gap.h index 194369c623..0a5835c6c7 100644 --- a/features/FEATURE_BLE/ble/gap/Gap.h +++ b/features/FEATURE_BLE/ble/gap/Gap.h @@ -538,6 +538,12 @@ public: */ virtual uint16_t getMaxAdvertisingDataLength(); + /** Return maximum advertising data length supported for connectable advertising. + * + * @return Maximum advertising data length supported for connectable advertising. + */ + virtual uint16_t getMaxConnectableAdvertisingDataLength(); + /** Create an advertising set and apply the passed in parameters. The handle returned * by this function must be used for all other calls that accept an advertising handle. * When done with advertising, remove from the system using destroyAdvertisingSet(). diff --git a/features/FEATURE_BLE/ble/generic/GenericGap.h b/features/FEATURE_BLE/ble/generic/GenericGap.h index 8b3fd4af13..7ef9e66080 100644 --- a/features/FEATURE_BLE/ble/generic/GenericGap.h +++ b/features/FEATURE_BLE/ble/generic/GenericGap.h @@ -50,7 +50,6 @@ class GenericGap : 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. @@ -92,6 +91,10 @@ public: */ virtual uint16_t getMaxAdvertisingDataLength(); + /** @copydoc Gap::getMaxConnectableAdvertisingDataLength + */ + virtual uint16_t getMaxConnectableAdvertisingDataLength(); + /** @copydoc Gap::createAdvertisingSet */ virtual ble_error_t createAdvertisingSet( diff --git a/features/FEATURE_BLE/ble/pal/PalGap.h b/features/FEATURE_BLE/ble/pal/PalGap.h index 0a9a017ae3..be9dade825 100644 --- a/features/FEATURE_BLE/ble/pal/PalGap.h +++ b/features/FEATURE_BLE/ble/pal/PalGap.h @@ -764,6 +764,23 @@ struct Gap { */ virtual uint16_t get_maximum_advertising_data_length() = 0; + /** + * Query the maximum data length the controller supports in an advertising set + * using connectable advertising. + * + * @return The length in byte the controller can support in an advertising set + * for connectable advertising. + */ + virtual uint16_t get_maximum_connectable_advertising_data_length() = 0; + + /** + * Query the maximum payload length for a single HCI packet carrying partial + * (or complete if it fits) data for advertising set. + * + * @return Max size of the HCI packet transporting the data. + */ + virtual uint8_t get_max_hci_advertising_data_length() = 0; + /** * Query the maximum number of concurrent advertising sets that is supported * by the controller. diff --git a/features/FEATURE_BLE/source/gap/Gap.cpp b/features/FEATURE_BLE/source/gap/Gap.cpp index 3515ddd531..6a5d5d4cef 100644 --- a/features/FEATURE_BLE/source/gap/Gap.cpp +++ b/features/FEATURE_BLE/source/gap/Gap.cpp @@ -36,6 +36,12 @@ uint16_t Gap::getMaxAdvertisingDataLength() return LEGACY_ADVERTISING_MAX_SIZE; } +uint16_t Gap::getMaxConnectableAdvertisingDataLength() +{ + /* 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 ¶meters diff --git a/features/FEATURE_BLE/source/generic/GenericGap.cpp b/features/FEATURE_BLE/source/generic/GenericGap.cpp index a45ce22149..c9bf963439 100644 --- a/features/FEATURE_BLE/source/generic/GenericGap.cpp +++ b/features/FEATURE_BLE/source/generic/GenericGap.cpp @@ -1989,8 +1989,6 @@ void GenericGap::set_connection_event_handler(pal::ConnectionEventMonitor::Event const uint8_t GenericGap::MAX_ADVERTISING_SETS; -const size_t GenericGap::MAX_HCI_DATA_LENGTH; - uint8_t GenericGap::getMaxAdvertisingSetNumber() { useVersionTwoAPI(); @@ -2009,6 +2007,12 @@ uint16_t GenericGap::getMaxAdvertisingDataLength() return _pal_gap.get_maximum_advertising_data_length(); } +uint16_t GenericGap::getMaxConnectableAdvertisingDataLength() +{ + useVersionTwoAPI(); + return _pal_gap.get_maximum_connectable_advertising_data_length(); +} + ble_error_t GenericGap::createAdvertisingSet( advertising_handle_t *handle, const AdvertisingParameters ¶meters @@ -2259,24 +2263,23 @@ ble_error_t GenericGap::setAdvertisingData( &pal::Gap::set_extended_scan_response_data : &pal::Gap::set_extended_advertising_data; - for (size_t i = 0, end = payload.size(); - (i < end) || (i == 0 && end == 0); - i += MAX_HCI_DATA_LENGTH) - { + const size_t hci_length = _pal_gap.get_max_hci_advertising_data_length(); + + for (size_t i = 0, end = payload.size(); (i < end) || (i == 0 && end == 0); i += hci_length) { // select the operation based on the index op_t op(op_t::INTERMEDIATE_FRAGMENT); - if (end < MAX_HCI_DATA_LENGTH) { + if (end < hci_length) { op = op_t::COMPLETE_FRAGMENT; } else if (i == 0) { op = op_t::FIRST_FRAGMENT; - } else if ((end - i) <= MAX_HCI_DATA_LENGTH) { + } else if ((end - i) <= hci_length) { op = op_t::LAST_FRAGMENT; } // extract the payload mbed::Span sub_payload = payload.subspan( i, - std::min(MAX_HCI_DATA_LENGTH, (end - i)) + std::min(hci_length, (end - i)) ); // set the payload @@ -2467,24 +2470,23 @@ ble_error_t GenericGap::setPeriodicAdvertisingPayload( typedef pal::advertising_fragment_description_t op_t; - for (size_t i = 0, end = payload.size(); - (i < end) || (i == 0 && end == 0); - i += MAX_HCI_DATA_LENGTH - ) { + const size_t hci_length = _pal_gap.get_max_hci_advertising_data_length(); + + for (size_t i = 0, end = payload.size(); (i < end) || (i == 0 && end == 0); i += hci_length) { // select the operation based on the index op_t op(op_t::INTERMEDIATE_FRAGMENT); - if (end < MAX_HCI_DATA_LENGTH) { + if (end < hci_length) { op = op_t::COMPLETE_FRAGMENT; } else if (i == 0) { op = op_t::FIRST_FRAGMENT; - } else if ((end - i) <= MAX_HCI_DATA_LENGTH) { + } else if ((end - i) <= hci_length) { op = op_t::LAST_FRAGMENT; } // extract the payload mbed::Span sub_payload = payload.subspan( i, - std::min(MAX_HCI_DATA_LENGTH, (end - i)) + std::min(hci_length, (end - i)) ); ble_error_t err = _pal_gap.set_periodic_advertising_data( diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/CordioPalGap.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/CordioPalGap.h index 02e6910d18..e31a252e1e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/CordioPalGap.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/CordioPalGap.h @@ -221,6 +221,10 @@ public: virtual uint16_t get_maximum_advertising_data_length(); + virtual uint16_t get_maximum_connectable_advertising_data_length(); + + virtual uint8_t get_max_hci_advertising_data_length(); + virtual uint8_t get_max_number_of_advertising_sets(); virtual ble_error_t remove_advertising_set( diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioPalGap.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioPalGap.cpp index c3330e9145..7d2e27f6ae 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioPalGap.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/source/CordioPalGap.cpp @@ -921,6 +921,16 @@ uint16_t Gap::get_maximum_advertising_data_length() return HciGetMaxAdvDataLen(); } +uint16_t Gap::get_maximum_connectable_advertising_data_length() +{ + return HCI_EXT_ADV_CONN_DATA_LEN; +} + +uint8_t Gap::get_max_hci_advertising_data_length() +{ + return HCI_EXT_ADV_DATA_LEN; +} + uint8_t Gap::get_max_number_of_advertising_sets() { return std::min(HciGetNumSupAdvSets(), (uint8_t) DM_NUM_ADV_SETS);