Skip to content

Commit ac79e0c

Browse files
committed
refactor: Read char
1 parent 25c73ae commit ac79e0c

1 file changed

Lines changed: 161 additions & 135 deletions

File tree

firmware/main/apps/ble/gattcmd/services/gattcmd_enum.c

Lines changed: 161 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ static esp_gattc_char_elem_t* char_elem_result = NULL;
1414
static esp_gattc_descr_elem_t* descr_elem_result = NULL;
1515
static bool connect = false;
1616
static bool get_server = false;
17+
static char remote_device_name[ESP_BLE_ADV_NAME_LEN_MAX] = "ELK-BLEDOM";
1718
static bool draw_headers = true;
1819

1920
static void gattcmd_enum_gap_cb(esp_gap_ble_cb_event_t event,
@@ -53,19 +54,6 @@ struct gattc_profile_inst {
5354
esp_bd_addr_t remote_bda;
5455
};
5556

56-
typedef struct {
57-
uint16_t conn_id;
58-
uint16_t start_handle;
59-
uint16_t end_handle;
60-
esp_gatt_id_t srvc_id;
61-
esp_gattc_char_elem_t* char_elem_result;
62-
uint16_t char_count;
63-
esp_gattc_descr_elem_t* descr_elem_result;
64-
} gattc_profile_table_t;
65-
66-
static gattc_profile_table_t gattc_context[20] = {0};
67-
static uint16_t gattc_context_count = 0;
68-
6957
static struct gattc_profile_inst enum_gl_profile_tab[GATTCMD_ENUM_PROFILE] = {
7058
[GATTCMD_ENUM_APP_ID] =
7159
{
@@ -75,6 +63,31 @@ static struct gattc_profile_inst enum_gl_profile_tab[GATTCMD_ENUM_PROFILE] = {
7563
},
7664
};
7765

66+
static void get_char_properties(uint8_t properties,
67+
char* output,
68+
size_t output_size) {
69+
output[0] = '\0';
70+
if (properties & ESP_GATT_CHAR_PROP_BIT_BROADCAST)
71+
strcat(output, "BROADCAST, ");
72+
if (properties & ESP_GATT_CHAR_PROP_BIT_READ)
73+
strcat(output, "READ, ");
74+
if (properties & ESP_GATT_CHAR_PROP_BIT_WRITE_NR)
75+
strcat(output, "WRITE_NR, ");
76+
if (properties & ESP_GATT_CHAR_PROP_BIT_WRITE)
77+
strcat(output, "WRITE, ");
78+
if (properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY)
79+
strcat(output, "NOTIFY, ");
80+
if (properties & ESP_GATT_CHAR_PROP_BIT_INDICATE)
81+
strcat(output, "INDICATE, ");
82+
if (properties & ESP_GATT_CHAR_PROP_BIT_AUTH)
83+
strcat(output, "AUTH, ");
84+
if (properties & ESP_GATT_CHAR_PROP_BIT_EXT_PROP)
85+
strcat(output, "EXT_PROP, ");
86+
size_t len = strlen(output);
87+
if (len >= 2)
88+
output[len - 2] = '\0';
89+
}
90+
7891
static void gattcmd_enum_gattc_profile_event_handler(
7992
esp_gattc_cb_event_t event,
8093
esp_gatt_if_t gattc_if,
@@ -124,23 +137,20 @@ static void gattcmd_enum_gattc_profile_event_handler(
124137
p_data->search_res.start_handle;
125138
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_end_handle =
126139
p_data->search_res.end_handle;
127-
128-
gattc_context[gattc_context_count].conn_id = param->dis_srvc_cmpl.conn_id;
129-
gattc_context[gattc_context_count].start_handle =
130-
p_data->search_res.start_handle;
131-
gattc_context[gattc_context_count].end_handle =
132-
p_data->search_res.end_handle;
133-
gattc_context[gattc_context_count].srvc_id.inst_id =
134-
p_data->search_res.srvc_id.inst_id;
135-
gattc_context[gattc_context_count].srvc_id.uuid.uuid.uuid16 =
136-
p_data->search_res.srvc_id.uuid.uuid.uuid16;
137-
gattc_context[gattc_context_count].srvc_id.uuid.uuid.uuid32 =
138-
p_data->search_res.srvc_id.uuid.uuid.uuid32;
139-
memcpy(gattc_context[gattc_context_count].srvc_id.uuid.uuid.uuid128,
140-
p_data->search_res.srvc_id.uuid.uuid.uuid128, ESP_UUID_LEN_128);
141-
gattc_context[gattc_context_count].srvc_id.uuid.len =
142-
p_data->search_res.srvc_id.uuid.len;
143-
gattc_context_count++;
140+
if (draw_headers) {
141+
draw_headers = false;
142+
printf(
143+
"|__________________|________________________________________\n");
144+
printf(
145+
"| Handles | Service > Characteristics > Descriptors |\n");
146+
printf(
147+
"|__________________|________________________________________\n");
148+
}
149+
printf(
150+
"| %04x -> %04x | UUID: 0x%04x (Service) "
151+
"|\n",
152+
p_data->search_res.start_handle, p_data->search_res.end_handle,
153+
p_data->search_res.srvc_id.uuid.uuid.uuid16);
144154
break;
145155
}
146156
case ESP_GATTC_SEARCH_CMPL_EVT:
@@ -156,124 +166,130 @@ static void gattcmd_enum_gattc_profile_event_handler(
156166
} else {
157167
ESP_LOGI(GATTCMD_ENUM_TAG, "Unknown service source");
158168
}
169+
printf(
170+
"|______________________|________________________________________\n");
171+
printf("|\t %04x -> %04x \t|\t\t\t\t|\n",
172+
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_start_handle,
173+
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_end_handle);
159174

160-
if (!get_server) {
161-
break;
162-
}
163-
uint16_t idx = 0;
164-
for (int i = 0; i < gattc_context_count; i++) {
165-
if (gattc_context[i].conn_id ==
166-
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_end_handle) {
167-
idx = i;
168-
}
169-
}
170-
uint16_t offset = 0;
171-
esp_gatt_status_t status = esp_ble_gattc_get_attr_count(
172-
gattc_if, p_data->search_cmpl.conn_id, ESP_GATT_DB_CHARACTERISTIC,
173-
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_start_handle,
174-
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_end_handle,
175-
INVALID_HANDLE, &gattc_context[idx].char_count);
176-
if (status != ESP_GATT_OK) {
177-
ESP_LOGE(GATTCMD_ENUM_TAG, "esp_ble_gattc_get_attr_count error");
178-
break;
179-
}
180-
if (gattc_context[idx].char_count > 0) {
181-
gattc_context[idx].char_elem_result = (esp_gattc_char_elem_t*) malloc(
182-
sizeof(esp_gattc_char_elem_t) * gattc_context[idx].char_count);
183-
if (!gattc_context[idx].char_elem_result) {
184-
ESP_LOGE(GATTCMD_ENUM_TAG, "gattc no mem");
175+
if (get_server) {
176+
uint16_t count = 0;
177+
uint16_t offset = 0;
178+
esp_gatt_status_t status = esp_ble_gattc_get_attr_count(
179+
gattc_if, p_data->search_cmpl.conn_id, ESP_GATT_DB_CHARACTERISTIC,
180+
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_start_handle,
181+
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_end_handle,
182+
INVALID_HANDLE, &count);
183+
if (status != ESP_GATT_OK) {
184+
ESP_LOGE(GATTCMD_ENUM_TAG, "esp_ble_gattc_get_attr_count error");
185185
break;
186-
} else {
186+
}
187+
if (count > 0) {
188+
char_elem_result = (esp_gattc_char_elem_t*) malloc(
189+
sizeof(esp_gattc_char_elem_t) * count);
190+
if (!char_elem_result) {
191+
ESP_LOGE(GATTCMD_ENUM_TAG, "gattc no mem");
192+
break;
193+
}
187194
status = esp_ble_gattc_get_all_char(
188195
gattc_if, p_data->search_cmpl.conn_id,
189196
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_start_handle,
190197
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].service_end_handle,
191-
gattc_context[idx].char_elem_result,
192-
&gattc_context[idx].char_count, offset);
198+
char_elem_result, &count, offset);
193199
if (status != ESP_GATT_OK) {
194200
ESP_LOGE(GATTCMD_ENUM_TAG, "esp_ble_gattc_get_char_by_uuid error");
195-
free(gattc_context[idx].char_elem_result);
196-
gattc_context[idx].char_elem_result = NULL;
201+
free(char_elem_result);
202+
char_elem_result = NULL;
197203
break;
198204
}
199-
for (int i = 0; i < gattc_context[idx].char_count; i++) {
200-
if (gattc_context[idx].char_elem_result[i].properties ==
201-
ESP_GATT_CHAR_PROP_BIT_READ ||
202-
gattc_context[idx].char_elem_result[i].properties == 6) {
203-
status = esp_ble_gattc_read_char_descr(
205+
for (int i = 0; i < count; i++) {
206+
char prop_str[128];
207+
get_char_properties(char_elem_result[i].properties, prop_str,
208+
sizeof(prop_str));
209+
printf("| %04x | UUID: 0x%04x (Char), Handle: %d, Props: %s |\n",
210+
char_elem_result[i].char_handle,
211+
char_elem_result[i].uuid.uuid.uuid16,
212+
char_elem_result[i].char_handle, prop_str);
213+
if (char_elem_result[i].properties & ESP_GATT_CHAR_PROP_BIT_READ) {
214+
esp_ble_gattc_read_char(gattc_if, p_data->search_cmpl.conn_id,
215+
char_elem_result[i].char_handle,
216+
ESP_GATT_AUTH_REQ_NONE);
217+
}
218+
219+
uint16_t desc_count = 0;
220+
status = esp_ble_gattc_get_attr_count(
221+
gattc_if, p_data->search_cmpl.conn_id, ESP_GATT_DB_DESCRIPTOR,
222+
char_elem_result[i].char_handle,
223+
char_elem_result[i].char_handle + 1,
224+
char_elem_result[i].char_handle, &desc_count);
225+
if (status != ESP_GATT_OK) {
226+
ESP_LOGE(GATTCMD_ENUM_TAG,
227+
"esp_ble_gattc_get_attr_count (descr) error");
228+
continue;
229+
}
230+
if (desc_count > 0) {
231+
descr_elem_result = (esp_gattc_descr_elem_t*) malloc(
232+
sizeof(esp_gattc_descr_elem_t) * desc_count);
233+
if (!descr_elem_result) {
234+
ESP_LOGE(GATTCMD_ENUM_TAG, "Failed malloc");
235+
continue;
236+
}
237+
status = esp_ble_gattc_get_all_descr(
204238
gattc_if, p_data->search_cmpl.conn_id,
205-
gattc_context[idx].char_elem_result[i].char_handle,
206-
ESP_GATT_AUTH_REQ_NONE);
239+
char_elem_result[i].char_handle, descr_elem_result,
240+
&desc_count, 0);
207241
if (status != ESP_GATT_OK) {
208-
ESP_LOGE(GATTCMD_ENUM_TAG, "Reading char-descr error");
209-
return;
242+
ESP_LOGE(GATTCMD_ENUM_TAG, "esp_ble_gattc_get_all_descr error");
243+
free(descr_elem_result);
244+
descr_elem_result = NULL;
245+
continue;
246+
}
247+
for (int j = 0; j < desc_count; j++) {
248+
printf(
249+
"| %04x | UUID: 0x%04x (Descr), Handle: %d "
250+
"|\n",
251+
descr_elem_result[j].handle,
252+
descr_elem_result[j].uuid.uuid.uuid16,
253+
descr_elem_result[j].handle);
254+
esp_ble_gattc_read_char_descr(
255+
gattc_if, p_data->search_cmpl.conn_id,
256+
descr_elem_result[j].handle, ESP_GATT_AUTH_REQ_NONE);
210257
}
258+
free(descr_elem_result);
259+
descr_elem_result = NULL;
211260
}
212261
}
262+
free(char_elem_result);
263+
descr_elem_result = NULL;
264+
} else {
265+
ESP_LOGE(GATTCMD_ENUM_TAG, "no char found");
213266
}
214-
/* free gattc_context[idx].char_elem_result */
215-
// free(gattc_context[idx].char_elem_result);
216-
} else {
217-
ESP_LOGE(GATTCMD_ENUM_TAG, "no char found");
218-
}
219-
break;
220-
case ESP_GATTC_READ_CHAR_EVT:
221-
if (draw_headers) {
222-
draw_headers = false;
223267
printf(
224-
"\n|_______________________|_________________________________|_____"
225-
"______|__________________|"
268+
"|______________________|________________________________________"
226269
"\n");
227-
printf(
228-
"|\t Handles \t| \tService > Characteristics | Properties| \t Data "
229-
"\t|\n");
230270
}
231-
// printf("| %d\t\t|\t%s\t\t|\n", p_data->read.handle,
232-
// p_data->read.value); ESP_LOGI(GATTCMD_ENUM_TAG, "Count service %d",
233-
// gattc_context_count);
234-
for (int i = 0; i < gattc_context_count; i++) {
235-
printf("|\t %04x -> %04x \t| %04x \t\t\t\t\t|\t|\t|\n",
236-
gattc_context[i].start_handle, gattc_context[i].end_handle,
237-
gattc_context[i].srvc_id.uuid.uuid.uuid16);
238-
for (int j = 0; j < gattc_context[i].char_count; i++) {
239-
printf("|\t %04x \t\t|\t %04x \t\t\t\t| %s | %s\n",
240-
gattc_context[i].char_elem_result[j].char_handle,
241-
gattc_context[i].char_elem_result[j].uuid.uuid.uuid16,
242-
gattc_context[i].char_elem_result[j].properties &
243-
(ESP_GATT_CHAR_PROP_BIT_READ |
244-
ESP_GATT_CHAR_PROP_BIT_WRITE)
245-
? "READ, WRITE"
246-
: gattc_context[i].char_elem_result[j].properties &
247-
ESP_GATT_CHAR_PROP_BIT_READ
248-
? "READ"
249-
: gattc_context[i].char_elem_result[j].properties &
250-
ESP_GATT_CHAR_PROP_BIT_WRITE
251-
? "WRITE"
252-
: gattc_context[i].char_elem_result[j].properties &
253-
ESP_GATT_CHAR_PROP_BIT_NOTIFY
254-
? "NOTIFY"
255-
: gattc_context[i].char_elem_result[j].properties &
256-
ESP_GATT_CHAR_PROP_BIT_INDICATE
257-
? "INDICATE"
258-
: "Unknown",
259-
p_data->read.value);
260-
}
271+
break;
272+
case ESP_GATTC_READ_CHAR_EVT:
273+
if (p_data->read.status != ESP_GATT_OK) {
274+
break;
261275
}
276+
printf("| %04x| Char value: %s |\n", p_data->read.handle,
277+
p_data->read.value);
262278
break;
263279
case ESP_GATTC_READ_DESCR_EVT:
264280
if (p_data->read.status != ESP_GATT_OK) {
265-
ESP_LOGE(GATTCMD_ENUM_TAG, "Descriptor read failed, status %x",
266-
p_data->read.status);
267281
break;
268282
}
269-
status =
270-
esp_ble_gattc_read_char(gattc_if, p_data->search_res.conn_id,
271-
p_data->read.handle, ESP_GATT_AUTH_REQ_NONE);
272-
if (status != ESP_GATT_OK) {
273-
ESP_LOGE(GATTCMD_ENUM_TAG, "Reading char error");
274-
return;
275-
}
283+
printf("| %04x| %04x \t\t| %s |\n", p_data->read.handle,
284+
p_data->read.handle, p_data->read.value);
285+
break;
286+
case ESP_GATTC_SRVC_CHG_EVT: {
287+
esp_bd_addr_t bda;
288+
memcpy(bda, p_data->srvc_chg.remote_bda, sizeof(esp_bd_addr_t));
289+
ESP_LOGI(GATTCMD_ENUM_TAG, "Service change from " ESP_BD_ADDR_STR "",
290+
ESP_BD_ADDR_HEX(bda));
276291
break;
292+
}
277293
case ESP_GATTC_DISCONNECT_EVT:
278294
connect = false;
279295
get_server = false;
@@ -293,42 +309,52 @@ static void gattcmd_enum_gap_cb(esp_gap_ble_cb_event_t event,
293309
uint8_t adv_name_len = 0;
294310
switch (event) {
295311
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: {
312+
// the unit of the duration is second
296313
uint32_t duration = 30;
297314
esp_ble_gap_start_scanning(duration);
298315
break;
299316
}
300317
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
318+
// scan start complete event to indicate scan start successfully or failed
301319
if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
302320
ESP_LOGE(GATTCMD_ENUM_TAG, "Scanning start failed, status %x",
303321
param->scan_start_cmpl.status);
304322
break;
305323
}
324+
ESP_LOGI(GATTCMD_ENUM_TAG, "Scanning start successfully");
325+
306326
break;
307327
case ESP_GAP_BLE_SCAN_RESULT_EVT: {
308328
esp_ble_gap_cb_param_t* scan_result = (esp_ble_gap_cb_param_t*) param;
309329
switch (scan_result->scan_rst.search_evt) {
310-
case ESP_GAP_SEARCH_INQ_RES_EVT: {
330+
case ESP_GAP_SEARCH_INQ_RES_EVT:
311331
adv_name = esp_ble_resolve_adv_data_by_type(
312332
scan_result->scan_rst.ble_adv,
313333
scan_result->scan_rst.adv_data_len +
314334
scan_result->scan_rst.scan_rsp_len,
315335
ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
316-
if (adv_name_len > 0) {
317-
if (adv_name != NULL) {
318-
if (memcmp(target_bda, scan_result->scan_rst.bda, 6) == 0) {
319-
if (connect == false) {
320-
connect = true;
321-
esp_ble_gap_stop_scanning();
322-
esp_ble_gattc_open(
323-
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].gattc_if,
324-
scan_result->scan_rst.bda,
325-
scan_result->scan_rst.ble_addr_type, true);
326-
}
336+
if (adv_name_len > 0)
337+
ESP_LOGI(GATTCMD_ENUM_TAG,
338+
"Scan result, device " ESP_BD_ADDR_STR ", name len %u",
339+
ESP_BD_ADDR_HEX(scan_result->scan_rst.bda), adv_name_len);
340+
// ESP_LOG_BUFFER_CHAR(GATTCMD_ENUM_TAG, adv_name, adv_name_len);
341+
// ESP_LOGI(GATTCMD_ENUM_TAG, "Locking for %s", remote_device_name);
342+
if (adv_name != NULL) {
343+
if (memcmp(target_bda, scan_result->scan_rst.bda, 6) == 0) {
344+
ESP_LOGE(GATTCMD_ENUM_TAG, "I Found you");
345+
ESP_LOGI(GATTCMD_ENUM_TAG, "Device found %s", remote_device_name);
346+
if (connect == false) {
347+
connect = true;
348+
ESP_LOGI(GATTCMD_ENUM_TAG, "Connect to the remote device");
349+
esp_ble_gap_stop_scanning();
350+
esp_ble_gattc_open(
351+
enum_gl_profile_tab[GATTCMD_ENUM_APP_ID].gattc_if,
352+
scan_result->scan_rst.bda,
353+
scan_result->scan_rst.ble_addr_type, true);
327354
}
328355
}
329356
}
330357
break;
331-
}
332358
case ESP_GAP_SEARCH_INQ_CMPL_EVT:
333359
break;
334360
default:

0 commit comments

Comments
 (0)