272 lines
7.9 KiB
C
272 lines
7.9 KiB
C
#include <stdint.h>
|
|
|
|
#include "ble.h"
|
|
#include "host/ble_att.h"
|
|
#include "host/ble_gatt.h"
|
|
#include "host/ble_hs_mbuf.h"
|
|
#include "nimble/hci_common.h"
|
|
#include "os/os_mbuf.h"
|
|
#include "esp_log.h"
|
|
|
|
#include "gatt_svcs.h"
|
|
#include "BLE_UUID.h"
|
|
#include "configuration.h"
|
|
#include "power_profiler.h"
|
|
|
|
static struct char_pres_format current_char_pres_format = {
|
|
.format = FORMAT_UINT32,
|
|
.exponent = -6,
|
|
.unit = AMPERE_UNIT_UUID,
|
|
.namespc = 1,
|
|
.descrH = NSP_DESC_MAIN & 0xff,
|
|
.descrL = (NSP_DESC_MAIN>>8) & 0xff,
|
|
};
|
|
|
|
static struct char_pres_format raw_voltage_char_pres_format = {
|
|
.format = FORMAT_UINT32,
|
|
.exponent = -3,
|
|
.unit = VOLTS_UNIT_UUID,
|
|
.namespc = 1,
|
|
.descrH = NSP_DESC_MAIN & 0xff,
|
|
.descrL = (NSP_DESC_MAIN>>8) & 0xff,
|
|
};
|
|
|
|
static struct char_pres_format refrsh_rate_char_pres_format = {
|
|
.format = FORMAT_UINT32,
|
|
.exponent = -3,
|
|
.unit = SECONDS_UNIT_UUID,
|
|
.namespc = 1,
|
|
.descrH = NSP_DESC_MAIN & 0xff,
|
|
.descrL = (NSP_DESC_MAIN>>8) & 0xff,
|
|
};
|
|
|
|
static struct char_pres_format zero_cali_nsamp_char_pres_format = {
|
|
.format = FORMAT_UINT32,
|
|
.exponent = 0,
|
|
.unit = UNITLESS_UNIT_UUID,
|
|
.namespc = 1,
|
|
.descrH = NSP_DESC_MAIN & 0xff,
|
|
.descrL = (NSP_DESC_MAIN>>8) & 0xff,
|
|
};
|
|
|
|
static struct char_pres_format auto_range_char_pres_format = {
|
|
.format = FORMAT_BOOL,
|
|
.exponent = 0,
|
|
.unit = UNITLESS_UNIT_UUID,
|
|
.namespc = 1,
|
|
.descrH = NSP_DESC_MAIN & 0xff,
|
|
.descrL = (NSP_DESC_MAIN>>8) & 0xff,
|
|
};
|
|
|
|
static struct char_pres_format current_range_char_pres_format = {
|
|
.format = FORMAT_INT32,
|
|
.exponent = 0,
|
|
.unit = UNITLESS_UNIT_UUID,
|
|
.namespc = 1,
|
|
.descrH = NSP_DESC_MAIN & 0xff,
|
|
.descrL = (NSP_DESC_MAIN>>8) & 0xff,
|
|
};
|
|
|
|
static int gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len,
|
|
void *dst, uint16_t *len)
|
|
{
|
|
uint16_t om_len;
|
|
int rc;
|
|
|
|
om_len = OS_MBUF_PKTLEN(om);
|
|
if (om_len < min_len || om_len > max_len) {
|
|
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
|
}
|
|
|
|
rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
|
|
if (rc != 0) {
|
|
return BLE_ATT_ERR_UNLIKELY;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int gatt_char_access_cs(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg){
|
|
int rc = 0;
|
|
|
|
switch(ctxt->op){
|
|
case BLE_GATT_ACCESS_OP_READ_CHR:
|
|
;
|
|
struct ble_context *c_ctxt = arg;
|
|
uint16_t id = c_ctxt->handle;
|
|
|
|
uint32_t data = c_ctxt->meas->amperes[id];
|
|
rc = os_mbuf_append(ctxt->om, &data, sizeof(data));
|
|
break;
|
|
case BLE_GATT_ACCESS_OP_READ_DSC:
|
|
;
|
|
if(arg == NULL) // characteristic presentation format
|
|
rc = os_mbuf_append(ctxt->om, ¤t_char_pres_format, CHAR_PRESENTATION_FORMAT_SIZE);
|
|
else{
|
|
struct ble_context *c_ctxt = arg;
|
|
uint16_t handle = c_ctxt->handle;
|
|
|
|
unsigned int gain = c_ctxt->meas_ctxt->inputs[handle].gain;
|
|
rc = os_mbuf_append(ctxt->om, &gain, sizeof(gain));
|
|
}
|
|
break;
|
|
}
|
|
|
|
return rc ? BLE_ATT_ERR_INSUFFICIENT_RES : 0;
|
|
}
|
|
|
|
int gatt_char_access_ev(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg){
|
|
int rc = 0;
|
|
|
|
switch(ctxt->op){
|
|
case BLE_GATT_ACCESS_OP_READ_CHR:
|
|
;
|
|
struct ble_context *c_ctxt = arg;
|
|
uint16_t id = c_ctxt->handle;
|
|
|
|
uint32_t data = c_ctxt->meas->raw_volt[id];
|
|
rc = os_mbuf_append(ctxt->om, &data, sizeof(data));
|
|
break;
|
|
case BLE_GATT_ACCESS_OP_READ_DSC:
|
|
if(arg == NULL) // characteristic presentation format
|
|
rc = os_mbuf_append(ctxt->om, &raw_voltage_char_pres_format, CHAR_PRESENTATION_FORMAT_SIZE);
|
|
else{
|
|
struct ble_context *c_ctxt = arg;
|
|
uint16_t handle = c_ctxt->handle;
|
|
|
|
unsigned int gain = c_ctxt->meas_ctxt->inputs[handle].gain;
|
|
rc = os_mbuf_append(ctxt->om, &gain, sizeof(gain));
|
|
}
|
|
break;
|
|
}
|
|
|
|
return rc ? BLE_ATT_ERR_INSUFFICIENT_RES : 0;
|
|
}
|
|
|
|
int gatt_char_access_sampling_rate(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg){
|
|
int rc = 0;
|
|
|
|
struct ble_context *c_ctxt = arg;
|
|
switch(ctxt->op){
|
|
case BLE_GATT_ACCESS_OP_READ_CHR:
|
|
;
|
|
rc = os_mbuf_append(ctxt->om, &c_ctxt->conf->refresh_delay, sizeof(c_ctxt->conf->refresh_delay));
|
|
break;
|
|
case BLE_GATT_ACCESS_OP_WRITE_CHR:
|
|
;
|
|
uint32_t data;
|
|
rc = gatt_svr_chr_write(ctxt->om, sizeof(data), sizeof(data), &data, NULL);
|
|
ESP_LOGI("BLE", "Refresh rate : %lu", data);
|
|
c_ctxt->conf->refresh_delay = data;
|
|
save_configuration_to_nvs(c_ctxt->conf);
|
|
break;
|
|
case BLE_GATT_ACCESS_OP_READ_DSC:
|
|
rc = os_mbuf_append(ctxt->om, &refrsh_rate_char_pres_format, CHAR_PRESENTATION_FORMAT_SIZE);
|
|
break;
|
|
}
|
|
|
|
return rc ? BLE_ATT_ERR_INSUFFICIENT_RES : 0;
|
|
}
|
|
|
|
int gatt_char_access_zeros_cali(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg){
|
|
int rc = 0;
|
|
|
|
|
|
struct ble_context* c_ctxt = arg;
|
|
switch(ctxt->op){
|
|
case BLE_GATT_ACCESS_OP_WRITE_CHR:
|
|
{
|
|
switch (c_ctxt->handle){
|
|
case ZEROS_CALI_ID:
|
|
start_zero_cali(c_ctxt->meas_ctxt, c_ctxt->conf->zero_cali_nsamp, c_ctxt->conf->offsets);
|
|
save_configuration_to_nvs(c_ctxt->conf);
|
|
break;
|
|
case ZEROS_CALI_RESET:
|
|
for(int i = 0; i < INPUTS_NUM; i++)
|
|
c_ctxt->conf->offsets[i] = 0;
|
|
save_configuration_to_nvs(c_ctxt->conf);
|
|
ESP_LOGI(TAG, "offset zeroed %lu %lu %lu", c_ctxt->conf->offsets[0], c_ctxt->conf->offsets[1], c_ctxt->conf->offsets[2]);
|
|
break;
|
|
case ZEROS_CALI_NSAMP_ID:
|
|
;
|
|
uint32_t data;
|
|
rc = gatt_svr_chr_write(ctxt->om, sizeof(data), sizeof(data), &data, NULL);
|
|
c_ctxt->conf->zero_cali_nsamp = data;
|
|
save_configuration_to_nvs(c_ctxt->conf);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case BLE_GATT_ACCESS_OP_READ_CHR:
|
|
;
|
|
rc = os_mbuf_append(ctxt->om, &c_ctxt->conf->zero_cali_nsamp, sizeof(c_ctxt->conf->zero_cali_nsamp));
|
|
break;
|
|
case BLE_GATT_ACCESS_OP_READ_DSC:
|
|
;
|
|
rc = os_mbuf_append(ctxt->om, &zero_cali_nsamp_char_pres_format, CHAR_PRESENTATION_FORMAT_SIZE);
|
|
break;
|
|
}
|
|
|
|
return rc ? BLE_ATT_ERR_INSUFFICIENT_RES : 0;
|
|
}
|
|
|
|
int gatt_char_access_range(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg){
|
|
int rc = 0;
|
|
|
|
struct ble_context* c_ctxt = arg;
|
|
switch(ctxt->op){
|
|
case BLE_GATT_ACCESS_OP_WRITE_CHR:
|
|
{
|
|
switch (c_ctxt->handle){
|
|
case AUTO_RANGE_ID:
|
|
;
|
|
uint8_t state;
|
|
rc = gatt_svr_chr_write(ctxt->om, sizeof(state), sizeof(state), &state, NULL);
|
|
c_ctxt->conf->auto_range = state;
|
|
save_configuration_to_nvs(c_ctxt->conf);
|
|
break;
|
|
case CURRENT_RANGE_ID:
|
|
;
|
|
int data;
|
|
rc = gatt_svr_chr_write(ctxt->om, sizeof(data), sizeof(data), &data, NULL);
|
|
ESP_LOGI(TAG, "new range %d", data);
|
|
c_ctxt->conf->range = data;
|
|
activate_range(c_ctxt->conf->ranges, data, c_ctxt->conf->ranges_num - 1);
|
|
save_configuration_to_nvs(c_ctxt->conf);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case BLE_GATT_ACCESS_OP_READ_CHR:
|
|
{
|
|
switch (c_ctxt->handle){
|
|
case AUTO_RANGE_ID:
|
|
;
|
|
rc = os_mbuf_append(ctxt->om, &c_ctxt->conf->auto_range, sizeof(c_ctxt->conf->auto_range));
|
|
break;
|
|
case CURRENT_RANGE_ID:
|
|
rc = os_mbuf_append(ctxt->om, &c_ctxt->conf->range, sizeof(c_ctxt->conf->range));
|
|
;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case BLE_GATT_ACCESS_OP_READ_DSC:
|
|
{
|
|
switch (c_ctxt->handle){
|
|
case AUTO_RANGE_ID:
|
|
;
|
|
rc = os_mbuf_append(ctxt->om, &auto_range_char_pres_format, CHAR_PRESENTATION_FORMAT_SIZE);
|
|
break;
|
|
case CURRENT_RANGE_ID:
|
|
;
|
|
rc = os_mbuf_append(ctxt->om, ¤t_range_char_pres_format, CHAR_PRESENTATION_FORMAT_SIZE);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return rc ? BLE_ATT_ERR_INSUFFICIENT_RES : 0;
|
|
}
|