From 4063b552709b912932438010528ad733a2b355ca Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Thu, 18 Jun 2026 21:52:46 -0400 Subject: [PATCH] Restore GAP device name after GATT reset ESP-IDF NimBLE can reset the GAP Device Name when the standard GAP service is reinitialized during GATT server startup. NimBLEDevice::init(deviceName) calls NimBLEDevice::setDeviceName(deviceName), but that happens before the server is started. Later, starting advertising starts the server and resets/re-registers the GAP service, causing the C GAP name backing storage to be rebuilt from CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME. In projects where that Kconfig default remains "nimble", the advertised Local Name can be correct while the Generic Access Device Name characteristic reports "nimble". The failing sequence is: -> pAdvertising->start() -> NimBLEAdvertising::start() -> NimBLEDevice::getServer()->start() -> NimBLEServer::resetGATT() -> ble_gatts_reset() -> ble_svc_gap_init() -> ESP-IDF NimBLE resets GAP name to CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME -> "nimble" -> ble_svc_gatt_init() Fix this by saving the device name supplied through NimBLEDevice::setDeviceName() and reapplying it immediately after ble_svc_gap_init() in NimBLEServer::resetGATT(). This preserves the C++ wrapper contract that the configured device name remains effective even when the wrapper internally resets the GATT/GAP service tables. --- src/NimBLEDevice.cpp | 4 ++++ src/NimBLEDevice.h | 2 ++ src/NimBLEServer.cpp | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index 06cb7865..db3f9d9d 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -95,6 +95,8 @@ bool NimBLEDevice::m_initialized{false}; uint32_t NimBLEDevice::m_passkey{123456}; bool NimBLEDevice::m_synced{false}; ble_gap_event_listener NimBLEDevice::m_listener{}; +std::string NimBLEDevice::m_deviceName{}; +bool NimBLEDevice::m_deviceNameSet{false}; std::vector NimBLEDevice::m_whiteList{}; uint8_t NimBLEDevice::m_ownAddrType{BLE_OWN_ADDR_PUBLIC}; @@ -1326,6 +1328,8 @@ bool NimBLEDevice::setDeviceName(const std::string& deviceName) { return false; } # endif + m_deviceName = deviceName; + m_deviceNameSet = true; return true; } // setDeviceName diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index fb64c83d..98ef8b77 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -219,6 +219,8 @@ class NimBLEDevice { static uint32_t m_passkey; static ble_gap_event_listener m_listener; static uint8_t m_ownAddrType; + static std::string m_deviceName; + static bool m_deviceNameSet; static std::vector m_whiteList; static NimBLEDeviceCallbacks* m_pDeviceCallbacks; static NimBLEDeviceCallbacks defaultDeviceCallbacks; diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index 1cab58ed..6c8616a9 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -891,6 +891,10 @@ bool NimBLEServer::resetGATT() { ble_gatts_reset(); ble_svc_gap_init(); + if (NimBLEDevice::m_deviceNameSet && !NimBLEDevice::setDeviceName(NimBLEDevice::m_deviceName)) { + return false; + } + ble_svc_gatt_init(); for (auto svcIt = m_svcVec.begin(); svcIt != m_svcVec.end();) {