@@ -112,6 +112,11 @@ bool BLERemoteCharacteristic::canWriteNoResponse() {
112112 * @brief Retrieve the map of descriptors keyed by UUID.
113113 */
114114std::map<std::string, BLERemoteDescriptor *> *BLERemoteCharacteristic::getDescriptors () {
115+ // Retrieve descriptors if not already done (lazy loading)
116+ if (m_descriptorMap.empty ()) {
117+ log_d (" Descriptors not yet retrieved, retrieving now..." );
118+ retrieveDescriptors ();
119+ }
115120 return &m_descriptorMap;
116121} // getDescriptors
117122
@@ -132,6 +137,11 @@ uint16_t BLERemoteCharacteristic::getHandle() {
132137 */
133138BLERemoteDescriptor *BLERemoteCharacteristic::getDescriptor (BLEUUID uuid) {
134139 log_v (" >> getDescriptor: uuid: %s" , uuid.toString ().c_str ());
140+ // Retrieve descriptors if not already done (lazy loading)
141+ if (m_descriptorMap.empty ()) {
142+ log_d (" Descriptors not yet retrieved, retrieving now..." );
143+ retrieveDescriptors ();
144+ }
135145 std::string v = uuid.toString ().c_str ();
136146 for (auto &myPair : m_descriptorMap) {
137147 if (myPair.first == v) {
@@ -663,14 +673,14 @@ BLERemoteCharacteristic::BLERemoteCharacteristic(BLERemoteService *pRemoteServic
663673
664674 m_handle = chr->val_handle ;
665675 m_defHandle = chr->def_handle ;
666- m_endHandle = 0 ;
667676 m_charProp = chr->properties ;
668677 m_pRemoteService = pRemoteService;
669678 m_notifyCallback = nullptr ;
670679 m_rawData = nullptr ;
671680 m_auth = 0 ;
672681
673- retrieveDescriptors (); // Get the descriptors for this characteristic
682+ // Don't retrieve descriptors in constructor for NimBLE to avoid deadlock
683+ // Descriptors will be retrieved on-demand when needed (e.g., for notifications)
674684
675685 log_v (" << BLERemoteCharacteristic(): %s" , m_uuid.toString ().c_str ());
676686} // BLERemoteCharacteristic
@@ -789,7 +799,7 @@ bool BLERemoteCharacteristic::retrieveDescriptors(const BLEUUID *uuid_filter) {
789799 desc_filter_t filter = {uuid_filter, &taskData};
790800 int rc = 0 ;
791801
792- rc = ble_gattc_disc_all_dscs (getRemoteService ()->getClient ()->getConnId (), m_handle, m_endHandle , BLERemoteCharacteristic::descriptorDiscCB, &filter);
802+ rc = ble_gattc_disc_all_dscs (getRemoteService ()->getClient ()->getConnId (), m_handle, getRemoteService ()-> getEndHandle () , BLERemoteCharacteristic::descriptorDiscCB, &filter);
793803
794804 if (rc != 0 ) {
795805 log_e (" ble_gattc_disc_all_dscs: rc=%d %s" , rc, BLEUtils::returnCodeToString (rc));
@@ -966,6 +976,15 @@ bool BLERemoteCharacteristic::setNotify(uint16_t val, notify_callback notifyCall
966976
967977 m_notifyCallback = notifyCallback;
968978
979+ // Retrieve descriptors if not already done (lazy loading)
980+ if (m_descriptorMap.empty ()) {
981+ log_d (" Descriptors not yet retrieved, retrieving now..." );
982+ if (!retrieveDescriptors ()) {
983+ log_e (" << setNotify(): Failed to retrieve descriptors" );
984+ return false ;
985+ }
986+ }
987+
969988 BLERemoteDescriptor *desc = getDescriptor (BLEUUID ((uint16_t )0x2902 ));
970989 if (desc == nullptr ) {
971990 log_w (" << setNotify(): Callback set, CCCD not found" );
0 commit comments