2023-06-14 18:12:33 +02:00

148 lines
4.7 KiB
C

#include "nimble/ble.h"
#include "esp_err.h"
#include "host/ble_att.h"
#include "host/ble_gap.h"
#include "host/ble_gatt.h"
#include "host/ble_hs_adv.h"
#include "host/ble_uuid.h"
#include "nimble/nimble_port.h"
#include "nimble/nimble_port_freertos.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"
#include "gatt_svcs.h"
#include "BLE_UUID.h"
struct ble_hs_adv_fields adv_fields = {
.tx_pwr_lvl_is_present = 1,
.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO,
.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP,
.name = (uint8_t*)&"Power Profiler"[0],
.name_len = 15,
.name_is_complete = 1,
};
struct ble_gap_adv_params adv_params = {
.conn_mode = BLE_GAP_CONN_MODE_UND,
.disc_mode = BLE_GAP_DISC_MODE_GEN,
};
static uint16_t cs_handle[EC_CHRS_NUM];
uint16_t ev_handle[EV_CHRS_NUM];
#define RAW_VOLTAGE_MEASURE_CHAR(ID) { \
.uuid = BLE_UUID16_DECLARE(VOLTAGE_CHAR), \
.access_cb = gatt_char_access_ev, \
.val_handle = &ev_handle[ID], \
.arg = ev_handle, \
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, \
.descriptors = (struct ble_gatt_dsc_def[]){ \
[0] = { \
.uuid = BLE_UUID16_DECLARE(CHAR_PRES_FORMAT), \
.att_flags = BLE_ATT_F_READ, \
.access_cb = gatt_char_access_ev, \
.arg = ev_handle, \
}, \
{ 0 }, \
}, \
}
#define CURRENT_MEASURE_CHAR(ID) { \
.uuid = BLE_UUID16_DECLARE(ELECTRIC_CURRENT_CHAR), \
.access_cb = gatt_char_access_cs, \
.val_handle = &cs_handle[ID], \
.arg = cs_handle, \
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, \
.descriptors = (struct ble_gatt_dsc_def[]){ \
[0] = { \
.uuid = BLE_UUID16_DECLARE(CHAR_PRES_FORMAT), \
.att_flags = BLE_ATT_F_READ, \
.access_cb = gatt_char_access_cs, \
}, \
{ 0 }, \
}, \
}
struct ble_gatt_svc_def gatt_svr_svcs[] = {
[CS_SVC_ID] = {
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(METROLOGY_SERVICE),
.characteristics = (struct ble_gatt_chr_def[]){
[ECx1_CHR_ID] = CURRENT_MEASURE_CHAR(ECx1_CHR_ID),
[ECx10_CHR_ID] = CURRENT_MEASURE_CHAR(ECx10_CHR_ID),
[ECx100_CHR_ID] = CURRENT_MEASURE_CHAR(ECx100_CHR_ID),
{ 0 },
}
},
[RVS_SVC_ID] = {
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(METROLOGY_SERVICE),
.characteristics = (struct ble_gatt_chr_def[]){
[EVx1_CHR_ID] = RAW_VOLTAGE_MEASURE_CHAR(EVx1_CHR_ID),
[EVx10_CHR_ID] = RAW_VOLTAGE_MEASURE_CHAR(EVx10_CHR_ID),
[EVx100_CHR_ID] = RAW_VOLTAGE_MEASURE_CHAR(EVx100_CHR_ID),
{ 0 },
}
},
[SETTINGS_SVC_ID] = {
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(CONFIGURATION_SERVICE),
.characteristics = (struct ble_gatt_chr_def[]){
[RFRSH_RATE_ID] = {
.uuid = BLE_UUID16_DECLARE(SAMPLING_RATE_CHAR),
.access_cb = gatt_char_access_sampling_rate,
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE,
.descriptors = (struct ble_gatt_dsc_def[]){
[0] = {
.uuid = BLE_UUID16_DECLARE(CHAR_PRES_FORMAT),
.att_flags = BLE_ATT_F_READ,
.access_cb = gatt_char_access_sampling_rate,
},
{ 0 },
}
},
{ 0 },
}
},
{ 0 },
};
static void ble_host_task(){
nimble_port_run();
nimble_port_freertos_deinit();
}
static void ble_advertise(void){
ESP_ERROR_CHECK(ble_gap_adv_set_fields(&adv_fields));
ESP_ERROR_CHECK(ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, NULL, NULL));
}
static void gatt_svr_init(void){
ble_svc_gap_init();
ble_svc_gatt_init();
ESP_ERROR_CHECK(ble_gatts_count_cfg(gatt_svr_svcs));
ESP_ERROR_CHECK(ble_gatts_add_svcs(gatt_svr_svcs));
}
static void ble_on_sync(void){
ble_advertise();
}
static void ble_on_reset(int p){
}
void initBLE(){
nimble_port_init();
ble_hs_cfg.sync_cb = ble_on_sync;
ble_hs_cfg.reset_cb = ble_on_reset;
gatt_svr_init();
ESP_ERROR_CHECK(ble_svc_gap_device_name_set("Power Profiler"));
nimble_port_freertos_init(ble_host_task);
}