@@ -14,6 +14,7 @@ static esp_gattc_char_elem_t* char_elem_result = NULL;
1414static esp_gattc_descr_elem_t * descr_elem_result = NULL ;
1515static bool connect = false;
1616static bool get_server = false;
17+ static char remote_device_name [ESP_BLE_ADV_NAME_LEN_MAX ] = "ELK-BLEDOM" ;
1718static bool draw_headers = true;
1819
1920static 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-
6957static 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+
7891static 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