Skip to content

Commit a0aad47

Browse files
authored
Merge pull request #825 from AndreasLamparter/master
Set the wait timeout for missing indication acknowledgment
2 parents af92c09 + 653b911 commit a0aad47

3 files changed

Lines changed: 29 additions & 18 deletions

File tree

libraries/Bluefruit52Lib/src/BLECharacteristic.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,9 @@ bool BLECharacteristic::indicate(uint16_t conn_hdl, const void* data, uint16_t l
874874

875875
LOG_LV2("CHR", "Indicate %d bytes", packet_len);
876876

877-
// Blocking wait until receiving confirmation from peer
877+
// Blocking wait until receiving confirmation from peer.
878+
// Reset HVC state BEFORE hvx() so a fast HVC event isn't drained as stale.
879+
VERIFY ( conn->prepareForIndicateConfirm() );
878880
VERIFY_STATUS( sd_ble_gatts_hvx(conn_hdl, &hvx_params), false );
879881
VERIFY ( conn->waitForIndicateConfirm() );
880882

libraries/Bluefruit52Lib/src/BLEConnection.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,23 @@ BLEConnection::BLEConnection(uint16_t conn_hdl, ble_gap_evt_connected_t const* e
5656

5757
_hvn_sem = xSemaphoreCreateCounting(hvn_qsize, hvn_qsize);
5858
_wrcmd_sem = xSemaphoreCreateCounting(wrcmd_qsize, wrcmd_qsize);
59+
_hvc_sem = xSemaphoreCreateBinary();
5960

6061
_sec_mode.sm = _sec_mode.lv = 1; // default to open
6162

6263
_bonded = false;
63-
_hvc_sem = NULL;
6464
_hvc_received = false;
6565

6666
_ediv = 0xFFFF;
67+
68+
_indicate_confirm_timeout = portMAX_DELAY;
6769
}
6870

6971
BLEConnection::~BLEConnection()
7072
{
71-
vSemaphoreDelete( _hvn_sem );
72-
vSemaphoreDelete( _wrcmd_sem );
73-
74-
//------------- on-the-fly data must be freed -------------//
75-
if (_hvc_sem ) vSemaphoreDelete(_hvc_sem );
73+
vSemaphoreDelete(_hvn_sem);
74+
vSemaphoreDelete(_wrcmd_sem);
75+
vSemaphoreDelete(_hvc_sem);
7676
}
7777

7878
uint16_t BLEConnection::handle (void)
@@ -285,17 +285,24 @@ bool BLEConnection::requestPairing(void)
285285
return Bluefruit.Security._authenticate(_conn_hdl);
286286
}
287287

288-
bool BLEConnection::waitForIndicateConfirm(void)
288+
void BLEConnection::setIndicateConfirmTimeout(uint32_t timeout_ms)
289289
{
290-
// on the fly semaphore
291-
_hvc_sem = xSemaphoreCreateBinary();
290+
_indicate_confirm_timeout = (timeout_ms == UINT32_MAX) ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms);
291+
}
292292

293+
// Must be called BEFORE sd_ble_gatts_hvx() to clear any stale HVC state from a
294+
// previous indication (e.g. a late HVC that arrived after a timeout). Pairs with
295+
// waitForIndicateConfirm().
296+
bool BLEConnection::prepareForIndicateConfirm(void)
297+
{
298+
xSemaphoreTake(_hvc_sem, 0);
293299
_hvc_received = false;
294-
xSemaphoreTake(_hvc_sem, portMAX_DELAY);
295-
296-
vSemaphoreDelete(_hvc_sem);
297-
_hvc_sem = NULL;
300+
return true;
301+
}
298302

303+
bool BLEConnection::waitForIndicateConfirm(void)
304+
{
305+
xSemaphoreTake(_hvc_sem, _indicate_confirm_timeout);
299306
return _hvc_received;
300307
}
301308

@@ -428,7 +435,7 @@ void BLEConnection::_eventHandler(ble_evt_t* evt)
428435
LOG_LV2("GATTS", "Confirm received handle = 0x%04X", evt->evt.gatts_evt.params.hvc.handle);
429436

430437
_hvc_received = true;
431-
if ( _hvc_sem ) xSemaphoreGive(_hvc_sem);
438+
xSemaphoreGive(_hvc_sem);
432439
}
433440
break;
434441

@@ -440,7 +447,7 @@ void BLEConnection::_eventHandler(ble_evt_t* evt)
440447
if (BLE_GATT_TIMEOUT_SRC_PROTOCOL == timeout_src)
441448
{
442449
_hvc_received = false;
443-
if ( _hvc_sem ) xSemaphoreGive(_hvc_sem);
450+
xSemaphoreGive(_hvc_sem);
444451
}
445452
}
446453
break;

libraries/Bluefruit52Lib/src/BLEConnection.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ class BLEConnection
6666

6767
SemaphoreHandle_t _hvn_sem;
6868
SemaphoreHandle_t _wrcmd_sem;
69-
70-
// On-demand semaphore/data that are created on the fly
7169
SemaphoreHandle_t _hvc_sem;
7270

71+
TickType_t _indicate_confirm_timeout;
72+
7373
public:
7474
BLEConnection(uint16_t conn_hdl, ble_gap_evt_connected_t const * evt_connected, uint8_t hvn_qsize, uint8_t wrcmd_qsize);
7575
virtual ~BLEConnection();
@@ -95,6 +95,7 @@ class BLEConnection
9595
bool disconnect(void);
9696

9797
bool setTxPower(int8_t power); // set power for this connection
98+
void setIndicateConfirmTimeout(uint32_t timeout_ms);
9899

99100
bool requestDataLengthUpdate(ble_gap_data_length_params_t const *p_dl_params = NULL, ble_gap_data_length_limitation_t *p_dl_limitation = NULL);
100101
bool requestMtuExchange(uint16_t mtu);
@@ -109,6 +110,7 @@ class BLEConnection
109110
bool getHvnPacket(void);
110111
bool releaseHvnPacket(void);
111112
bool getWriteCmdPacket(void);
113+
bool prepareForIndicateConfirm(void);
112114
bool waitForIndicateConfirm(void);
113115

114116
bool saveBondKey(bond_keys_t const* ltkey);

0 commit comments

Comments
 (0)