#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
#include <esp_log.h>
#include <esp_bt.h>
#include <esp_bt_main.h>
#include <esp_gap_ble_api.h>
#include "BLEDevice.h"
#include "BLEServer.h"
#include "BLEService.h"
#include "BLEUtils.h"
#include <string.h>
#include <string>
#include <gatt_api.h>
#include <unordered_set>
#ifdef ARDUINO_ARCH_ESP32
#include "esp32-hal-log.h"
#endif
static const char* LOG_TAG = "BLEServer";
BLEServer::BLEServer() {
m_appId = -1;
m_gatts_if = -1;
m_connectedCount = 0;
m_connId = -1;
m_pServerCallbacks = nullptr;
}
void BLEServer::createApp(uint16_t appId) {
m_appId = appId;
registerApp();
}
BLEService* BLEServer::createService(const char* uuid) {
return createService(BLEUUID(uuid));
}
BLEService* BLEServer::createService(BLEUUID uuid, uint32_t numHandles) {
ESP_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str());
m_semaphoreCreateEvt.take("createService");
if (m_serviceMap.getByUUID(uuid) != nullptr) {
ESP_LOGE(LOG_TAG, "<< Attempt to create a new service with uuid %s but a service with that UUID already exists.",
uuid.toString().c_str());
m_semaphoreCreateEvt.give();
return nullptr;
}
BLEService* pService = new BLEService(uuid, numHandles);
m_serviceMap.setByUUID(uuid, pService);
pService->executeCreate(this);
m_semaphoreCreateEvt.wait("createService");
ESP_LOGD(LOG_TAG, "<< createService");
return pService;
}
BLEAdvertising* BLEServer::getAdvertising() {
return &m_bleAdvertising;
}
uint16_t BLEServer::getConnId() {
return m_connId;
}
uint32_t BLEServer::getConnectedCount() {
return m_connectedCount;
}
uint16_t BLEServer::getGattsIf() {
return m_gatts_if;
}
void BLEServer::handleGAPEvent(
esp_gap_ble_cb_event_t event,
esp_ble_gap_cb_param_t* param) {
ESP_LOGD(LOG_TAG, "BLEServer ... handling GAP event!");
switch(event) {
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: {
break;
}
default:
break;
}
}
void BLEServer::handleGATTServerEvent(
esp_gatts_cb_event_t event,
esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t* param) {
ESP_LOGD(LOG_TAG, ">> handleGATTServerEvent: %s",
BLEUtils::gattServerEventTypeToString(event).c_str());
m_serviceMap.handleGATTServerEvent(event, gatts_if, param);
switch(event) {
case ESP_GATTS_ADD_CHAR_EVT: {
break;
}
case ESP_GATTS_CONNECT_EVT: {
m_connId = param->connect.conn_id;
if (m_pServerCallbacks != nullptr) {
m_pServerCallbacks->onConnect(this);
}
m_connectedCount++;
break;
}
case ESP_GATTS_CREATE_EVT: {
BLEService* pService = m_serviceMap.getByUUID(param->create.service_id.id.uuid);
m_serviceMap.setByHandle(param->create.service_handle, pService);
m_semaphoreCreateEvt.give();
break;
}
case ESP_GATTS_DISCONNECT_EVT: {
m_connectedCount--;
if (m_pServerCallbacks != nullptr) {
m_pServerCallbacks->onDisconnect(this);
}
startAdvertising();
break;
}
case ESP_GATTS_READ_EVT: {
break;
}
case ESP_GATTS_REG_EVT: {
m_gatts_if = gatts_if;
m_semaphoreRegisterAppEvt.give();
break;
}
case ESP_GATTS_WRITE_EVT: {
break;
}
default: {
break;
}
}
ESP_LOGD(LOG_TAG, "<< handleGATTServerEvent");
}
void BLEServer::registerApp() {
ESP_LOGD(LOG_TAG, ">> registerApp - %d", m_appId);
m_semaphoreRegisterAppEvt.take("registerApp");
::esp_ble_gatts_app_register(m_appId);
m_semaphoreRegisterAppEvt.wait("registerApp");
ESP_LOGD(LOG_TAG, "<< registerApp");
}
void BLEServer::setCallbacks(BLEServerCallbacks* pCallbacks) {
m_pServerCallbacks = pCallbacks;
}
void BLEServer::startAdvertising() {
ESP_LOGD(LOG_TAG, ">> startAdvertising");
m_bleAdvertising.start();
ESP_LOGD(LOG_TAG, "<< startAdvertising");
}
void BLEServerCallbacks::onConnect(BLEServer* pServer) {
ESP_LOGD("BLEServerCallbacks", ">> onConnect(): Default");
ESP_LOGD("BLEServerCallbacks", "Device: %s", BLEDevice::toString().c_str());
ESP_LOGD("BLEServerCallbacks", "<< onConnect()");
}
void BLEServerCallbacks::onDisconnect(BLEServer* pServer) {
ESP_LOGD("BLEServerCallbacks", ">> onDisconnect(): Default");
ESP_LOGD("BLEServerCallbacks", "Device: %s", BLEDevice::toString().c_str());
ESP_LOGD("BLEServerCallbacks", "<< onDisconnect()");
}
#endif