1
1
/*
2
- * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
2
+ * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
3
3
*
4
4
* SPDX-License-Identifier: Unlicense OR CC0-1.0
5
5
*/
@@ -59,6 +59,19 @@ static char test_device_name[ESP_BLE_ADV_NAME_LEN_MAX] = "ESP_GATTS_DEMO";
59
59
#define PREPARE_BUF_MAX_SIZE 1024
60
60
61
61
static uint8_t char1_str [] = {0x11 ,0x22 ,0x33 };
62
+
63
+ static uint16_t descr_value = 0x0 ;
64
+ /**
65
+ * Current MTU size for the active connection.
66
+ *
67
+ * This simplified implementation assumes a single connection.
68
+ * For multi-connection scenarios, the MTU should be stored per connection ID.
69
+ */
70
+ static uint16_t local_mtu = 23 ;
71
+
72
+ static uint8_t char_value_read [CONFIG_EXAMPLE_CHAR_READ_DATA_LEN ] = {0xDE ,0xED ,0xBE ,0xEF };
73
+
74
+
62
75
static esp_gatt_char_prop_t a_property = 0 ;
63
76
static esp_gatt_char_prop_t b_property = 0 ;
64
77
@@ -348,17 +361,53 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
348
361
esp_ble_gatts_create_service (gatts_if , & gl_profile_tab [PROFILE_A_APP_ID ].service_id , GATTS_NUM_HANDLE_TEST_A );
349
362
break ;
350
363
case ESP_GATTS_READ_EVT : {
351
- ESP_LOGI (GATTS_TAG , "Characteristic read, conn_id %d, trans_id %" PRIu32 ", handle %d" , param -> read .conn_id , param -> read .trans_id , param -> read .handle );
364
+ ESP_LOGI (GATTS_TAG ,
365
+ "Characteristic read request: conn_id=%d, trans_id=%" PRIu32 ", handle=%d, is_long=%d, offset=%d, need_rsp=%d" ,
366
+ param -> read .conn_id , param -> read .trans_id , param -> read .handle ,
367
+ param -> read .is_long , param -> read .offset , param -> read .need_rsp );
368
+
369
+ // If no response is needed, exit early (stack handles it automatically)
370
+ if (!param -> read .need_rsp ) {
371
+ return ;
372
+ }
373
+
352
374
esp_gatt_rsp_t rsp ;
353
375
memset (& rsp , 0 , sizeof (esp_gatt_rsp_t ));
354
376
rsp .attr_value .handle = param -> read .handle ;
355
- rsp .attr_value .len = 4 ;
356
- rsp .attr_value .value [0 ] = 0xde ;
357
- rsp .attr_value .value [1 ] = 0xed ;
358
- rsp .attr_value .value [2 ] = 0xbe ;
359
- rsp .attr_value .value [3 ] = 0xef ;
360
- esp_ble_gatts_send_response (gatts_if , param -> read .conn_id , param -> read .trans_id ,
361
- ESP_GATT_OK , & rsp );
377
+
378
+ // Handle descriptor read request
379
+ if (param -> read .handle == gl_profile_tab [PROFILE_A_APP_ID ].descr_handle ) {
380
+ memcpy (rsp .attr_value .value , & descr_value , 2 );
381
+ rsp .attr_value .len = 2 ;
382
+ esp_ble_gatts_send_response (gatts_if , param -> read .conn_id , param -> read .trans_id , ESP_GATT_OK , & rsp );
383
+ return ;
384
+ }
385
+
386
+ // Handle characteristic read request
387
+ if (param -> read .handle == gl_profile_tab [PROFILE_A_APP_ID ].char_handle ) {
388
+ uint16_t offset = param -> read .offset ;
389
+
390
+ // Validate read offset
391
+ if (param -> read .is_long && offset > CONFIG_EXAMPLE_CHAR_READ_DATA_LEN ) {
392
+ ESP_LOGW (GATTS_TAG , "Read offset (%d) out of range (0-%d)" , offset , CONFIG_EXAMPLE_CHAR_READ_DATA_LEN );
393
+ rsp .attr_value .len = 0 ;
394
+ esp_ble_gatts_send_response (gatts_if , param -> read .conn_id , param -> read .trans_id , ESP_GATT_INVALID_OFFSET , & rsp );
395
+ return ;
396
+ }
397
+
398
+ // Determine response length based on MTU
399
+ uint16_t mtu_size = local_mtu - 1 ; // ATT header (1 byte)
400
+ uint16_t send_len = (CONFIG_EXAMPLE_CHAR_READ_DATA_LEN - offset > mtu_size ) ? mtu_size : (CONFIG_EXAMPLE_CHAR_READ_DATA_LEN - offset );
401
+
402
+ memcpy (rsp .attr_value .value , & char_value_read [offset ], send_len );
403
+ rsp .attr_value .len = send_len ;
404
+
405
+ // Send response to GATT client
406
+ esp_err_t err = esp_ble_gatts_send_response (gatts_if , param -> read .conn_id , param -> read .trans_id , ESP_GATT_OK , & rsp );
407
+ if (err != ESP_OK ) {
408
+ ESP_LOGE (GATTS_TAG , "Failed to send response: %s" , esp_err_to_name (err ));
409
+ }
410
+ }
362
411
break ;
363
412
}
364
413
case ESP_GATTS_WRITE_EVT : {
@@ -367,7 +416,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
367
416
ESP_LOGI (GATTS_TAG , "value len %d, value " , param -> write .len );
368
417
ESP_LOG_BUFFER_HEX (GATTS_TAG , param -> write .value , param -> write .len );
369
418
if (gl_profile_tab [PROFILE_A_APP_ID ].descr_handle == param -> write .handle && param -> write .len == 2 ){
370
- uint16_t descr_value = param -> write .value [1 ]<<8 | param -> write .value [0 ];
419
+ descr_value = param -> write .value [1 ]<<8 | param -> write .value [0 ];
371
420
if (descr_value == 0x0001 ){
372
421
if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY ){
373
422
ESP_LOGI (GATTS_TAG , "Notification enable" );
@@ -412,6 +461,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
412
461
break ;
413
462
case ESP_GATTS_MTU_EVT :
414
463
ESP_LOGI (GATTS_TAG , "MTU exchange, MTU %d" , param -> mtu .mtu );
464
+ local_mtu = param -> mtu .mtu ;
415
465
break ;
416
466
case ESP_GATTS_UNREG_EVT :
417
467
break ;
@@ -490,6 +540,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
490
540
ESP_LOGI (GATTS_TAG , "Disconnected, remote " ESP_BD_ADDR_STR ", reason 0x%02x" ,
491
541
ESP_BD_ADDR_HEX (param -> disconnect .remote_bda ), param -> disconnect .reason );
492
542
esp_ble_gap_start_advertising (& adv_params );
543
+ local_mtu = 23 ; // Reset MTU for a single connection
493
544
break ;
494
545
case ESP_GATTS_CONF_EVT :
495
546
ESP_LOGI (GATTS_TAG , "Confirm receive, status %d, attr_handle %d" , param -> conf .status , param -> conf .handle );
0 commit comments