Skip to content
Merged

Test #405

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions examples/Bluetooth_5/NimBLE_extended_server/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ extern "C" void app_main(void) {

pCharacteristic->setValue("Hello World");

/** Start the service */
pService->start();

/**
* Create an extended advertisement with the instance ID 0 and set the PHY's.
* Multiple instances can be added as long as the instance ID is incremented.
Expand Down
3 changes: 0 additions & 3 deletions examples/Bluetooth_5/NimBLE_multi_advertiser/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ extern "C" void app_main(void) {

pCharacteristic->setValue("Hello World");

/** Start the service */
pService->start();

/** Create our multi advertising instances */

/** extended scannable instance advertising on coded and 1m PHY's. */
Expand Down
4 changes: 0 additions & 4 deletions examples/NimBLE_Server/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,6 @@ extern "C" void app_main(void) {
pC01Ddsc->setValue("Send it back!");
pC01Ddsc->setCallbacks(&dscCallbacks);

/** Start the services when finished creating all Characteristics and Descriptors */
pDeadService->start();
pBaadService->start();

/** Create an advertising instance and add the services to the advertised data */
NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising();
pAdvertising->setName("NimBLE-Server");
Expand Down
5 changes: 3 additions & 2 deletions src/NimBLEAdvertising.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,9 @@ bool NimBLEAdvertising::start(uint32_t duration, const NimBLEAddress* dirAddr) {

# if MYNEWT_VAL(BLE_ROLE_PERIPHERAL)
NimBLEServer* pServer = NimBLEDevice::getServer();
if (pServer != nullptr) {
pServer->start(); // make sure the GATT server is ready before advertising
if (pServer != nullptr && !pServer->start()) { // make sure the GATT server is ready before advertising
NIMBLE_LOGE(LOG_TAG, "Failed to start GATT server");
return false;
}
# endif

Expand Down
16 changes: 15 additions & 1 deletion src/NimBLEClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,16 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
break;
}

if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
struct ble_sm_io pkey = {0, 0};
pkey.action = event->passkey.params.action;
pkey.passkey = NimBLEDevice::getSecurityPasskey();
if (pkey.passkey == 123456) {
pkey.passkey = pClient->m_pClientCallbacks->onPassKeyDisplay(peerInfo);
}
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc);
} else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %" PRIu32, event->passkey.params.numcmp);
pClient->m_pClientCallbacks->onConfirmPasskey(peerInfo, event->passkey.params.numcmp);
} else if (event->passkey.params.action == BLE_SM_IOACT_OOB) {
Expand Down Expand Up @@ -1314,6 +1323,11 @@ void NimBLEClientCallbacks::onPassKeyEntry(NimBLEConnInfo& connInfo) {
NimBLEDevice::injectPassKey(connInfo, 123456);
} // onPassKeyEntry

uint32_t NimBLEClientCallbacks::onPassKeyDisplay(NimBLEConnInfo& connInfo) {
NIMBLE_LOGD(CB_TAG, "onPassKeyDisplay: default");
return NimBLEDevice::getSecurityPasskey();
} // onPassKeyDisplay

void NimBLEClientCallbacks::onAuthenticationComplete(NimBLEConnInfo& connInfo) {
NIMBLE_LOGD(CB_TAG, "onAuthenticationComplete: default");
} // onAuthenticationComplete
Expand Down
7 changes: 7 additions & 0 deletions src/NimBLEClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ class NimBLEClientCallbacks {
*/
virtual void onPassKeyEntry(NimBLEConnInfo& connInfo);

/**
* @brief Called when using passkey entry pairing and the passkey should be displayed.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
* @return The passkey to display to the user. The peer device must enter this passkey to complete the pairing.
*/
virtual uint32_t onPassKeyDisplay(NimBLEConnInfo& connInfo);

/**
* @brief Called when the pairing procedure is complete.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.\n
Expand Down
80 changes: 80 additions & 0 deletions src/NimBLECppVersion.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef NIMBLE_CPP_VERSION_H_
#define NIMBLE_CPP_VERSION_H_

/** @brief NimBLE-Arduino library major version number. */
#define NIMBLE_CPP_VERSION_MAJOR 2

/** @brief NimBLE-Arduino library minor version number. */
#define NIMBLE_CPP_VERSION_MINOR 3

/** @brief NimBLE-Arduino library patch version number. */
#define NIMBLE_CPP_VERSION_PATCH 9

/**
* @brief Macro to create a version number for comparison.
* @param major Major version number.
* @param minor Minor version number.
* @param patch Patch version number.
* @details Example usage:
* @code{.cpp}
* #if NIMBLE_CPP_VERSION >= NIMBLE_CPP_VERSION_VAL(2, 0, 0)
* // Using NimBLE-Arduino v2 or later
* #endif
* @endcode
*/
#define NIMBLE_CPP_VERSION_VAL(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch))

/**
* @brief The library version as a single integer for compile-time comparison.
* @details Format: (major << 16) | (minor << 8) | patch
*/
#define NIMBLE_CPP_VERSION \
NIMBLE_CPP_VERSION_VAL(NIMBLE_CPP_VERSION_MAJOR, NIMBLE_CPP_VERSION_MINOR, NIMBLE_CPP_VERSION_PATCH)

/** @cond NIMBLE_CPP_INTERNAL */
#define NIMBLE_CPP_VERSION_STRINGIFY_IMPL(x) #x
#define NIMBLE_CPP_VERSION_STRINGIFY(x) NIMBLE_CPP_VERSION_STRINGIFY_IMPL(x)
/** @endcond */

/**
* @brief Optional Semantic Versioning prerelease suffix.
* @details Include the leading '-' when defined, for example: "-beta.1"
*/
#ifndef NIMBLE_CPP_VERSION_PRERELEASE
# define NIMBLE_CPP_VERSION_PRERELEASE ""
#endif

/**
* @brief Optional Semantic Versioning build metadata suffix.
* @details Include the leading '+' when defined, for example: "+sha.abcd1234"
*/
#ifndef NIMBLE_CPP_VERSION_BUILD_METADATA
# define NIMBLE_CPP_VERSION_BUILD_METADATA ""
#endif

/** @brief library version as a prefixed Semantic Versioning string. */
#define NIMBLE_CPP_VERSION_STR \
"NimBLE-CPP " \
NIMBLE_CPP_VERSION_STRINGIFY(NIMBLE_CPP_VERSION_MAJOR) "." \
NIMBLE_CPP_VERSION_STRINGIFY(NIMBLE_CPP_VERSION_MINOR) "." \
NIMBLE_CPP_VERSION_STRINGIFY(NIMBLE_CPP_VERSION_PATCH) \
NIMBLE_CPP_VERSION_PRERELEASE NIMBLE_CPP_VERSION_BUILD_METADATA

#endif // NIMBLE_CPP_VERSION_H_
15 changes: 11 additions & 4 deletions src/NimBLEDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,6 @@ extern "C" int ble_vhci_disc_duplicate_mode_enable(int mode);
NimBLEServer* NimBLEDevice::createServer() {
if (NimBLEDevice::m_pServer == nullptr) {
NimBLEDevice::m_pServer = new NimBLEServer();
ble_gatts_reset();
ble_svc_gap_init();
ble_svc_gatt_init();
}

return m_pServer;
Expand Down Expand Up @@ -867,7 +864,7 @@ void NimBLEDevice::onSync(void) {
* @brief The main host task.
*/
void NimBLEDevice::host_task(void* param) {
NIMBLE_LOGI(LOG_TAG, "BLE Host Task Started");
NIMBLE_LOGI(LOG_TAG, "NimBLE Started!");
nimble_port_run(); // This function will return only when nimble_port_stop() is executed
nimble_port_freertos_deinit();
} // host_task
Expand All @@ -878,6 +875,7 @@ void NimBLEDevice::host_task(void* param) {
*/
bool NimBLEDevice::init(const std::string& deviceName) {
if (!m_initialized) {
NIMBLE_LOGD(LOG_TAG, "Starting %s", getVersion());
# ifdef ESP_PLATFORM

# if defined(CONFIG_ENABLE_ARDUINO_DEPENDS) && SOC_BT_SUPPORTED
Expand Down Expand Up @@ -999,6 +997,7 @@ bool NimBLEDevice::init(const std::string& deviceName) {
}

m_initialized = true; // Set the initialization flag to ensure we are only initialized once.
NIMBLE_LOGD(LOG_TAG, "Initialized");
return true;
} // init

Expand Down Expand Up @@ -1329,6 +1328,14 @@ std::string NimBLEDevice::toString() {
return getAddress().toString();
} // toString

/**
* @brief Return the library version as a string.
* @return A const char* containing library version information.
*/
const char* NimBLEDevice::getVersion() {
return NIMBLE_CPP_VERSION_STR;
} // getVersion

# if MYNEWT_VAL(NIMBLE_CPP_DEBUG_ASSERT_ENABLED) || __DOXYGEN__
/**
* @brief Debug assert - weak function.
Expand Down
2 changes: 2 additions & 0 deletions src/NimBLEDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef NIMBLE_CPP_DEVICE_H_
#define NIMBLE_CPP_DEVICE_H_

#include "NimBLECppVersion.h"
#include "syscfg/syscfg.h"
#if CONFIG_BT_NIMBLE_ENABLED
# ifdef ESP_PLATFORM
Expand Down Expand Up @@ -123,6 +124,7 @@ class NimBLEDevice {
static bool isInitialized();
static NimBLEAddress getAddress();
static std::string toString();
static const char* getVersion();
static bool whiteListAdd(const NimBLEAddress& address);
static bool whiteListRemove(const NimBLEAddress& address);
static bool onWhiteList(const NimBLEAddress& address);
Expand Down
47 changes: 37 additions & 10 deletions src/NimBLEServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,18 @@ void NimBLEServer::gattRegisterCallback(ble_gatt_register_ctxt* ctxt, void* arg)
* @details Required to be called after setup of all services and characteristics / descriptors
* for the NimBLE host to register them.
*/
void NimBLEServer::start() {
bool NimBLEServer::start() {
if (m_svcChanged && !getConnectedCount()) {
NIMBLE_LOGD(LOG_TAG, "Services have changed since last start, resetting GATT server");
resetGATT();
m_gattsStarted = false;
}

if (m_gattsStarted) {
return; // already started
return true; // already started
}

if (!resetGATT()) {
return false;
}

ble_hs_cfg.gatts_register_cb = NimBLEServer::gattRegisterCallback;
Expand All @@ -286,7 +290,7 @@ void NimBLEServer::start() {
int rc = ble_gatts_start();
if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "ble_gatts_start; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc));
return;
return false;
}

# if MYNEWT_VAL(NIMBLE_CPP_LOG_LEVEL) >= 4
Expand All @@ -313,6 +317,7 @@ void NimBLEServer::start() {
}

m_gattsStarted = true;
return true;
} // start

/**
Expand All @@ -335,7 +340,7 @@ bool NimBLEServer::disconnect(uint16_t connHandle, uint8_t reason) const {
* @brief Disconnect the specified client with optional reason.
* @param [in] connInfo Connection of the client to disconnect.
* @param [in] reason code for disconnecting.
* @return NimBLE host return code.
* @return True if successful.
*/
bool NimBLEServer::disconnect(const NimBLEConnInfo& connInfo, uint8_t reason) const {
return disconnect(connInfo.getConnHandle(), reason);
Expand Down Expand Up @@ -505,7 +510,7 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) {

peerInfo.m_desc = event->disconnect.conn;
pServer->m_pServerCallbacks->onDisconnect(pServer, peerInfo, event->disconnect.reason);
# if !MYNEWT_VAL(BLE_EXT_ADV)
# if !MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_ROLE_BROADCASTER)
if (pServer->m_advertiseOnDisconnect) {
pServer->startAdvertising();
}
Expand Down Expand Up @@ -684,6 +689,15 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) {
// }
// rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
// NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_OOB; ble_sm_inject_io result: %d", rc);
} else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
NIMBLE_LOGD(LOG_TAG, "Enter the passkey");

rc = ble_gap_conn_find(event->passkey.conn_handle, &peerInfo.m_desc);
if (rc != 0) {
return BLE_ATT_ERR_INVALID_HANDLE;
}

pServer->m_pServerCallbacks->onPassKeyEntry(peerInfo);
} else if (event->passkey.params.action == BLE_SM_IOACT_NONE) {
NIMBLE_LOGD(LOG_TAG, "No passkey action required");
}
Expand Down Expand Up @@ -854,8 +868,13 @@ void NimBLEServer::addService(NimBLEService* service) {

/**
* @brief Resets the GATT server, used when services are added/removed after initialization.
* @return True if successful.
* @details This will reset the GATT server and re-register all services, characteristics, and
* descriptors that have not been removed. Services, characteristics, and descriptors that have been
* removed but not deleted will be skipped and have their handles cleared, and those that have been
* deleted will be removed from the server's service vector.
*/
void NimBLEServer::resetGATT() {
bool NimBLEServer::resetGATT() {
# if MYNEWT_VAL(BLE_ROLE_BROADCASTER)
NimBLEDevice::stopAdvertising();
# endif
Expand All @@ -864,8 +883,6 @@ void NimBLEServer::resetGATT() {
ble_svc_gap_init();
ble_svc_gatt_init();

m_gattsStarted = false;

for (auto svcIt = m_svcVec.begin(); svcIt != m_svcVec.end();) {
auto* pSvc = *svcIt;
if (pSvc->getRemoved() == NIMBLE_ATT_REMOVE_DELETE) {
Expand Down Expand Up @@ -899,12 +916,17 @@ void NimBLEServer::resetGATT() {
}

if (pSvc->getRemoved() == 0) {
pSvc->start();
if (!pSvc->start_internal()) {
NIMBLE_LOGE(LOG_TAG, "Failed to start service: %s", pSvc->getUUID().toString().c_str());
return false;
}
}

pSvc->m_handle = 0;
++svcIt;
}

return true;
} // resetGATT

/**
Expand Down Expand Up @@ -1119,6 +1141,11 @@ uint32_t NimBLEServerCallbacks::onPassKeyDisplay() {
return 123456;
} // onPassKeyDisplay

void NimBLEServerCallbacks::onPassKeyEntry(NimBLEConnInfo& connInfo) {
NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyEntry: default: 123456");
NimBLEDevice::injectPassKey(connInfo, 123456);
} // onPassKeyEntry

void NimBLEServerCallbacks::onConfirmPassKey(NimBLEConnInfo& connInfo, uint32_t pin) {
NIMBLE_LOGD("NimBLEServerCallbacks", "onConfirmPasskey: default: true");
NimBLEDevice::injectConfirmPasskey(connInfo, true);
Expand Down
Loading