2020-03-30 01:44:20 +02:00
|
|
|
/*
|
|
|
|
* NimBLEClient.h
|
|
|
|
*
|
|
|
|
* Created: on Jan 26 2020
|
|
|
|
* Author H2zero
|
2020-05-14 06:03:56 +02:00
|
|
|
*
|
2020-03-30 01:44:20 +02:00
|
|
|
* Originally:
|
|
|
|
* BLEClient.h
|
|
|
|
*
|
|
|
|
* Created on: Mar 22, 2017
|
|
|
|
* Author: kolban
|
|
|
|
*/
|
|
|
|
|
2024-11-03 02:00:07 +01:00
|
|
|
#ifndef NIMBLE_CPP_CLIENT_H_
|
|
|
|
#define NIMBLE_CPP_CLIENT_H_
|
2020-03-30 01:44:20 +02:00
|
|
|
|
2020-05-14 06:03:56 +02:00
|
|
|
#include "nimconfig.h"
|
2021-09-07 05:14:43 +02:00
|
|
|
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
2020-03-30 01:44:20 +02:00
|
|
|
|
2024-11-03 02:00:07 +01:00
|
|
|
# if defined(CONFIG_NIMBLE_CPP_IDF)
|
|
|
|
# include "host/ble_gap.h"
|
|
|
|
# else
|
|
|
|
# include "nimble/nimble/host/include/host/ble_gap.h"
|
|
|
|
# endif
|
2020-03-30 01:44:20 +02:00
|
|
|
|
2024-11-03 02:00:07 +01:00
|
|
|
# include "NimBLEAddress.h"
|
2020-03-30 01:44:20 +02:00
|
|
|
|
2024-11-03 02:00:07 +01:00
|
|
|
# include <stdint.h>
|
|
|
|
# include <vector>
|
|
|
|
# include <string>
|
|
|
|
|
|
|
|
class NimBLEAddress;
|
|
|
|
class NimBLEUUID;
|
2020-03-30 01:44:20 +02:00
|
|
|
class NimBLERemoteService;
|
2020-09-16 06:09:30 +02:00
|
|
|
class NimBLERemoteCharacteristic;
|
2020-03-30 01:44:20 +02:00
|
|
|
class NimBLEAdvertisedDevice;
|
2024-11-03 02:00:07 +01:00
|
|
|
class NimBLEAttValue;
|
2024-07-26 22:47:36 +02:00
|
|
|
class NimBLEClientCallbacks;
|
2024-11-03 02:00:07 +01:00
|
|
|
class NimBLEConnInfo;
|
|
|
|
struct BleTaskData;
|
2020-03-30 01:44:20 +02:00
|
|
|
|
|
|
|
/**
|
2024-11-03 02:00:07 +01:00
|
|
|
* @brief A model of a BLE client.
|
2020-03-30 01:44:20 +02:00
|
|
|
*/
|
|
|
|
class NimBLEClient {
|
2024-11-03 02:00:07 +01:00
|
|
|
public:
|
2024-10-29 20:50:12 +01:00
|
|
|
bool connect(NimBLEAdvertisedDevice* device,
|
|
|
|
bool deleteAttributes = true,
|
|
|
|
bool asyncConnect = false,
|
|
|
|
bool exchangeMTU = true);
|
|
|
|
bool connect(const NimBLEAddress& address, bool deleteAttributes = true, bool asyncConnect = false, bool exchangeMTU = true);
|
|
|
|
bool connect(bool deleteAttributes = true, bool asyncConnect = false, bool exchangeMTU = true);
|
2024-11-03 02:00:07 +01:00
|
|
|
bool disconnect(uint8_t reason = BLE_ERR_REM_USER_CONN_TERM);
|
2024-11-10 17:11:52 +01:00
|
|
|
bool cancelConnect();
|
2024-11-03 02:00:07 +01:00
|
|
|
NimBLEAddress getPeerAddress() const;
|
|
|
|
bool setPeerAddress(const NimBLEAddress& address);
|
|
|
|
int getRssi() const;
|
|
|
|
bool isConnected() const;
|
|
|
|
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;
|
2024-10-29 20:50:12 +01:00
|
|
|
bool exchangeMTU();
|
2024-11-03 02:00:07 +01:00
|
|
|
bool secureConnection() const;
|
|
|
|
void setConnectTimeout(uint32_t timeout);
|
|
|
|
bool setDataLen(uint16_t txOctets);
|
|
|
|
bool discoverAttributes();
|
|
|
|
NimBLEConnInfo getConnInfo() const;
|
|
|
|
int getLastError() const;
|
|
|
|
bool updateConnParams(uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout);
|
|
|
|
void setConnectionParams(uint16_t minInterval,
|
|
|
|
uint16_t maxInterval,
|
|
|
|
uint16_t latency,
|
|
|
|
uint16_t timeout,
|
|
|
|
uint16_t scanInterval = 16,
|
|
|
|
uint16_t scanWindow = 16);
|
|
|
|
const std::vector<NimBLERemoteService*>& getServices(bool refresh = false);
|
Add iterators to client remote attributes.
Add iterators for NimBLEScan: NimBLEadvertisedDevice, NimBLEClient: NimBLERemoteService, NimBLERemoteService: NimBLERemoteCharacteristic and NimBLERemoteCharacteristic: NimBLERemoteDescriptor
This is handy e.g. for showing every address of the advertised devices from a scan. To do so, first get a new scan and next:
```
for(auto pAdvertisedDevice: pBLEScan->getResults()) {
Serial.printf("Address is %s\n", std::string(pAdvertisedDevice->getAddress()).c_str());
}
```
Of course any other property of the advertised device can be shown (or looked up, if that is your use case)
Also this is handy e.g. for showing every UUID in a peripheral. To do so, first connect to a peripheral and next:
```
for(auto pService: *pClient) {
Serial.printf("Service UUID is %s\n", std::string(pService->getUUID()).c_str());
for(auto pCharacteristic: *pService) {
Serial.printf("Characteristic UUID is %s\n", std::string(pCharacteristic->getUUID()).c_str());
for(auto pDescriptor: *pCharacteristic) {
Serial.printf("Descriptor UUID is %s\n", std::string(pDescriptor->getUUID()).c_str());
}
}
}
```
Again of course any other property can be shown, or looked up.
2020-05-23 04:13:52 +02:00
|
|
|
std::vector<NimBLERemoteService*>::iterator begin();
|
|
|
|
std::vector<NimBLERemoteService*>::iterator end();
|
2024-11-03 02:00:07 +01:00
|
|
|
NimBLERemoteCharacteristic* getCharacteristic(uint16_t handle);
|
2020-05-23 18:27:32 +02:00
|
|
|
NimBLERemoteService* getService(const char* uuid);
|
2024-11-03 02:00:07 +01:00
|
|
|
NimBLERemoteService* getService(const NimBLEUUID& uuid);
|
2020-05-30 05:21:56 +02:00
|
|
|
void deleteServices();
|
2024-11-03 02:00:07 +01:00
|
|
|
size_t deleteService(const NimBLEUUID& uuid);
|
|
|
|
NimBLEAttValue getValue(const NimBLEUUID& serviceUUID, const NimBLEUUID& characteristicUUID);
|
|
|
|
bool setValue(const NimBLEUUID& serviceUUID,
|
|
|
|
const NimBLEUUID& characteristicUUID,
|
|
|
|
const NimBLEAttValue& value,
|
|
|
|
bool response = false);
|
|
|
|
|
|
|
|
# if CONFIG_BT_NIMBLE_EXT_ADV
|
|
|
|
void setConnectPhy(uint8_t mask);
|
|
|
|
# endif
|
|
|
|
|
|
|
|
private:
|
|
|
|
NimBLEClient(const NimBLEAddress& peerAddress);
|
2020-03-30 01:44:20 +02:00
|
|
|
~NimBLEClient();
|
2024-11-03 02:00:07 +01:00
|
|
|
NimBLEClient(const NimBLEClient&) = delete;
|
|
|
|
NimBLEClient& operator=(const NimBLEClient&) = delete;
|
|
|
|
|
|
|
|
bool retrieveServices(const NimBLEUUID* uuidFilter = nullptr);
|
|
|
|
static int handleGapEvent(struct ble_gap_event* event, void* arg);
|
2024-10-29 20:50:12 +01:00
|
|
|
static int exchangeMTUCb(uint16_t conn_handle, const ble_gatt_error* error, uint16_t mtu, void* arg);
|
2024-11-03 02:00:07 +01:00
|
|
|
static int serviceDiscoveredCB(uint16_t connHandle,
|
|
|
|
const struct ble_gatt_error* error,
|
|
|
|
const struct ble_gatt_svc* service,
|
|
|
|
void* arg);
|
|
|
|
|
|
|
|
NimBLEAddress m_peerAddress;
|
|
|
|
mutable int m_lastErr;
|
|
|
|
int32_t m_connectTimeout;
|
|
|
|
mutable BleTaskData* m_pTaskData;
|
|
|
|
std::vector<NimBLERemoteService*> m_svcVec;
|
|
|
|
NimBLEClientCallbacks* m_pClientCallbacks;
|
|
|
|
uint16_t m_connHandle;
|
|
|
|
uint8_t m_terminateFailCount;
|
|
|
|
bool m_deleteCallbacks;
|
|
|
|
bool m_connEstablished;
|
2024-10-29 20:50:12 +01:00
|
|
|
bool m_asyncConnect;
|
|
|
|
bool m_exchangeMTU;
|
2024-11-03 02:00:07 +01:00
|
|
|
# if CONFIG_BT_NIMBLE_EXT_ADV
|
|
|
|
uint8_t m_phyMask;
|
|
|
|
# endif
|
|
|
|
ble_gap_conn_params m_connParams;
|
|
|
|
|
|
|
|
friend class NimBLEDevice;
|
2020-05-14 06:03:56 +02:00
|
|
|
}; // class NimBLEClient
|
2020-03-30 01:44:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Callbacks associated with a %BLE client.
|
|
|
|
*/
|
|
|
|
class NimBLEClientCallbacks {
|
2024-11-03 02:00:07 +01:00
|
|
|
public:
|
2020-03-30 01:44:20 +02:00
|
|
|
virtual ~NimBLEClientCallbacks() {};
|
2020-07-09 03:27:26 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called after client connects.
|
|
|
|
* @param [in] pClient A pointer to the calling client object.
|
|
|
|
*/
|
2020-04-14 03:13:51 +02:00
|
|
|
virtual void onConnect(NimBLEClient* pClient);
|
2020-07-09 03:27:26 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called when disconnected from the server.
|
|
|
|
* @param [in] pClient A pointer to the calling client object.
|
2022-08-27 20:38:53 +02:00
|
|
|
* @param [in] reason Contains the reason code for the disconnection.
|
2020-07-09 03:27:26 +02:00
|
|
|
*/
|
2022-08-27 03:51:19 +02:00
|
|
|
virtual void onDisconnect(NimBLEClient* pClient, int reason);
|
2020-07-09 03:27:26 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called when server requests to update the connection parameters.
|
|
|
|
* @param [in] pClient A pointer to the calling client object.
|
|
|
|
* @param [in] params A pointer to the struct containing the connection parameters requested.
|
2022-07-31 19:00:12 +02:00
|
|
|
* @return True to accept the parameters.
|
2020-07-09 03:27:26 +02:00
|
|
|
*/
|
2020-04-14 03:13:51 +02:00
|
|
|
virtual bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params);
|
2020-07-09 03:27:26 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called when server requests a passkey for pairing.
|
2024-06-07 03:36:14 +02:00
|
|
|
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
|
2020-07-09 03:27:26 +02:00
|
|
|
*/
|
2024-07-26 22:47:36 +02:00
|
|
|
virtual void onPassKeyEntry(NimBLEConnInfo& connInfo);
|
2020-07-09 03:27:26 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called when the pairing procedure is complete.
|
2022-08-27 20:38:53 +02:00
|
|
|
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.\n
|
2020-07-09 03:27:26 +02:00
|
|
|
* This can be used to check the status of the connection encryption/pairing.
|
|
|
|
*/
|
2024-07-26 22:47:36 +02:00
|
|
|
virtual void onAuthenticationComplete(NimBLEConnInfo& connInfo);
|
2020-07-09 03:27:26 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called when using numeric comparision for pairing.
|
2024-06-07 03:36:14 +02:00
|
|
|
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
|
2020-07-09 03:27:26 +02:00
|
|
|
* @param [in] pin The pin to compare with the server.
|
|
|
|
*/
|
2024-11-03 02:00:07 +01:00
|
|
|
virtual void onConfirmPasskey(NimBLEConnInfo& connInfo, uint32_t pin);
|
2024-06-12 17:26:10 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called when the peer identity address is resolved.
|
|
|
|
* @param [in] connInfo A reference to a NimBLEConnInfo instance with information
|
|
|
|
*/
|
2024-07-26 22:47:36 +02:00
|
|
|
virtual void onIdentity(NimBLEConnInfo& connInfo);
|
2024-10-29 20:50:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Called when the connection MTU changes.
|
|
|
|
* @param [in] pClient A pointer to the client that the MTU change is associated with.
|
|
|
|
* @param [in] MTU The new MTU value.
|
|
|
|
* about the peer connection parameters.
|
|
|
|
*/
|
|
|
|
virtual void onMTUChange(NimBLEClient* pClient, uint16_t MTU);
|
2020-03-30 01:44:20 +02:00
|
|
|
};
|
|
|
|
|
2021-09-07 05:14:43 +02:00
|
|
|
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */
|
2024-11-03 02:00:07 +01:00
|
|
|
#endif /* NIMBLE_CPP_CLIENT_H_ */
|