Skip to content
Open
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
43 changes: 39 additions & 4 deletions src/NimBLEServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ NimBLEServer::NimBLEServer()
: m_gattsStarted{false},
m_svcChanged{false},
m_deleteCallbacks{false},
m_registerAppServicesFirst{false},
# if !MYNEWT_VAL(BLE_EXT_ADV)
m_advertiseOnDisconnect{false},
# endif
Expand Down Expand Up @@ -366,6 +367,20 @@ void NimBLEServer::advertiseOnDisconnect(bool enable) {
} // advertiseOnDisconnect
# endif

/**
* @brief Register the application's services before the standard GAP/GATT services.
* @param [in] enable true == register the application services first (they take the
Comment thread
finger563 marked this conversation as resolved.
* low attribute handles, starting at 0x0001, and GAP/GATT are placed after them);
* false (default) == the standard behavior, GAP/GATT register first and take the low
* handles.
* @details Must be called before the services are started (i.e. before
* NimBLEServer::start()). Useful when a peripheral must expose a fixed attribute-table
* layout that another device relies on by hardcoded handle rather than discovery.
*/
void NimBLEServer::registerAppServicesFirst(bool enable) {
m_registerAppServicesFirst = enable;
} // registerAppServicesFirst

/**
* @brief Return the number of connected clients.
* @return The number of connected clients.
Expand Down Expand Up @@ -897,14 +912,24 @@ bool NimBLEServer::resetGATT() {
#endif

ble_gatts_reset();
ble_svc_gap_init();

// Register the standard GAP (0x1800) and GATT (0x1801) services, restoring the
// device name/appearance that ble_gatts_reset() clears. By default this happens
// first, so GAP/GATT take the low attribute handles (0x0001+). When
// registerAppServicesFirst() is enabled, it is deferred until after the application
// services below, so those take the low handles instead.
auto initGapGattServices = [&]() {
ble_svc_gap_init();
#ifndef CONFIG_USING_NIMBLE_COMPONENT
ble_svc_gap_device_name_set(name.c_str());
ble_svc_gap_device_appearance_set(appearance);
ble_svc_gap_device_name_set(name.c_str());
ble_svc_gap_device_appearance_set(appearance);
#endif
ble_svc_gatt_init();
};

ble_svc_gatt_init();
if (!m_registerAppServicesFirst) {
initGapGattServices();
}

for (auto svcIt = m_svcVec.begin(); svcIt != m_svcVec.end();) {
auto* pSvc = *svcIt;
Expand Down Expand Up @@ -941,6 +966,12 @@ bool NimBLEServer::resetGATT() {
if (pSvc->getRemoved() == 0) {
if (!pSvc->start_internal()) {
NIMBLE_LOGE(LOG_TAG, "Failed to start service: %s", pSvc->getUUID().toString().c_str());
// When deferring GAP/GATT (registerAppServicesFirst), still register
// them on the failure path so the mandatory GAP/GATT services (and
// the restored name/appearance) are never left out of the database.
if (m_registerAppServicesFirst) {
initGapGattServices();
}
return false;
}
}
Expand All @@ -949,6 +980,10 @@ bool NimBLEServer::resetGATT() {
++svcIt;
}

if (m_registerAppServicesFirst) {
initGapGattServices();
}

return true;
} // resetGATT

Expand Down
2 changes: 2 additions & 0 deletions src/NimBLEServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class NimBLEServer {
NimBLEConnInfo getPeerInfo(const NimBLEAddress& address) const;
NimBLEConnInfo getPeerInfoByHandle(uint16_t connHandle) const;
void advertiseOnDisconnect(bool enable);
void registerAppServicesFirst(bool enable);
void setDataLen(uint16_t connHandle, uint16_t tx_octets) const;
bool updatePhy(uint16_t connHandle, uint8_t txPhysMask, uint8_t rxPhysMask, uint16_t phyOptions);
bool getPhy(uint16_t connHandle, uint8_t* txPhy, uint8_t* rxPhy);
Expand Down Expand Up @@ -129,6 +130,7 @@ class NimBLEServer {
bool m_gattsStarted : 1;
bool m_svcChanged : 1;
bool m_deleteCallbacks : 1;
bool m_registerAppServicesFirst : 1;
# if !MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_ROLE_BROADCASTER)
bool m_advertiseOnDisconnect : 1;
# endif
Expand Down