From 6077421ee0a30771a38626d0d6afb133a0b5d526 Mon Sep 17 00:00:00 2001 From: hjlee Date: Thu, 18 Sep 2025 21:09:42 +0900 Subject: [PATCH 1/4] NimBLEClient::handleGapEvent() { case BLE_GAP_EVENT_PASSKEY_ACTION: } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT || event->passkey.params.action == BLE_SM_IOACT_DISP) { ... } } Add BLE_SM_IOACT_DISP action. This action is necessary when using NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY). --- src/NimBLEClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NimBLEClient.cpp b/src/NimBLEClient.cpp index 02773c44..f42b5c18 100644 --- a/src/NimBLEClient.cpp +++ b/src/NimBLEClient.cpp @@ -1205,7 +1205,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) { // pClient->onOobPairingRequest(pkey.oob); // rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); // NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); - } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) { + } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT || event->passkey.params.action == BLE_SM_IOACT_DISP) { NIMBLE_LOGD(LOG_TAG, "Enter the passkey"); pClient->m_pClientCallbacks->onPassKeyEntry(peerInfo); } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { From 9ac9a72d35872388077b19ce6982921151f64778 Mon Sep 17 00:00:00 2001 From: hjlee Date: Thu, 18 Sep 2025 21:22:13 +0900 Subject: [PATCH 2/4] NimBLERemoteCharacteristic::getProperties(), NimBLERemoteCharacteristic::retrieveDescriptors2() added. --- src/NimBLERemoteCharacteristic.cpp | 64 +++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/NimBLERemoteCharacteristic.cpp b/src/NimBLERemoteCharacteristic.cpp index 2c23ccbf..51206f6e 100644 --- a/src/NimBLERemoteCharacteristic.cpp +++ b/src/NimBLERemoteCharacteristic.cpp @@ -132,6 +132,63 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* pFi return true; } // retrieveDescriptors +bool NimBLERemoteCharacteristic::retrieveDescriptors2(NimBLEDescriptorFilter* pFilter) const { + NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors2() for characteristic: %s", getUUID().toString().c_str()); + + const auto pSvc = getRemoteService(); + uint16_t endHandle = pSvc->getEndHandle(); + + // Find the handle of the next characteristic to limit the descriptor search range. + const auto& chars = pSvc->getCharacteristics(false); + for (auto it = chars.begin(); it != chars.end(); ++it) { + if ((*it)->getHandle() == this->getHandle()) { + auto next_it = std::next(it); + if (next_it != chars.end()) { + endHandle = (*next_it)->getHandle() - 1; + NIMBLE_LOGD(LOG_TAG, "Search range limited to handle 0x%04X", endHandle); + } + break; + } + } + + // If this is the last handle then there are no descriptors + if (getHandle() == endHandle) { + NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors2(): found 0 descriptors."); + return true; + } + + NimBLETaskData taskData(const_cast(this)); + NimBLEDescriptorFilter defaultFilter{nullptr, nullptr, &taskData}; + if (pFilter == nullptr) { + pFilter = &defaultFilter; + } + + int rc = ble_gattc_disc_all_dscs(getClient()->getConnHandle(), + getHandle(), + endHandle, // Use the correctly calculated end handle + NimBLERemoteCharacteristic::descriptorDiscCB, + pFilter); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_dscs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + return false; + } + + auto prevDscCount = m_vDescriptors.size(); + NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER); + rc = ((NimBLETaskData*)pFilter->taskData)->m_flags; + if (rc != BLE_HS_EDONE) { + NIMBLE_LOGE(LOG_TAG, "<< retrieveDescriptors2(): failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + return false; + } + + if (m_vDescriptors.size() > prevDscCount) { + pFilter->dsc = m_vDescriptors.back(); + } + + NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors2(): found %d descriptors.", m_vDescriptors.size() - prevDscCount); + return true; +} // retrieveDescriptors2 + /** * @brief Get the descriptor instance with the given UUID that belongs to this characteristic. * @param [in] uuid The UUID of the descriptor to find. @@ -184,7 +241,8 @@ NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUU const std::vector& NimBLERemoteCharacteristic::getDescriptors(bool refresh) const { if (refresh) { deleteDescriptors(); - retrieveDescriptors(); + //retrieveDescriptors(); + retrieveDescriptors2(); } return m_vDescriptors; @@ -383,6 +441,10 @@ std::string NimBLERemoteCharacteristic::toString() const { return res; } // toString +uint8_t NimBLERemoteCharacteristic::getProperties() const { + return m_properties; +} + NimBLEClient* NimBLERemoteCharacteristic::getClient() const { return getRemoteService()->getClient(); } // getClient From bf35fb835b4352db50d0c8e04e035b43f64ac04e Mon Sep 17 00:00:00 2001 From: hjlee Date: Thu, 18 Sep 2025 21:35:54 +0900 Subject: [PATCH 3/4] NimBLEServerCallbacks::onPassKeyRequest(), NimBLEServer::handleGapEvent() { } else if(event->passkey.params.action == BLE_SM_IOACT_INPUT) { NIMBLE_LOGI(LOG_TAG, "BLE_SM_IOACT_INPUT!!!!"); pServer->m_pServerCallbacks->onPassKeyRequest(peerInfo); } } added. This function/action is necessary when using NimBLEDevice::setSecurityIOCap(BLE_HS_IO_KEYBOARD_ONLY). --- src/NimBLEServer.cpp | 8 +++++++- src/NimBLEServer.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index 5e4f381b..a9cd650f 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -601,7 +601,10 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { NIMBLE_LOGD(LOG_TAG, "No passkey action required"); } - + else if(event->passkey.params.action == BLE_SM_IOACT_INPUT) { + NIMBLE_LOGI(LOG_TAG, "BLE_SM_IOACT_INPUT!!!!"); + pServer->m_pServerCallbacks->onPassKeyRequest(peerInfo); + } break; } // BLE_GAP_EVENT_PASSKEY_ACTION @@ -1032,4 +1035,7 @@ void NimBLEServerCallbacks::onPhyUpdate(NimBLEConnInfo& connInfo, uint8_t txPhy, NIMBLE_LOGD("NimBLEServerCallbacks", "onPhyUpdate: default, txPhy: %d, rxPhy: %d", txPhy, rxPhy); } // onPhyUpdate +void NimBLEServerCallbacks::onPassKeyRequest(NimBLEConnInfo& connInfo) { + NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyRequest: default"); +} // onPassKeyRequest #endif // CONFIG_BT_NIMBLE_ENABLED && MYNEWT_VAL(BLE_ROLE_PERIPHERAL) diff --git a/src/NimBLEServer.h b/src/NimBLEServer.h index 214578ab..e3fac131 100644 --- a/src/NimBLEServer.h +++ b/src/NimBLEServer.h @@ -221,6 +221,7 @@ class NimBLEServerCallbacks { * * BLE_GAP_LE_PHY_CODED */ virtual void onPhyUpdate(NimBLEConnInfo& connInfo, uint8_t txPhy, uint8_t rxPhy); + virtual void onPassKeyRequest(NimBLEConnInfo& connInfo); }; // NimBLEServerCallbacks #endif // CONFIG_BT_NIMBLE_ENABLED && MYNEWT_VAL(BLE_ROLE_PERIPHERAL) From 4b9a77e752b9ea1cd7be1af0c9fa2cd3d671db7b Mon Sep 17 00:00:00 2001 From: hjlee Date: Fri, 19 Sep 2025 10:33:38 +0900 Subject: [PATCH 4/4] add NimBLERemoteCharacteristic::retrieveDescriptors2(), NimBLERemoteCharacteristic::getProperties() to NimBLERemoteCharacteristic.h --- src/NimBLERemoteCharacteristic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/NimBLERemoteCharacteristic.h b/src/NimBLERemoteCharacteristic.h index c1a6ecac..56ec2153 100644 --- a/src/NimBLERemoteCharacteristic.h +++ b/src/NimBLERemoteCharacteristic.h @@ -47,6 +47,7 @@ class NimBLERemoteCharacteristic : public NimBLERemoteValueAttribute { bool canIndicate() const; bool canWriteSigned() const; bool hasExtendedProps() const; + uint8_t getProperties() const; NimBLEClient* getClient() const override; typedef std::function notify_callback; @@ -68,6 +69,7 @@ class NimBLERemoteCharacteristic : public NimBLERemoteValueAttribute { bool setNotify(uint16_t val, notify_callback notifyCallback = nullptr, bool response = true) const; bool retrieveDescriptors(NimBLEDescriptorFilter* pFilter = nullptr) const; + bool retrieveDescriptors2(NimBLEDescriptorFilter* pFilter = nullptr) const; static int descriptorDiscCB( uint16_t connHandle, const ble_gatt_error* error, uint16_t chrHandle, const ble_gatt_dsc* dsc, void* arg);