bleh/simple_gatt_value_server.c

130 lines
4.1 KiB
C

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#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);
}
}