From 6a651ce129cf9d0ce562aa676cbdd9789ff6011e Mon Sep 17 00:00:00 2001 From: leo Date: Sat, 24 Jun 2023 19:30:24 +0200 Subject: [PATCH] basic value server --- BLEh.c | 12 +--- CMakeLists.txt | 2 +- include/BLEh.h | 13 ++++ include/simple_gatt_value_server.h | 10 +++ simple_gatt_value_server.c | 112 +++++++++++++++++++++++++++++ 5 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 include/simple_gatt_value_server.h create mode 100644 simple_gatt_value_server.c diff --git a/BLEh.c b/BLEh.c index f45db89..a50c03e 100644 --- a/BLEh.c +++ b/BLEh.c @@ -106,16 +106,14 @@ void set_gatt_services(struct ble_gatt_svc_def* svcs, uint16_t num){ // map our attributes handle to the services // first get the sizes of each services to know the size to allocate - struct ble_gatt_svc_def svc = svcs[0]; - for(int svc_ind = 0; svc_ind < svcs_num; svc_ind++){ - struct ble_gatt_chr_def chr = svc.characteristics[0]; + struct ble_gatt_chr_def chr = svcs[svc_ind].characteristics[0]; svcs_sizes = realloc(svcs_sizes, (svc_ind + 1) * sizeof(uint16_t)); - + int chr_ind; for(chr_ind = 0; chr.uuid != NULL; chr_ind++){ - chr = svc.characteristics[chr_ind]; + chr = svcs[svc_ind].characteristics[chr_ind]; } svcs_sizes[svc_ind] = chr_ind - 1; @@ -127,8 +125,6 @@ void set_gatt_services(struct ble_gatt_svc_def* svcs, uint16_t num){ notify_state = malloc(svcs_num * sizeof(uint8_t*)); // finally we populate the handles - svc = svcs[0]; - int svc_ind; for(svc_ind = 0; svc_ind < svcs_num; svc_ind++){ att_handle[svc_ind] = malloc(svcs_sizes[svc_ind] * sizeof(uint16_t)); @@ -138,8 +134,6 @@ void set_gatt_services(struct ble_gatt_svc_def* svcs, uint16_t num){ struct ble_gatt_chr_def chr = svcs[svc_ind].characteristics[chr_ind]; chr.val_handle = &att_handle[svc_ind][chr_ind]; } - - svc = svcs[svc_ind]; } } diff --git a/CMakeLists.txt b/CMakeLists.txt index a259982..1700831 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( - SRCS "BLEh.c" + SRCS "BLEh.c" "simple_gatt_value_server.c" INCLUDE_DIRS "include" REQUIRES bt ) diff --git a/include/BLEh.h b/include/BLEh.h index 23c3f46..5065bef 100644 --- a/include/BLEh.h +++ b/include/BLEh.h @@ -1,7 +1,20 @@ +#pragma once + #include #include "host/ble_gatt.h" +#define CHAR_PRESENTATION_FORMAT_SIZE 7 + +struct char_pres_format { + uint8_t format; + uint8_t exponent; + uint16_t unit; + uint8_t namespc; + uint8_t descrH; + uint8_t descrL; +}; + void initBLE(char* name); void ble_advertise(void); void set_gatt_services(struct ble_gatt_svc_def* svcs, uint16_t num); diff --git a/include/simple_gatt_value_server.h b/include/simple_gatt_value_server.h new file mode 100644 index 0000000..3cd46b1 --- /dev/null +++ b/include/simple_gatt_value_server.h @@ -0,0 +1,10 @@ +#pragma once + +#include "host/ble_gatt.h" + +#include "BLEh.h" +#include "host/ble_uuid.h" + +typedef void* gatt_value_server_handle_t; + +gatt_value_server_handle_t simple_gatt_value_server(void* values, int values_num, size_t values_size, struct char_pres_format format, struct ble_gatt_svc_def* svc, ble_uuid_t* uuid); \ No newline at end of file diff --git a/simple_gatt_value_server.c b/simple_gatt_value_server.c new file mode 100644 index 0000000..261d6b9 --- /dev/null +++ b/simple_gatt_value_server.c @@ -0,0 +1,112 @@ +#include +#include +#include + +#include "esp_log.h" + +#include "host/ble_gatt.h" +#include "host/ble_uuid.h" +#include "os/os_mbuf.h" + +#include "BLE_UUID.h" +#include "BLEh.h" + +#define TAG "GATT value server" + +struct serve_conf { + void* value; + size_t value_size; + struct char_pres_format* format; +}; + +static struct serve_conf** serve_confs; +typedef struct serve_conf* gatt_value_server_handle_t; + +static uint16_t svcs_num; +struct char_pres_format* formats; +struct ble_gatt_chr_def** chars; +struct ble_gatt_dsc_def** descrs; + +static uint16_t serve_num; + +static 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, ble_uuid_t* char_uuid){ + struct ble_gatt_chr_def* chrs = malloc((values_num + 1) * sizeof(struct ble_gatt_chr_def)); + + formats = realloc(formats, (svcs_num + 1) * sizeof(struct char_pres_format)); + chars = realloc(chars, (svcs_num + 1) * sizeof(struct ble_gatt_chr_def*)); + chars[svcs_num] = chrs; + + memcpy(&formats[svcs_num], &format, sizeof(format)); + + 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)); + serve_confs[serve_num]->value = values[i]; + serve_confs[serve_num]->value_size = value_size; + serve_confs[serve_num]->format = &formats[svcs_num]; + + 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[] = { + [0] = { + .uuid = char_pres_format, + .access_cb = read_handler, + .arg = serve_confs[serve_num], + .att_flags = BLE_GATT_CHR_F_READ, + .min_key_size = 0, + }, + { 0 }, + }; + memcpy(descrs[serve_num], dsc, 2 * sizeof(struct ble_gatt_dsc_def)); + + struct ble_gatt_chr_def chr = { + .uuid = char_uuid, + .access_cb = read_handler, + .arg = serve_confs[serve_num], + .flags = BLE_GATT_CHR_F_READ, + .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_confs[serve_num - values_num]; +} + +void simple_gatt_value_server_deinit(){ + for(int i = 0; i < serve_num; i++) free(serve_confs[i]); + free(serve_confs); + free(formats); + 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); +} \ No newline at end of file