#include #include #include #include "esp_log.h" #include "host/ble_att.h" #include "host/ble_gatt.h" #include "host/ble_uuid.h" #include "os/os_mbuf.h" #include "BLE_UUID.h" #include "BLEh.h" #include "simple_gatt_value_server.h" #define TAG "GATT value server" struct serve_conf { uint8_t* value; size_t value_size; struct char_pres_format* format; uint16_t svc_ind; uint16_t chr_ind; }; static struct serve_conf** serve_confs; static uint16_t svcs_num = 0; struct ble_gatt_chr_def** chars; struct ble_gatt_dsc_def** descrs; static uint16_t serve_num = 0; int read_handler(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg){ int rc = 0; struct serve_conf* conf = arg; switch(ctxt->op){ case BLE_GATT_ACCESS_OP_READ_CHR: ; rc = os_mbuf_append(ctxt->om, conf->value, conf->value_size); break; case BLE_GATT_ACCESS_OP_READ_DSC: ; rc = os_mbuf_append(ctxt->om, conf->format, CHAR_PRESENTATION_FORMAT_SIZE); break; } return rc ? BLE_ATT_ERR_INSUFFICIENT_RES : 0; } ble_uuid_t* char_pres_format = BLE_UUID16_DECLARE(CHAR_PRES_FORMAT); gatt_value_server_handle_t simple_gatt_value_server(void* values, size_t value_size, int values_num, struct char_pres_format* format[], struct ble_gatt_svc_def* svc, uint16_t svc_ind, ble_uuid_t* char_uuid[]){ struct ble_gatt_chr_def* chrs = malloc((values_num + 1) * sizeof(struct ble_gatt_chr_def)); chars = realloc(chars, (svcs_num + 1) * sizeof(struct ble_gatt_chr_def*)); chars[svcs_num] = chrs; for(int i = 0; i < values_num; i++){ serve_confs = realloc(serve_confs, (serve_num + 1) * sizeof(struct serve_conf*)); serve_confs[serve_num] = malloc(sizeof(struct serve_conf)); ESP_LOGI(TAG, "Creating conf %d %d %p", svcs_num, serve_num, serve_confs[serve_num]); serve_confs[serve_num]->value = values+(i*value_size); serve_confs[serve_num]->value_size = value_size; serve_confs[serve_num]->format = format[i]; serve_confs[serve_num]->svc_ind = svc_ind; serve_confs[serve_num]->chr_ind = i; descrs = realloc(descrs, (serve_num + 1) * sizeof(struct ble_gatt_dsc_def*)); descrs[serve_num] = malloc(2 * sizeof(struct ble_gatt_dsc_def)); struct ble_gatt_dsc_def dsc = { .uuid = char_pres_format, .access_cb = read_handler, .arg = serve_confs[serve_num], .att_flags = BLE_ATT_F_READ, .min_key_size = 0, }; memcpy(&descrs[serve_num][0], &dsc, sizeof(struct ble_gatt_dsc_def)); memset(&descrs[serve_num][1], 0, sizeof(struct ble_gatt_dsc_def)); struct ble_gatt_chr_def chr = { .uuid = char_uuid[i], .access_cb = read_handler, .arg = serve_confs[serve_num], .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, .descriptors = descrs[serve_num], }; memcpy(&chrs[i], &chr, sizeof(chr)); serve_num++; } memset(&chrs[values_num], 0, sizeof(struct ble_gatt_chr_def)); svc->characteristics = chrs; svcs_num++; return serve_num - values_num; } gatt_value_server_handle_t simple_gatt_identical_values_server(void* values, size_t values_size, int values_num, struct char_pres_format* format, struct ble_gatt_svc_def* svc, uint16_t svc_ind, ble_uuid_t* uuid){ struct char_pres_format* formats[values_num]; for(int i = 0; i < values_num; i++) formats[i] = format; ble_uuid_t* uuids[values_num]; for(int i = 0; i < values_num; i++) uuids[i] = uuid; return simple_gatt_value_server(values, values_size, values_num, formats, svc, svc_ind, uuids); } void simple_gatt_value_server_deinit(){ for(int i = 0; i < serve_num; i++) free(serve_confs[i]); free(serve_confs); for(int i = 0; i < svcs_num; i++) free(chars[i]); free(chars); for(int i = 0; i < serve_num; i++) free(descrs[i]); free(descrs); } void simple_gatt_value_server_notify(gatt_value_server_handle_t handle, int values_num){ for(int i = 0; i < values_num; i++){ struct serve_conf* conf = serve_confs[handle + i]; // ESP_LOGI(TAG, "notify %d %d", conf->svc_ind, conf->chr_ind); notify(conf->svc_ind, conf->chr_ind, conf->value, conf->value_size); } }