Skip to content

Commit 9e0a6ff

Browse files
committed
enhance indicat API() to wait for confirm or timeout from peer.
1 parent fc2e360 commit 9e0a6ff

File tree

4 files changed

+67
-42
lines changed

4 files changed

+67
-42
lines changed

libraries/Bluefruit52Lib/src/BLECharacteristic.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,9 @@ bool BLECharacteristic::indicate(const void* data, uint16_t len)
619619

620620
if ( indicateEnabled() )
621621
{
622-
uint16_t const max_payload = Bluefruit.Gap.getMTU( Bluefruit.connHandle() ) - 3;
622+
uint16_t conn_hdl = Bluefruit.connHandle();
623+
624+
uint16_t const max_payload = Bluefruit.Gap.getMTU( conn_hdl ) - 3;
623625
const uint8_t* u8data = (const uint8_t*) data;
624626

625627
while ( remaining )
@@ -636,16 +638,10 @@ bool BLECharacteristic::indicate(const void* data, uint16_t len)
636638
};
637639

638640
LOG_LV2("CHR", "Indicate %d bytes", packet_len);
639-
err_t err;
640-
641-
// If previous indicate is still in progress, wait for a while and try again
642-
while ( NRF_ERROR_BUSY == (err = sd_ble_gatts_hvx(Bluefruit.connHandle(), &hvx_params)) )
643-
{
644-
// TODO should wait for BLE_GATTS_EVT_HVC event
645-
delay( Bluefruit.connInterval() );
646-
}
647641

648-
VERIFY_STATUS( err, false );
642+
// Blocking wait until receiving confirmation from peer
643+
VERIFY_STATUS( sd_ble_gatts_hvx( conn_hdl, &hvx_params), false );
644+
VERIFY ( Bluefruit.Gatt.waitForIndicateConfirm(conn_hdl) );
649645

650646
remaining -= packet_len;
651647
u8data += packet_len;

libraries/Bluefruit52Lib/src/BLEGap.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,17 @@ class BLEGap
105105

106106
SemaphoreHandle_t hvn_tx_sem;
107107
SemaphoreHandle_t wrcmd_tx_sem;
108+
109+
SemaphoreHandle_t indicate_confirm_sem;
110+
bool hvc_received;
108111
} gap_peer_t;
109112

110113
gap_peer_t _peers[BLE_MAX_CONN];
111114

115+
gap_peer_t* _get_peer(uint16_t conn_hdl) { return &_peers[conn_hdl]; }
116+
112117
friend class AdafruitBluefruit;
118+
friend class BLEGatt;
113119
};
114120

115121
#endif /* BLEGAP_H_ */

libraries/Bluefruit52Lib/src/BLEGatt.cpp

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,20 @@ uint16_t BLEGatt::readCharByUuid(uint16_t conn_hdl, BLEUuid bleuuid, void* buffe
7474
return (count < 0) ? 0 : count;
7575
}
7676

77-
//bool BLEGatt::waitForIndicateConfirm(uint16_t conn_hdl)
78-
//{
79-
// while( _adamsg.isWaiting() )
80-
// {
81-
// // TODO multiple peripherals
82-
// delay( Bluefruit.connInterval() );
83-
// }
84-
//
85-
// _adamsg.begin(true);
86-
// _adamsg.prepare(NULL, 0);
87-
//
88-
// // Wait for HVC event
89-
// int32_t result = _adamsg.waitUntilComplete(BLE_GENERIC_TIMEOUT);
90-
//
91-
// _adamsg.stop();
92-
//
93-
// return (result == 0);
94-
//}
77+
bool BLEGatt::waitForIndicateConfirm(uint16_t conn_hdl)
78+
{
79+
BLEGap::gap_peer_t* peer = Bluefruit.Gap._get_peer(conn_hdl);
80+
81+
// hvi confirm semaphore is created on the fly
82+
peer->indicate_confirm_sem = xSemaphoreCreateBinary();
83+
84+
xSemaphoreTake(peer->indicate_confirm_sem, portMAX_DELAY);
85+
86+
vSemaphoreDelete(peer->indicate_confirm_sem);
87+
peer->indicate_confirm_sem = NULL;
88+
89+
return peer->hvc_received;
90+
}
9591

9692
void BLEGatt::_eventHandler(ble_evt_t* evt)
9793
{
@@ -204,25 +200,51 @@ void BLEGatt::_eventHandler(ble_evt_t* evt)
204200
}
205201

206202
// GATTC Read Characteristic by UUID procedure
207-
if ( evt_id == BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP )
203+
switch ( evt_id )
208204
{
209-
ble_gattc_evt_char_val_by_uuid_read_rsp_t* rd_rsp = &evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp;
205+
case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
206+
{
207+
ble_gattc_evt_char_val_by_uuid_read_rsp_t* rd_rsp = &evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp;
208+
209+
if (rd_rsp->count)
210+
{
211+
#if SD_VER < 500
212+
_adamsg.feed(rd_rsp->handle_value[0].p_value, rd_rsp->value_len);
213+
#else
214+
ble_gattc_handle_value_t hdl_value;
215+
216+
if ( ERROR_NONE == sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&evt->evt.gattc_evt, &hdl_value) )
217+
{
218+
_adamsg.feed(hdl_value.p_value, rd_rsp->value_len);
219+
}
220+
#endif
221+
222+
_adamsg.complete();
223+
}
224+
}
210225

211-
if (rd_rsp->count)
226+
case BLE_GATTS_EVT_HVC:
212227
{
213-
#if SD_VER < 500
214-
_adamsg.feed(rd_rsp->handle_value[0].p_value, rd_rsp->value_len);
215-
#else
216-
ble_gattc_handle_value_t hdl_value;
228+
LOG_LV2("GATTS", "Confirm received handle = 0x%04X", evt->evt.gatts_evt.params.hvc.handle);
229+
BLEGap::gap_peer_t* peer = Bluefruit.Gap._get_peer(evt_conn_hdl);
217230

218-
if ( ERROR_NONE == sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&evt->evt.gattc_evt, &hdl_value) )
219-
{
220-
_adamsg.feed(hdl_value.p_value, rd_rsp->value_len);
221-
}
222-
#endif
231+
if ( peer->indicate_confirm_sem ) xSemaphoreGive(peer->indicate_confirm_sem);
232+
peer->hvc_received = true;
233+
}
234+
break;
223235

224-
_adamsg.complete();
236+
case BLE_GATTS_EVT_TIMEOUT:
237+
{
238+
LOG_LV2("GATTS", "Timeout Source = %d", evt->evt.gatts_evt.params.timeout.src);
239+
240+
BLEGap::gap_peer_t* peer = Bluefruit.Gap._get_peer(evt_conn_hdl);
241+
242+
if ( peer->indicate_confirm_sem ) xSemaphoreGive(peer->indicate_confirm_sem);
243+
peer->hvc_received = false;
225244
}
245+
break;
246+
247+
default: break;
226248
}
227249
}
228250

libraries/Bluefruit52Lib/src/BLEGatt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ class BLEGatt
5959
BLEGatt(void);
6060

6161
uint16_t readCharByUuid(uint16_t conn_hdl, BLEUuid bleuuid, void* buffer, uint16_t bufsize, uint16_t start_hdl = 1, uint16_t end_hdl = 0xffff);
62-
// bool waitForIndicateConfirm(uint16_t conn_hdl);
62+
63+
bool waitForIndicateConfirm(uint16_t conn_hdl);
6364

6465
/*------------------------------------------------------------------*/
6566
/* INTERNAL USAGE ONLY

0 commit comments

Comments
 (0)