Skip to content

Commit 8cb8e49

Browse files
authored
Merge pull request #14747 from paul-szczepanek-arm/fix-adv-con
BLE: fix advertising set termination event
2 parents 3cf5f8e + afeb696 commit 8cb8e49

File tree

6 files changed

+89
-20
lines changed

6 files changed

+89
-20
lines changed

connectivity/FEATURE_BLE/include/ble/common/blecommon.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,17 @@ enum ble_error_t {
216216
/**
217217
* Data not found or there is nothing to return.
218218
*/
219-
BLE_ERROR_NOT_FOUND = 13
219+
BLE_ERROR_NOT_FOUND = 13,
220+
221+
/**
222+
* Specified timeout expired.
223+
*/
224+
BLE_ERROR_TIMEOUT = 14,
225+
226+
/**
227+
* Specified limit expired.
228+
*/
229+
BLE_ERROR_LIMIT_REACHED = 15
220230
};
221231

222232
/**

connectivity/FEATURE_BLE/include/ble/gap/Events.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,10 +627,15 @@ struct AdvertisingEndEvent {
627627
/** Create an extended advertising end event.
628628
*
629629
* @param advHandle Advertising set handle.
630-
* @param connection Connection handle.
631-
* @param completed_events Number of events created during before advertising end.
630+
* @param connection Connection handle - only valid if connected is True.
631+
* @param completed_events Number of events created during before advertising end - only valid
632+
* if advertising end has been caused by BLE_ERROR_LIMIT_REACHED, not the local user.
633+
* Check getStatus().
632634
* @param connected True if connection has been established.
633-
* @param status Error code if stop command failed.
635+
* @param status Error code showing the reason for event. BLE_ERROR_LIMIT_REACHED if set number
636+
* of events have been reached. BLE_ERROR_TIMEOUT if set time has elapsed.
637+
* BLE_ERROR_SUCCESS if connection occurred or user ended the set. Check isConnected()
638+
* to determine which.
634639
*/
635640
AdvertisingEndEvent(
636641
advertising_handle_t advHandle,

connectivity/FEATURE_BLE/libraries/cordio_stack/ble-host/sources/stack/dm/dm_adv_ae.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "dm_adv.h"
3232
#include "dm_dev.h"
3333
#include "dm_main.h"
34+
#include "dm_conn.h"
3435

3536
/**************************************************************************************************
3637
Macros
@@ -1215,15 +1216,20 @@ void dmExtAdvActHciEnableCmpl(hciEvt_t *pEvent)
12151216
dmEvt_t dmMsg;
12161217

12171218
memcpy(&dmMsg, &pEvent->hdr, sizeof(wsfMsgHdr_t));
1218-
dmMsg.advSetStart.numSets = 0;
1219+
1220+
/* we have to handle stopping and starting separately as it uses the same message memory */
12191221

12201222
for ( i= 0; i < DM_NUM_ADV_SETS; i++)
12211223
{
12221224
switch(dmAdvCb.advState[i])
12231225
{
12241226
case DM_ADV_STATE_STOPPING:
12251227
case DM_ADV_STATE_STOPPING_DIRECTED:
1228+
/* prepare the message for callback */
1229+
dmMsg.advSetStop.handle = DM_ADV_HCI_HANDLE_NONE;
1230+
dmMsg.advSetStop.status = dmMsg.hdr.status;
12261231
dmMsg.advSetStop.advHandle = i;
1232+
12271233
advType = dmAdvCb.advType[i];
12281234

12291235
if (dmMsg.hdr.status == HCI_SUCCESS)
@@ -1243,10 +1249,24 @@ void dmExtAdvActHciEnableCmpl(hciEvt_t *pEvent)
12431249
/* if not connectable directed advertising */
12441250
if ((advType != DM_ADV_NONE) && !DM_ADV_CONN_DIRECTED(advType))
12451251
{
1246-
cbackEvent = DM_ADV_SET_STOP_IND;
1252+
/* we have to dispatch callbacks one by one as msg only has space for one set of parameters */
1253+
dmMsg.hdr.event = DM_ADV_SET_STOP_IND;
1254+
(*dmCb.cback)((dmEvt_t *) &dmMsg);
12471255
}
12481256
break;
12491257

1258+
default:
1259+
break;
1260+
}
1261+
}
1262+
1263+
/* safe to write as message is only used by starting, removing and clearing does not send a message */
1264+
dmMsg.advSetStart.numSets = 0;
1265+
1266+
for ( i= 0; i < DM_NUM_ADV_SETS; i++)
1267+
{
1268+
switch(dmAdvCb.advState[i])
1269+
{
12501270
case DM_ADV_STATE_STARTING:
12511271
case DM_ADV_STATE_STARTING_DIRECTED:
12521272
dmMsg.advSetStart.advHandle[dmMsg.advSetStart.numSets++] = i;
@@ -1355,6 +1375,13 @@ void dmExtAdvHciHandler(hciEvt_t *pEvent)
13551375
if (!DM_ADV_CONN_DIRECTED(advType))
13561376
{
13571377
pEvent->hdr.event = DM_ADV_SET_STOP_IND;
1378+
if (pEvent->leAdvSetTerm.status == HCI_SUCCESS) {
1379+
/* translate the handle to conn id */
1380+
dmConnCcb_t* ccb = dmConnCcbByHandle(pEvent->leAdvSetTerm.handle);
1381+
if (ccb) {
1382+
pEvent->hdr.param = ccb->connId;
1383+
}
1384+
}
13581385
(*dmCb.cback)((dmEvt_t *) pEvent);
13591386
}
13601387
/* else if low duty cycle directed advertising failed to create connection */

connectivity/FEATURE_BLE/source/cordio/source/PalGapImpl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,10 +869,17 @@ void PalGap::gap_handler(const wsfMsgHdr_t *msg)
869869
break;
870870
}
871871

872+
connection_handle_t connection_handle = DM_CONN_ID_NONE;
873+
/* the way we distinguish between local close and connection is the invalid HCI conn handle */
874+
if (evt->status == HCI_SUCCESS && evt->handle != DM_CONN_HCI_HANDLE_NONE) {
875+
/* use the translated conn handle */
876+
connection_handle = evt->hdr.param;
877+
}
878+
872879
handler->on_advertising_set_terminated(
873880
hci_error_code_t(evt->status),
874881
evt->advHandle,
875-
evt->handle,
882+
connection_handle,
876883
evt->numComplEvts
877884
);
878885
} break;

connectivity/FEATURE_BLE/source/generic/GapImpl.cpp

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,6 +2461,8 @@ ble_error_t Gap::startAdvertising(
24612461
#if BLE_FEATURE_EXTENDED_ADVERTISING
24622462
void Gap::process_enable_queue()
24632463
{
2464+
_process_enable_queue_pending = false;
2465+
24642466
tr_info("Evaluating pending advertising sets to be started");
24652467
if (!_advertising_enable_command_params.number_of_handles) {
24662468
/* no set pending to be enabled */
@@ -2506,7 +2508,6 @@ void Gap::process_enable_queue()
25062508
}
25072509

25082510
_advertising_enable_command_params.number_of_handles = 0;
2509-
_process_enable_queue_pending = false;
25102511
}
25112512
#endif //BLE_FEATURE_EXTENDED_ADVERTISING
25122513

@@ -3480,16 +3481,34 @@ void Gap::on_advertising_set_terminated(
34803481
to_string(status),
34813482
number_of_completed_extended_advertising_events);
34823483

3483-
_active_sets.clear(advertising_handle);
3484-
_pending_sets.clear(advertising_handle);
3484+
ble_error_t error_code = BLE_ERROR_UNSPECIFIED;
3485+
bool connected = false;
34853486

3486-
// If this is part of the address refresh start advertising again.
3487-
if (_address_refresh_sets.get(advertising_handle) && !connection_handle) {
3488-
_address_refresh_sets.clear(advertising_handle);
3489-
tr_info("Part of the address refresh, restarting advertising");
3490-
startAdvertising(advertising_handle);
3491-
_adv_started_from_refresh.set(advertising_handle);
3492-
return;
3487+
/* translate HCI error into BLE API error code */
3488+
if (status == hci_error_code_t::SUCCESS) {
3489+
error_code = BLE_ERROR_NONE;
3490+
/* self cancelled set will have the handle set to invalid value */
3491+
if (connection_handle != DM_CONN_ID_NONE) {
3492+
connected = true;
3493+
}
3494+
} else if (status == hci_error_code_t::ADVERTISING_TIMEOUT) {
3495+
error_code = BLE_ERROR_TIMEOUT;
3496+
} else if (status == hci_error_code_t::LIMIT_REACHED) {
3497+
error_code = BLE_ERROR_LIMIT_REACHED;
3498+
}
3499+
3500+
if (error_code != BLE_ERROR_UNSPECIFIED) {
3501+
_active_sets.clear(advertising_handle);
3502+
_pending_sets.clear(advertising_handle);
3503+
3504+
// If this is part of the address refresh start advertising again.
3505+
if (_address_refresh_sets.get(advertising_handle) && !connection_handle) {
3506+
_address_refresh_sets.clear(advertising_handle);
3507+
tr_info("Part of the address refresh, restarting advertising");
3508+
startAdvertising(advertising_handle);
3509+
_adv_started_from_refresh.set(advertising_handle);
3510+
return;
3511+
}
34933512
}
34943513

34953514
/* postpone as other events may still be pending */
@@ -3508,7 +3527,8 @@ void Gap::on_advertising_set_terminated(
35083527
advertising_handle,
35093528
connection_handle,
35103529
number_of_completed_extended_advertising_events,
3511-
status == hci_error_code_t::SUCCESS
3530+
connected,
3531+
error_code
35123532
)
35133533
);
35143534
}

connectivity/FEATURE_BLE/source/pal/PalGap.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,9 @@ struct PalGapEventHandler {
193193

194194
/** Called when advertising set stops advertising.
195195
*
196-
* @param status SUCCESS if connection has been established.
196+
* @param status SUCCESS if connection has been established or if stopped by user.
197197
* @param advertising_handle Advertising set handle.
198-
* @param advertising_handle Connection handle.
198+
* @param advertising_handle Connection handle. Set to invalid handle if no connection made.
199199
* @param number_of_completed_extended_advertising_events Number of events created during before advertising end.
200200
*/
201201
virtual void on_advertising_set_terminated(

0 commit comments

Comments
 (0)