#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>
static const char* LOG_TAG = "BLERemoteService";
BLERemoteService::BLERemoteService(
esp_gatt_srvc_id_t srvcId,
BLEClient *pClient) {
m_srvcId = srvcId;
m_pClient = pClient;
m_uuid = BLEUUID(m_srvcId);
m_haveCharacteristics = false;
}
BLERemoteService::~BLERemoteService() {
removeCharacteristics();
}
static bool compareSrvcId(esp_gatt_srvc_id_t id1, esp_gatt_srvc_id_t id2) {
if (id1.id.inst_id != id2.id.inst_id) {
return false;
}
if (!BLEUUID(id1.id.uuid).equals(BLEUUID(id2.id.uuid))) {
return false;
}
return true;
}
void BLERemoteService::gattClientEventHandler(
esp_gattc_cb_event_t event,
esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t *evtParam) {
switch(event) {
case ESP_GATTC_GET_CHAR_EVT: {
if (compareSrvcId(m_srvcId, evtParam->get_char.srvc_id) == false) {
break;
}
if (evtParam->get_char.status != ESP_GATT_OK) {
m_semaphoreGetCharEvt.give();
break;
}
m_characteristicMap.insert(std::pair<std::string, BLERemoteCharacteristic*>(
BLEUUID(evtParam->get_char.char_id.uuid).toString(),
new BLERemoteCharacteristic(evtParam->get_char.char_id, evtParam->get_char.char_prop, this) ));
esp_err_t errRc = ::esp_ble_gattc_get_characteristic(
m_pClient->getGattcIf(),
m_pClient->getConnId(),
&m_srvcId,
&evtParam->get_char.char_id);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_get_characteristic: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
break;
}
break;
}
default: {
break;
}
}
for (auto &myPair : m_characteristicMap) {
myPair.second->gattClientEventHandler(event, gattc_if, evtParam);
}
}
BLERemoteCharacteristic* BLERemoteService::getCharacteristic(const char* uuid) {
return getCharacteristic(BLEUUID(uuid));
}
BLERemoteCharacteristic* BLERemoteService::getCharacteristic(BLEUUID uuid) {
if (!m_haveCharacteristics) {
getCharacteristics();
}
std::string v = uuid.toString();
for (auto &myPair : m_characteristicMap) {
if (myPair.first == v) {
return myPair.second;
}
}
return nullptr;
}
void BLERemoteService::getCharacteristics() {
ESP_LOGD(LOG_TAG, ">> getCharacteristics() for service: %s", getUUID().toString().c_str());
removeCharacteristics();
m_semaphoreGetCharEvt.take("getCharacteristics");
esp_err_t errRc = ::esp_ble_gattc_get_characteristic(
m_pClient->getGattcIf(),
m_pClient->getConnId(),
&m_srvcId,
nullptr);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_get_characteristic: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
m_semaphoreGetCharEvt.wait("getCharacteristics");
m_haveCharacteristics = true;
ESP_LOGD(LOG_TAG, "<< getCharacteristics()");
}
BLEClient* BLERemoteService::getClient() {
return m_pClient;
}
esp_gatt_srvc_id_t* BLERemoteService::getSrvcId() {
return &m_srvcId;
}
BLEUUID BLERemoteService::getUUID() {
return m_uuid;
}
void BLERemoteService::removeCharacteristics() {
for (auto &myPair : m_characteristicMap) {
delete myPair.second;
}
m_characteristicMap.empty();
}
std::string BLERemoteService::toString() {
std::ostringstream ss;
ss << "Service: uuid: " + m_uuid.toString();
for (auto &myPair : m_characteristicMap) {
ss << "\n" << myPair.second->toString();
}
return ss.str();
}
#endif