@@ -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