#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
#include <sstream>
#include "BLERemoteService.h"
#include "BLEUtils.h"
#include "GeneralUtils.h"
#include <esp_log.h>
#include <esp_err.h>
#ifdef ARDUINO_ARCH_ESP32
#include "esp32-hal-log.h"
#endif
static const char* LOG_TAG = "BLERemoteService";
BLERemoteService::BLERemoteService(
esp_gatt_id_t srvcId,
BLEClient* pClient,
uint16_t startHandle,
uint16_t endHandle
) {
ESP_LOGD(LOG_TAG, ">> BLERemoteService()");
m_srvcId = srvcId;
m_pClient = pClient;
m_uuid = BLEUUID(m_srvcId);
m_haveCharacteristics = false;
m_startHandle = startHandle;
m_endHandle = endHandle;
ESP_LOGD(LOG_TAG, "<< BLERemoteService()");
}
BLERemoteService::~BLERemoteService() {
removeCharacteristics();
}
void BLERemoteService::gattClientEventHandler(
esp_gattc_cb_event_t event,
esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t *evtParam) {
switch(event) {
default: {
break;
}
}
for (auto &myPair : m_characteristicMap) {
myPair.first->gattClientEventHandler(event, gattc_if, evtParam);
}
}
BLERemoteCharacteristic* BLERemoteService::getCharacteristic(const char* uuid) {
return getCharacteristic(BLEUUID(uuid));
}
BLERemoteCharacteristic* BLERemoteService::getCharacteristic(BLEUUID uuid) {
if (!m_haveCharacteristics) {
retrieveCharacteristics();
}
std::string v = uuid.toString();
for (auto &myPair : m_characteristicMap) {
if (myPair.second == v) {
return myPair.first;
}
}
return nullptr;
}
void BLERemoteService::retrieveCharacteristics() {
ESP_LOGD(LOG_TAG, ">> getCharacteristics() for service: %s", getUUID().toString().c_str());
removeCharacteristics();
uint16_t offset = 0;
esp_gattc_char_elem_t result;
while(1) {
uint16_t count = 1;
esp_gatt_status_t status = ::esp_ble_gattc_get_all_char(
getClient()->getGattcIf(),
getClient()->getConnId(),
m_startHandle,
m_endHandle,
&result,
&count,
offset
);
if (status == ESP_GATT_INVALID_OFFSET) {
break;
}
if (status != ESP_GATT_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_get_all_char: %s", BLEUtils::gattStatusToString(status).c_str());
break;
}
if (count == 0) {
break;
}
ESP_LOGD(LOG_TAG, "Found a characteristic: Handle: %d, UUID: %s", result.char_handle, BLEUUID(result.uuid).toString().c_str());
BLERemoteCharacteristic *pNewRemoteCharacteristic = new BLERemoteCharacteristic(
result.char_handle,
BLEUUID(result.uuid),
result.properties,
this
);
m_characteristicMap.insert(std::pair<BLERemoteCharacteristic*, std::string>(pNewRemoteCharacteristic, pNewRemoteCharacteristic->getUUID().toString()));
offset++;
}
m_haveCharacteristics = true;
ESP_LOGD(LOG_TAG, "<< getCharacteristics()");
}
std::map<BLERemoteCharacteristic*, std::string>* BLERemoteService::getCharacteristics() {
ESP_LOGD(LOG_TAG, ">> getCharacteristics() for service: %s", getUUID().toString().c_str());
if (!m_haveCharacteristics) {
retrieveCharacteristics();
}
ESP_LOGD(LOG_TAG, "<< getCharacteristics() for service: %s", getUUID().toString().c_str());
return &m_characteristicMap;
}
BLEClient* BLERemoteService::getClient() {
return m_pClient;
}
uint16_t BLERemoteService::getEndHandle() {
return m_endHandle;
}
esp_gatt_id_t* BLERemoteService::getSrvcId() {
return &m_srvcId;
}
uint16_t BLERemoteService::getStartHandle() {
return m_startHandle;
}
uint16_t BLERemoteService::getHandle() {
ESP_LOGD(LOG_TAG, ">> getHandle: service: %s", getUUID().toString().c_str());
ESP_LOGD(LOG_TAG, "<< getHandle: %d 0x%.2x", getStartHandle(), getStartHandle());
return getStartHandle();
}
BLEUUID BLERemoteService::getUUID() {
return m_uuid;
}
void BLERemoteService::removeCharacteristics() {
for (auto &myPair : m_characteristicMap) {
delete myPair.first;
m_characteristicMap.erase(myPair.first);
}
m_characteristicMap.clear();
}
std::string BLERemoteService::toString() {
std::ostringstream ss;
ss << "Service: uuid: " + m_uuid.toString();
ss << ", start_handle: " << std::dec << m_startHandle << " 0x" << std::hex << m_startHandle <<
", end_handle: " << std::dec << m_endHandle << " 0x" << std::hex << m_endHandle;
for (auto &myPair : m_characteristicMap) {
ss << "\n" << myPair.first->toString();
}
return ss.str();
}
#endif