BLE: Reduce complexity of GenericGap::setAdvertisingData

pull/8738/head
Vincent Coubard 2018-11-10 17:36:33 +00:00
parent 0d90671842
commit d2773e9731
1 changed files with 62 additions and 56 deletions

View File

@ -1710,76 +1710,82 @@ ble_error_t GenericGap::setAdvertisingData(
bool minimiseFragmentation, bool minimiseFragmentation,
bool scan_response bool scan_response
) { ) {
// type declarations
typedef pal::advertising_fragment_description_t op_t;
typedef ble_error_t (pal::Gap::*legacy_set_data_fn_t)(
uint8_t ,
const pal::advertising_data_t&
);
typedef ble_error_t (pal::Gap::*set_data_fn_t)(
advertising_handle_t advertising_handle,
op_t operation,
bool minimize_fragmentation,
uint8_t scan_response_data_size,
const uint8_t *scan_response_data
);
if (!_existing_sets.get(handle)) { if (!_existing_sets.get(handle)) {
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
// handle special case of legacy advertising
if (!is_extended_advertising_available()) { if (!is_extended_advertising_available()) {
if (handle == Gap::LEGACY_ADVERTISING_HANDLE) { if (handle != Gap::LEGACY_ADVERTISING_HANDLE) {
if (payload.size() < GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
return BLE_ERROR_INVALID_PARAM;
}
if (scan_response) {
return _pal_gap.set_advertising_data(
payload.size(),
pal::advertising_data_t(payload.data(), payload.size())
);
} else {
return _pal_gap.set_scan_response_data(
payload.size(),
pal::advertising_data_t(payload.data(), payload.size())
);
}
} else {
return BLE_ERROR_INVALID_PARAM; return BLE_ERROR_INVALID_PARAM;
} }
return BLE_ERROR_NOT_IMPLEMENTED;
if (payload.size() < GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
return BLE_ERROR_INVALID_PARAM;
}
// select the pal function
legacy_set_data_fn_t set_data = scan_response ?
&pal::Gap::set_scan_response_data :
&pal::Gap::set_advertising_data;
// set the payload
return (_pal_gap.*set_data)(
payload.size(),
pal::advertising_data_t(payload.data(), payload.size())
);
} }
ble_error_t status = BLE_ERROR_NONE; // select the pal function
uint16_t index = 0; set_data_fn_t set_data = scan_response ?
const uint16_t& length = payload.size(); &pal::Gap::set_extended_scan_response_data :
uint16_t packet_data_length = length; &pal::Gap::set_extended_advertising_data;
typedef pal::advertising_fragment_description_t op_t; for (size_t i = 0, end = payload.size(); i < end; i += MAX_HCI_DATA_LENGTH) {
op_t operation = (length > MAX_HCI_DATA_LENGTH) ? op_t::FIRST_FRAGMENT : op_t::COMPLETE_FRAGMENT; // select the operation based on the index
op_t op(op_t::INTERMEDIATE_FRAGMENT);
while (index < length) { if (end < MAX_HCI_DATA_LENGTH) {
if ((length - index) > MAX_HCI_DATA_LENGTH) { op = op_t::COMPLETE_FRAGMENT;
packet_data_length = MAX_HCI_DATA_LENGTH; } else if (i == 0) {
} else { op = op_t::FIRST_FRAGMENT;
packet_data_length = length - index; } else if ((end - i) <= MAX_HCI_DATA_LENGTH) {
operation = op_t::LAST_FRAGMENT; op = op_t::LAST_FRAGMENT;
} }
if (scan_response) { // extract the payload
status = _pal_gap.set_extended_scan_response_data( mbed::Span<uint8_t> sub_payload = payload.subspan(
handle, i,
operation, std::min(MAX_HCI_DATA_LENGTH, (end - i))
minimiseFragmentation, );
packet_data_length,
&payload[index] // set the payload
); ble_error_t err = (_pal_gap.*set_data)(
} else { handle,
status = _pal_gap.set_extended_advertising_data( op,
handle, minimiseFragmentation,
operation, sub_payload.size(),
minimiseFragmentation, sub_payload.data()
packet_data_length, );
&payload[index]
); if (err) {
return err;
} }
if (status != BLE_ERROR_NONE) {
return status;
}
index += packet_data_length;
operation = op_t::INTERMEDIATE_FRAGMENT;
} }
return BLE_ERROR_NONE;
return status;
} }
ble_error_t GenericGap::startAdvertising( ble_error_t GenericGap::startAdvertising(