From 544c26fdfda6d679f07192b2358de1cefc998859 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 26 Jun 2023 15:12:51 +0200 Subject: [PATCH] char read callback + auto dsc serve --- BLEh.c | 55 ++++++++++++++++++++++++++++++++++++++ include/BLE_UUID.h | 1 + include/BLEh.h | 12 ++++++++- simple_gatt_value_server.c | 2 +- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/BLEh.c b/BLEh.c index 00e953b..1036e36 100644 --- a/BLEh.c +++ b/BLEh.c @@ -27,6 +27,9 @@ static uint16_t* svcs_sizes; static uint16_t** att_handle; static uint8_t** notify_state; +static charReadCallback on_char_read_callback; +static charWriteCallback on_char_write_callback; + static struct ble_hs_adv_fields adv_fields = { .tx_pwr_lvl_is_present = 1, .tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO, @@ -68,6 +71,18 @@ static uint16_t get_att_handle(uint16_t svc_ind, uint16_t chr_ind){ return att_handle[svc_ind][chr_ind]; } +static void get_indices_from_att_handle(uint16_t handle, uint16_t* svc_ind, uint16_t* chr_ind){ + for(int i = 0; i < svcs_num; i++){ + for(int j = 0; j < svcs_sizes[i]; j++){ + if(att_handle[i][j] == handle){ + *svc_ind = i; + *chr_ind = j; + return; + } + } + } +} + static int ble_gap_event(struct ble_gap_event *event, void* arg){ switch(event->type){ case BLE_GAP_EVENT_CONNECT: @@ -113,6 +128,37 @@ void ble_advertise(void){ ESP_ERROR_CHECK(ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, ble_gap_event, NULL)); } +static int char_access_handler(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg){ + int rc = 0; + + ESP_LOGI(TAG, "char read event"); + + uint16_t svc_ind, chr_ind; + get_indices_from_att_handle(attr_handle, &svc_ind, &chr_ind); + + switch(ctxt->op){ + case BLE_GATT_ACCESS_OP_READ_CHR: + ; + if(on_char_read_callback == NULL) return 0; + void* value; + size_t value_size = 0; + on_char_read_callback(svc_ind, chr_ind, &value, &value_size); + rc = os_mbuf_append(ctxt->om, value, value_size); + break; + case BLE_GATT_ACCESS_OP_READ_DSC: + ; + struct dsc_content* content = (struct dsc_content*)ctxt->dsc->arg; + rc = os_mbuf_append(ctxt->om, content->data, content->data_size); + break; + } + + return rc ? BLE_ATT_ERR_INSUFFICIENT_RES : 0; +} + +void add_on_char_read_handler(charReadCallback cb){ + on_char_read_callback = cb; +} + void set_gatt_services(struct ble_gatt_svc_def* svcs, uint16_t num){ gatt_svr_svcs = svcs; svcs_num = num; @@ -146,6 +192,15 @@ void set_gatt_services(struct ble_gatt_svc_def* svcs, uint16_t num){ for(int chr_ind = 0; chr_ind < svcs_sizes[svc_ind]; chr_ind++){ struct ble_gatt_chr_def* chr = &gatt_svr_svcs[svc_ind].characteristics[chr_ind]; chr->val_handle = &att_handle[svc_ind][chr_ind]; + if(chr->access_cb == NULL) + chr->access_cb = char_access_handler; + + struct ble_gatt_dsc_def* dsc = &chr->descriptors[0]; + for(int dsc_ind = 0; dsc->uuid != NULL; dsc_ind++){ + if(dsc->access_cb == NULL) + dsc->access_cb = char_access_handler; + dsc = &chr->descriptors[dsc_ind]; + } notify_state[svc_ind][chr_ind] = 0; } diff --git a/include/BLE_UUID.h b/include/BLE_UUID.h index 9c24c61..a29437e 100644 --- a/include/BLE_UUID.h +++ b/include/BLE_UUID.h @@ -13,6 +13,7 @@ #define ELECTRIC_CURRENT_RANGE_CHAR 0x2AEF #define AUTO_RANGE_CHAR 0x2C15 #define SWITCHING_FREQUENCY_CHAR 0x2C17 +#define DUTY_CYCLE_FREQUENCY_CHAR 0x2C18 #define CHAR_PRES_FORMAT 0x2904 #define SOURCE_GAIN_DESCR 0x2920 diff --git a/include/BLEh.h b/include/BLEh.h index ca63cb8..f8c32b2 100644 --- a/include/BLEh.h +++ b/include/BLEh.h @@ -15,8 +15,18 @@ struct char_pres_format { uint8_t descrL; }; +struct dsc_content { + size_t data_size; + void* data; +}; + +typedef void (*charReadCallback)(int svc_ind, int chr_ind, void** value, size_t* value_size); +typedef void (*charWriteCallback)(int svc_ind, int chr_ind, void* value, size_t value_size); +typedef void (*dscReadCallback)(int svc_ind, int chr_ind, void** value, size_t* value_size); + void initBLE(char* name); void ble_advertise(void); void set_gatt_services(struct ble_gatt_svc_def* svcs, uint16_t num); void print_service(struct ble_gatt_svc_def* svcs); -void notify(uint16_t svc_ind, uint16_t chr_ind, void* value, size_t value_size); \ No newline at end of file +void notify(uint16_t svc_ind, uint16_t chr_ind, void* value, size_t value_size); +void add_on_char_read_handler(charReadCallback cb); diff --git a/simple_gatt_value_server.c b/simple_gatt_value_server.c index c7130a1..ed819ef 100644 --- a/simple_gatt_value_server.c +++ b/simple_gatt_value_server.c @@ -123,7 +123,7 @@ void simple_gatt_value_server_deinit(){ 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); + // ESP_LOGI(TAG, "notify %d %d", conf->svc_ind, conf->chr_ind); notify(conf->svc_ind, conf->chr_ind, conf->value, conf->value_size); }