Skip to content

Commit f23d2b2

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 f23d2b2

1 file changed

Lines changed: 35 additions & 24 deletions

File tree

src/NimBLEClient.cpp

Lines changed: 35 additions & 24 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

@@ -1050,33 +1048,46 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
10501048
} // BLE_GAP_EVENT_TERM_FAILURE
10511049

10521050
case BLE_GAP_EVENT_NOTIFY_RX: {
1053-
if (pClient->m_connHandle != event->notify_rx.conn_handle) return 0;
1054-
NIMBLE_LOGD(LOG_TAG, "Notify Received for handle: %d", event->notify_rx.attr_handle);
1055-
1056-
for (const auto& svc : pClient->m_svcVec) {
1057-
// Dont waste cycles searching services without this handle in its range
1058-
if (svc->getEndHandle() < event->notify_rx.attr_handle) {
1059-
continue;
1060-
}
1061-
1062-
NIMBLE_LOGD(LOG_TAG,
1063-
"checking service %s for handle: %d",
1064-
svc->getUUID().toString().c_str(),
1065-
event->notify_rx.attr_handle);
1051+
if (pClient->m_connHandle != event->notify_rx.conn_handle) {
1052+
return 0;
1053+
}
10661054

1067-
for (const auto& chr : svc->m_vChars) {
1068-
if (chr->getHandle() == event->notify_rx.attr_handle) {
1069-
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", chr->toString().c_str());
1055+
NIMBLE_LOGD(LOG_TAG, "Notify Received for handle: %d", event->notify_rx.attr_handle);
10701056

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);
1057+
NimBLERemoteCharacteristic* pChr = pClient->getCharacteristic(event->notify_rx.attr_handle);
1058+
if (pChr == nullptr) {
1059+
NIMBLE_LOGW(LOG_TAG, "unknown handle: %d", event->notify_rx.attr_handle);
1060+
return BLE_ATT_ERR_INVALID_HANDLE;
1061+
}
10731062

1074-
if (chr->m_notifyCallback != nullptr) {
1075-
chr->m_notifyCallback(chr, event->notify_rx.om->om_data, data_len, !event->notify_rx.indication);
1076-
}
1063+
auto len = event->notify_rx.om->om_len;
1064+
if (pChr->m_value.setValue(event->notify_rx.om->om_data, len)) {
1065+
os_mbuf* next;
1066+
next = SLIST_NEXT(event->notify_rx.om, om_next);
1067+
while (next != NULL) {
1068+
pChr->m_value.append(next->om_data, next->om_len);
1069+
if (pChr->m_value.length() != len + next->om_len) {
1070+
rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
10771071
break;
10781072
}
1073+
len += next->om_len;
1074+
next = SLIST_NEXT(next, om_next);
10791075
}
1076+
} else {
1077+
rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
1078+
}
1079+
1080+
if (rc != 0) { // This should never happen
1081+
NIMBLE_LOGE(LOG_TAG, "notification value error; exceeds limit");
1082+
return rc;
1083+
}
1084+
1085+
if (pChr->m_notifyCallback != nullptr) {
1086+
// TODO: change this callback to use the NimBLEAttValue class instead of raw data and length
1087+
pChr->m_notifyCallback(pChr,
1088+
const_cast<uint8_t*>(pChr->m_value.getValue().data()),
1089+
pChr->m_value.length(),
1090+
!event->notify_rx.indication);
10801091
}
10811092

10821093
return 0;

0 commit comments

Comments
 (0)