OVMS3/OVMS.V3/components/esp32bluetooth/src/esp32bluetooth_gatts.cpp

466 lines
14 KiB
C++

/*
; Project: Open Vehicle Monitor System
; Date: 14th March 2017
;
; Changes:
; 1.0 Initial release
;
; (C) 2011 Michael Stegen / Stegen Electronics
; (C) 2011-2017 Mark Webb-Johnson
; (C) 2011 Sonny Chen @ EPRO/DX
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.
*/
#include <string.h>
#include "esp_system.h"
#include "esp32bluetooth_gap.h"
#include "esp32bluetooth_gatts.h"
#include "ovms_config.h"
#include "ovms_events.h"
#include "ovms_log.h"
static const char *TAG = "bt-gatts";
esp32bluetoothGATTS MyBluetoothGATTS __attribute__ ((init_priority (8012)));
////////////////////////////////////////////////////////////////////////
// esp32bluetoothCharacteristic
esp32bluetoothCharacteristic::esp32bluetoothCharacteristic(
esp32bluetoothApp* app,
esp_bt_uuid_t* charuuid,
esp_bt_uuid_t* descruuid = NULL)
{
m_app = app;
m_notifying = false;
m_indicating = false;
memcpy(&m_char_uuid,charuuid,sizeof(esp_bt_uuid_t));
m_char_handle = 0;
m_char_perm = 0;
m_char_property = 0;
if (descruuid != NULL)
{
memcpy(&m_descr_uuid,&descruuid,sizeof(esp_bt_uuid_t));
}
else
{
memset(&m_descr_uuid,0,sizeof(esp_bt_uuid_t));
}
m_descr_handle = 0;
}
esp32bluetoothCharacteristic::~esp32bluetoothCharacteristic()
{
}
////////////////////////////////////////////////////////////////////////
// esp32bluetoothApp
esp32bluetoothApp::esp32bluetoothApp(const char* name)
{
m_name = name;
m_gatts_if = ESP_GATT_IF_NONE;
m_app_id = 0;
m_conn_id = 0;
m_service_handle = 0;
memset(&m_service_id, 0, sizeof(m_service_id));
m_mtu = 0;
}
esp32bluetoothApp::~esp32bluetoothApp()
{
}
void esp32bluetoothApp::EventRegistered(esp_ble_gatts_cb_param_t::gatts_reg_evt_param *reg)
{
}
void esp32bluetoothApp::EventRead(esp_ble_gatts_cb_param_t::gatts_read_evt_param *read)
{
}
void esp32bluetoothApp::EventWrite(esp_ble_gatts_cb_param_t::gatts_write_evt_param *write)
{
}
void esp32bluetoothApp::EventExecWrite(esp_ble_gatts_cb_param_t::gatts_exec_write_evt_param *execwrite)
{
}
void esp32bluetoothApp::EventMTU(esp_ble_gatts_cb_param_t::gatts_mtu_evt_param *mtu)
{
}
void esp32bluetoothApp::EventConf(esp_ble_gatts_cb_param_t::gatts_conf_evt_param *conf)
{
}
void esp32bluetoothApp::EventUnregistered()
{
}
void esp32bluetoothApp::EventDelete(esp_ble_gatts_cb_param_t::gatts_delete_evt_param *del)
{
}
void esp32bluetoothApp::EventStart(esp_ble_gatts_cb_param_t::gatts_start_evt_param *start)
{
}
void esp32bluetoothApp::EventStop(esp_ble_gatts_cb_param_t::gatts_stop_evt_param *stop)
{
}
void esp32bluetoothApp::EventConnect(esp_ble_gatts_cb_param_t::gatts_connect_evt_param *connect)
{
}
void esp32bluetoothApp::EventDisconnect(esp_ble_gatts_cb_param_t::gatts_disconnect_evt_param *disconnect)
{
}
void esp32bluetoothApp::EventOpen(esp_ble_gatts_cb_param_t::gatts_open_evt_param *open)
{
}
void esp32bluetoothApp::EventCancelOpen(esp_ble_gatts_cb_param_t::gatts_cancel_open_evt_param *cancelopen)
{
}
void esp32bluetoothApp::EventClose(esp_ble_gatts_cb_param_t::gatts_close_evt_param *close)
{
}
void esp32bluetoothApp::EventListen()
{
}
void esp32bluetoothApp::EventCongest(esp_ble_gatts_cb_param_t::gatts_congest_evt_param *congest)
{
}
void esp32bluetoothApp::EventCreate(esp_ble_gatts_cb_param_t::gatts_add_attr_tab_evt_param *attrtab)
{
}
void esp32bluetoothApp::EventAddChar(esp_ble_gatts_cb_param_t::gatts_add_char_evt_param *addchar)
{
}
void esp32bluetoothApp::EventAddCharDescr(esp_ble_gatts_cb_param_t::gatts_add_char_descr_evt_param *adddescr)
{
}
////////////////////////////////////////////////////////////////////////
// esp32bluetoothGATTS
void ble_gatts_event_handler(esp_gatts_cb_event_t event,
esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t *param)
{
MyBluetoothGATTS.EventHandler(event, gatts_if, param);
}
esp32bluetoothGATTS::esp32bluetoothGATTS()
{
ESP_LOGI(TAG, "Initialising Bluetooth GATTS (8012)");
}
esp32bluetoothGATTS::~esp32bluetoothGATTS()
{
}
void esp32bluetoothGATTS::RegisterForEvents()
{
esp_err_t ret = esp_ble_gatts_register_callback(ble_gatts_event_handler);
if (ret)
{
ESP_LOGE(TAG, "gatts register error, error code = %x", ret);
return;
}
}
void esp32bluetoothGATTS::EventHandler(esp_gatts_cb_event_t event,
esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t *param)
{
for (esp32bluetoothApp* app : m_apps)
{
if (event == ESP_GATTS_REG_EVT)
{
// Store the gatts_if for the registered app
if (param->reg.app_id == app->m_app_id)
{
if (param->reg.status == ESP_GATT_OK)
{
ESP_LOGI(TAG,"ESP_GATTS_REG_EVT register app %s (0x%04x) ok with interface ID %d",
app->m_name, param->reg.app_id, gatts_if);
app->m_gatts_if = gatts_if;
}
else
{
ESP_LOGE(TAG, "ESP_GATTS_REG_EVT register app %s (0x%04x) failed with status %d",
app->m_name,
param->reg.app_id,
param->reg.status);
return;
}
}
}
if ((gatts_if == ESP_GATT_IF_NONE) ||
(gatts_if == app->m_gatts_if))
{
switch (event)
{
case ESP_GATTS_REG_EVT:
{
ESP_LOGI(TAG, "ESP_GATTS_REG_EVT/%s",app->m_name);
std::string devname = MyConfig.GetParamValue("vehicle", "id");
if (devname.empty())
{
devname = std::string("OVMS");
}
else
{
devname.insert(0,"OVMS ");
}
esp_ble_gap_set_device_name(devname.c_str());
esp_ble_gap_config_local_privacy(true);
app->EventRegistered(&param->reg);
break;
}
case ESP_GATTS_READ_EVT:
ESP_LOGI(TAG, "ESP_GATTS_READ_EVT/%s conn_id %d, trans_id %d, handle %d",
app->m_name,
param->read.conn_id, param->read.trans_id, param->read.handle);
app->EventRead(&param->read);
break;
case ESP_GATTS_WRITE_EVT:
ESP_LOGI(TAG, "ESP_GATTS_WRITE_EVT/%s conn_id %d, trans_id %d, handle %d, write %d bytes, value:",
app->m_name,
param->write.conn_id, param->write.trans_id, param->write.handle,
param->write.len);
esp_log_buffer_hex(TAG, param->write.value, param->write.len);
app->EventWrite(&param->write);
break;
case ESP_GATTS_EXEC_WRITE_EVT:
ESP_LOGI(TAG, "ESP_GATTS_EXEC_WRITE_EVT/%s conn_id %d, trans_id %d",
app->m_name,
param->exec_write.conn_id, param->exec_write.trans_id);
app->EventExecWrite(&param->exec_write);
break;
case ESP_GATTS_MTU_EVT:
ESP_LOGI(TAG, "ESP_GATTS_MTU_EVT/%s conn_id %d, mtu %d",
app->m_name,
param->mtu.conn_id,
param->mtu.mtu);
app->m_mtu = param->mtu.mtu;
app->EventMTU(&param->mtu);
break;
case ESP_GATTS_CONF_EVT:
ESP_LOGI(TAG, "ESP_GATTS_CONF_EVT/%s",app->m_name);
app->EventConf(&param->conf);
break;
case ESP_GATTS_UNREG_EVT:
ESP_LOGI(TAG, "ESP_GATTS_UNREG_EVT/%s",app->m_name);
app->EventUnregistered();
break;
case ESP_GATTS_DELETE_EVT:
ESP_LOGI(TAG, "ESP_GATTS_DELETE_EVT/%s",app->m_name);
app->EventDelete(&param->del);
break;
case ESP_GATTS_START_EVT:
ESP_LOGI(TAG, "ESP_GATTS_START_EVT/%s",app->m_name);
app->EventStart(&param->start);
break;
case ESP_GATTS_STOP_EVT:
ESP_LOGI(TAG, "ESP_GATTS_STOP_EVT/%s",app->m_name);
app->EventStop(&param->stop);
break;
case ESP_GATTS_CONNECT_EVT:
{
ESP_LOGI(TAG, "ESP_GATTS_CONNECT_EVT/%s conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x",
app->m_name,
param->connect.conn_id,
param->connect.remote_bda[0],
param->connect.remote_bda[1],
param->connect.remote_bda[2],
param->connect.remote_bda[3],
param->connect.remote_bda[4],
param->connect.remote_bda[5]);
app->EventConnect(&param->connect);
char signal[32];
sprintf(signal,"bt.connect.%02x:%02x:%02x:%02x:%02x:%02x",
param->connect.remote_bda[0],
param->connect.remote_bda[1],
param->connect.remote_bda[2],
param->connect.remote_bda[3],
param->connect.remote_bda[4],
param->connect.remote_bda[5]);
MyEvents.SignalEvent(signal, NULL);
app->m_conn_id = param->connect.conn_id;
if (app->m_app_slot == 0)
{
esp_ble_conn_update_params_t conn_params;
memset(&conn_params,0,sizeof(conn_params));
memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
/* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */
conn_params.latency = 0;
conn_params.max_int = 0x30; // max_int = 0x30*1.25ms = 40ms
conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms
conn_params.timeout = 400; // timeout = 400*10ms = 4000ms
//start sent the update connection parameters to the peer device.
esp_ble_gap_update_conn_params(&conn_params);
esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
}
break;
}
case ESP_GATTS_DISCONNECT_EVT:
{
ESP_LOGI(TAG, "ESP_GATTS_DISCONNECT_EVT/%s conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x",
app->m_name,
param->disconnect.conn_id,
param->disconnect.remote_bda[0],
param->disconnect.remote_bda[1],
param->disconnect.remote_bda[2],
param->disconnect.remote_bda[3],
param->disconnect.remote_bda[4],
param->disconnect.remote_bda[5]);
app->EventDisconnect(&param->disconnect);
char signal[32];
sprintf(signal,"bt.disconnect.%02x:%02x:%02x:%02x:%02x:%02x",
param->disconnect.remote_bda[0],
param->disconnect.remote_bda[1],
param->disconnect.remote_bda[2],
param->disconnect.remote_bda[3],
param->disconnect.remote_bda[4],
param->disconnect.remote_bda[5]);
MyEvents.SignalEvent(signal, NULL);
if (app->m_app_slot == 0)
{
MyBluetoothGAP.StartAdvertising();
}
break;
}
case ESP_GATTS_OPEN_EVT:
ESP_LOGI(TAG, "ESP_GATTS_OPEN_EVT/%s",app->m_name);
app->EventOpen(&param->open);
break;
case ESP_GATTS_CANCEL_OPEN_EVT:
ESP_LOGI(TAG, "ESP_GATTS_CANCEL_OPEN_EVT/%s",app->m_name);
app->EventCancelOpen(&param->cancel_open);
break;
case ESP_GATTS_CLOSE_EVT:
ESP_LOGI(TAG, "ESP_GATTS_CLOSE_EVT/%s",app->m_name);
app->EventClose(&param->close);
break;
case ESP_GATTS_LISTEN_EVT:
ESP_LOGI(TAG, "ESP_GATTS_LISTEN_EVT/%s",app->m_name);
app->EventListen();
break;
case ESP_GATTS_CONGEST_EVT:
ESP_LOGI(TAG, "ESP_GATTS_CONGEST_EVT/%s",app->m_name);
app->EventCongest(&param->congest);
break;
case ESP_GATTS_CREATE_EVT:
ESP_LOGI(TAG, "ESP_GATTS_CREATE_EVT/%s status %d, service_handle %d",
app->m_name,
param->create.status, param->create.service_handle);
app->m_service_handle = param->create.service_handle;
app->EventCreate(&param->add_attr_tab);
break;
case ESP_GATTS_ADD_CHAR_EVT:
ESP_LOGI(TAG, "ESP_GATTS_ADD_CHAR_EVT/%s status %d, attr_handle %d, service_handle %d",
app->m_name,
param->add_char.status,
param->add_char.attr_handle,
param->add_char.service_handle);
app->EventAddChar(&param->add_char);
break;
case ESP_GATTS_ADD_CHAR_DESCR_EVT:
ESP_LOGI(TAG, "ESP_GATTS_ADD_CHAR_DESCR_EVT/%s status %d, attr_handle %d, service_handle %d",
app->m_name,
param->add_char.status, param->add_char.attr_handle,
param->add_char.service_handle);
app->EventAddCharDescr(&param->add_char_descr);
break;
default:
ESP_LOGD(TAG, "GATTS PROFILE event = %d\n",event);
break;
}
}
}
}
void esp32bluetoothGATTS::RegisterAllApps()
{
for (esp32bluetoothApp* app : m_apps)
{
esp_err_t ret = esp_ble_gatts_app_register(app->m_app_id);
if (ret)
{
ESP_LOGE(TAG, "App %s register error, error code = %x",
app->m_name, ret);
}
else
{
ESP_LOGI(TAG,"App %s registered successfully",app->m_name);
}
}
}
void esp32bluetoothGATTS::UnregisterAllApps()
{
for (esp32bluetoothApp* app : m_apps)
{
esp_err_t ret = esp_ble_gatts_app_unregister(app->m_gatts_if);
if (ret)
{
ESP_LOGE(TAG, "App %s unregister error, error code = %x",
app->m_name, ret);
}
else
{
ESP_LOGI(TAG,"App %s unregistered successfully",app->m_name);
}
}
}
void esp32bluetoothGATTS::RegisterApp(esp32bluetoothApp* app)
{
m_apps.push_back(app);
app->m_app_slot = m_apps.size()-1;
}