Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
56 changes: 0 additions & 56 deletions src/NimBLEClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,62 +536,6 @@ uint16_t NimBLEClient::getConnHandle() const {
return m_connHandle;
} // getConnHandle

/**
* @brief Clear the connection information for this client.
* @note This is designed to be used to reset the connection information after
* calling setConnection(), and should not be used to disconnect from a peer.
* To disconnect from a peer, use disconnect().
*/
void NimBLEClient::clearConnection() {
m_connHandle = BLE_HS_CONN_HANDLE_NONE;
m_peerAddress = NimBLEAddress{};
} // clearConnection

/**
* @brief Set the connection information for this client.
* @param [in] connInfo The connection information.
* @return True on success.
* @note Sets the connection established flag to true.
* @note If the client is already connected to a peer, this will return false.
* @note This is designed to be used when a connection is made outside of the
* NimBLEClient class, such as when a connection is made by the
* NimBLEServer class and the client is passed the connection info.
* This enables the GATT Server to read the attributes of the client connected to it.
*/
bool NimBLEClient::setConnection(const NimBLEConnInfo& connInfo) {
if (isConnected()) {
NIMBLE_LOGE(LOG_TAG, "Already connected");
return false;
}

m_peerAddress = connInfo.getAddress();
m_connHandle = connInfo.getConnHandle();
return true;
} // setConnection

/**
* @brief Set the connection information for this client.
* @param [in] connHandle The connection handle.
* @note Sets the connection established flag to true.
* @note This is designed to be used when a connection is made outside of the
* NimBLEClient class, such as when a connection is made by the
* NimBLEServer class and the client is passed the connection handle.
* This enables the GATT Server to read the attributes of the client connected to it.
* @note If the client is already connected to a peer, this will return false.
* @note This will look up the peer address using the connection handle.
*/
bool NimBLEClient::setConnection(uint16_t connHandle) {
// we weren't provided the peer address, look it up using ble_gap_conn_find
NimBLEConnInfo connInfo;
int rc = ble_gap_conn_find(connHandle, &connInfo.m_desc);
if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "Connection info not found");
return false;
}

return setConnection(connInfo);
} // setConnection

/**
* @brief Retrieve the address of the peer.
* @return A NimBLEAddress instance with the peer address data.
Expand Down
6 changes: 2 additions & 4 deletions src/NimBLEClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ class NimBLEClient {
void setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, bool deleteCallbacks = true);
std::string toString() const;
uint16_t getConnHandle() const;
void clearConnection();
bool setConnection(const NimBLEConnInfo& connInfo);
bool setConnection(uint16_t connHandle);
uint16_t getMTU() const;
bool exchangeMTU();
bool secureConnection() const;
Expand Down Expand Up @@ -139,6 +136,7 @@ class NimBLEClient {
ble_gap_conn_params m_connParams;

friend class NimBLEDevice;
friend class NimBLEServer;
}; // class NimBLEClient

/**
Expand All @@ -154,7 +152,7 @@ class NimBLEClientCallbacks {
*/
virtual void onConnect(NimBLEClient* pClient);

/**
/**
* @brief Called when a connection attempt fails.
* @param [in] pClient A pointer to the connecting client object.
* @param [in] reason Contains the reason code for the connection failure.
Expand Down
67 changes: 64 additions & 3 deletions src/NimBLEServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
# include "NimBLEDevice.h"
# include "NimBLELog.h"

# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
# include "NimBLEClient.h"
# endif

# if defined(CONFIG_NIMBLE_CPP_IDF)
# include "services/gap/ble_svc_gap.h"
# include "services/gatt/ble_svc_gatt.h"
Expand Down Expand Up @@ -63,6 +67,10 @@ NimBLEServer::~NimBLEServer() {
if (m_deleteCallbacks) {
delete m_pServerCallbacks;
}

if (m_pClient != nullptr) {
delete m_pClient;
}
}

/**
Expand Down Expand Up @@ -169,7 +177,7 @@ void NimBLEServer::serviceChanged() {
*/
void NimBLEServer::start() {
if (m_gattsStarted) {
return; //already started
return; // already started
}

int rc = ble_gatts_start();
Expand Down Expand Up @@ -497,6 +505,11 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) {
}
}

if (pServer->m_pClient->m_connHandle == event->disconnect.conn.conn_handle) {
// If this was also the client make sure it's flagged as disconnected.
pServer->m_pClient->m_connHandle = BLE_HS_CONN_HANDLE_NONE;
}

if (pServer->m_svcChanged) {
pServer->resetGATT();
}
Expand Down Expand Up @@ -705,8 +718,8 @@ int NimBLEServer::handleGattEvent(uint16_t connHandle, uint16_t attrHandle, ble_
NIMBLE_LOGD(LOG_TAG,
"Gatt %s event",
(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR || ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) ? "Read" : "Write");
auto pAtt = static_cast<NimBLELocalValueAttribute*>(arg);
auto val = pAtt->getAttVal();
auto pAtt = static_cast<NimBLELocalValueAttribute*>(arg);
auto val = pAtt->getAttVal();
NimBLEConnInfo peerInfo{};
ble_gap_conn_find(connHandle, &peerInfo.m_desc);

Expand Down Expand Up @@ -1029,6 +1042,54 @@ void NimBLEServer::setDataLen(uint16_t connHandle, uint16_t octets) const {
# endif
} // setDataLen

# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
/**
* @brief Create a client instance from the connection handle.
* @param [in] connHandle The connection handle to create a client instance from.
* @return A pointer to the NimBLEClient instance or nullptr if there was an error.
* @note Only one instance is supported subsequent calls will overwrite the previous
* client connection information and data.
*/
NimBLEClient* NimBLEServer::getClient(uint16_t connHandle) {
NimBLEConnInfo connInfo;
int rc = ble_gap_conn_find(connHandle, &connInfo.m_desc);
if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "Client info not found");
return nullptr;
}

return getClient(connInfo);
} // getClient

/**
* @brief Create a client instance from the NimBLEConnInfo reference.
* @param [in] connInfo The connection info to create a client instance from.
* @return A pointer to the NimBLEClient instance or nullptr if there was an error.
* @note Only one instance is supported subsequent calls will overwrite the previous
* client connection information and data.
*/
NimBLEClient* NimBLEServer::getClient(const NimBLEConnInfo& connInfo) {
if (m_pClient == nullptr) {
m_pClient = new NimBLEClient(connInfo.getAddress());
}

m_pClient->deleteServices(); // Changed peer connection delete the database.
m_pClient->m_peerAddress = connInfo.getAddress();
m_pClient->m_connHandle = connInfo.getConnHandle();
return m_pClient;
} // getClient

/**
* @brief Delete the NimBLEClient instance that was created with `getClient()`
*/
void NimBLEServer::deleteClient() {
if (m_pClient != nullptr) {
delete m_pClient;
m_pClient = nullptr;
}
} // deleteClient
# endif

/** Default callback handlers */
void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) {
NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default");
Expand Down
13 changes: 13 additions & 0 deletions src/NimBLEServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class NimBLEExtAdvertising;
# else
class NimBLEAdvertising;
# endif
# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
class NimBLEClient;
# endif

/**
* @brief The model of a BLE server.
Expand Down Expand Up @@ -77,6 +80,12 @@ class NimBLEServer {
void advertiseOnDisconnect(bool enable);
void setDataLen(uint16_t connHandle, uint16_t tx_octets) const;

# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
NimBLEClient* getClient(uint16_t connHandle);
NimBLEClient* getClient(const NimBLEConnInfo& connInfo);
void deleteClient();
# endif

# if CONFIG_BT_NIMBLE_EXT_ADV
NimBLEExtAdvertising* getAdvertising() const;
bool startAdvertising(uint8_t instanceId, int duration = 0, int maxEvents = 0) const;
Expand Down Expand Up @@ -115,6 +124,10 @@ class NimBLEServer {
std::vector<NimBLEService*> m_svcVec;
std::array<uint16_t, CONFIG_BT_NIMBLE_MAX_CONNECTIONS> m_connectedPeers;

# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
NimBLEClient* m_pClient{nullptr};
# endif

static int handleGapEvent(struct ble_gap_event* event, void* arg);
static int handleGattEvent(uint16_t connHandle, uint16_t attrHandle, ble_gatt_access_ctxt* ctxt, void* arg);
static int peerNameCB(uint16_t connHandle, const ble_gatt_error* error, ble_gatt_attr* attr, void* arg);
Expand Down
Loading