Skip to content

Commit 970537a

Browse files
committed
[Bugfix] Missing notification data when length > 255 bytes
When the ACL buffer is less than the MTU, the data arrives in more than one mbuf. This combines the data from the mbuf chain and stores it before calling the appliation callback, ensuring it has all the data.
1 parent 13dc292 commit 970537a

1 file changed

Lines changed: 20 additions & 6 deletions

File tree

src/NimBLEClient.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,6 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
933933

934934
switch (event->type) {
935935
case BLE_GAP_EVENT_DISCONNECT: {
936-
937936
// workaround for bug in NimBLE stack where disconnect event argument is not passed correctly
938937
pClient = NimBLEDevice::getClientByPeerAddress(event->disconnect.conn.peer_ota_addr);
939938
if (pClient == nullptr) {
@@ -946,8 +945,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
946945
}
947946

948947
if (pClient == nullptr) {
949-
NIMBLE_LOGE(LOG_TAG, "Disconnected client not found, conn_handle=%d",
950-
event->disconnect.conn.conn_handle);
948+
NIMBLE_LOGE(LOG_TAG, "Disconnected client not found, conn_handle=%d", event->disconnect.conn.conn_handle);
951949
return 0;
952950
}
953951

@@ -1068,11 +1066,27 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
10681066
if (chr->getHandle() == event->notify_rx.attr_handle) {
10691067
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", chr->toString().c_str());
10701068

1071-
uint32_t data_len = OS_MBUF_PKTLEN(event->notify_rx.om);
1072-
chr->m_value.setValue(event->notify_rx.om->om_data, data_len);
1069+
uint8_t buf[BLE_ATT_ATTR_MAX_LEN];
1070+
uint16_t len = event->notify_rx.om->om_len;
1071+
memcpy(buf, event->notify_rx.om->om_data, len);
1072+
1073+
os_mbuf* next;
1074+
next = SLIST_NEXT(event->notify_rx.om, om_next);
1075+
while (next != NULL) {
1076+
if ((len + next->om_len) > BLE_ATT_ATTR_MAX_LEN) {
1077+
NIMBLE_LOGE(LOG_TAG,
1078+
"Received notification is too long for buffer, dropping remaining data");
1079+
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
1080+
}
1081+
memcpy(&buf[len], next->om_data, next->om_len);
1082+
len += next->om_len;
1083+
next = SLIST_NEXT(next, om_next);
1084+
}
1085+
1086+
chr->m_value.setValue(buf, len);
10731087

10741088
if (chr->m_notifyCallback != nullptr) {
1075-
chr->m_notifyCallback(chr, event->notify_rx.om->om_data, data_len, !event->notify_rx.indication);
1089+
chr->m_notifyCallback(chr, buf, len, !event->notify_rx.indication);
10761090
}
10771091
break;
10781092
}

0 commit comments

Comments
 (0)