xref: /btstack/src/classic/hfp.c (revision 90af00b83ef3cf38af21be9d8e98b07db75c02f3)
1 /*
2  * Copyright (C) 2014 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define BTSTACK_FILE__ "hfp.c"
39 
40 
41 #include "btstack_config.h"
42 
43 #include <stdint.h>
44 #include <string.h>
45 #include <inttypes.h>
46 
47 #include "bluetooth_sdp.h"
48 #include "btstack_debug.h"
49 #include "btstack_event.h"
50 #include "btstack_memory.h"
51 #include "btstack_run_loop.h"
52 #include "classic/sdp_client_rfcomm.h"
53 #include "classic/sdp_server.h"
54 #include "classic/sdp_util.h"
55 #include "classic/sdp_client.h"
56 #include "hci.h"
57 #include "hci_cmd.h"
58 #include "hci_dump.h"
59 
60 #if defined(ENABLE_CC256X_ASSISTED_HFP) && !defined(ENABLE_SCO_OVER_PCM)
61 #error "Assisted HFP is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM"
62 #endif
63 
64 #if defined(ENABLE_BCM_PCM_WBS) && !defined(ENABLE_SCO_OVER_PCM)
65 #error "WBS for PCM is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM"
66 #endif
67 
68 #define HFP_HF_FEATURES_SIZE 10
69 #define HFP_AG_FEATURES_SIZE 12
70 
71 typedef struct {
72     hfp_role_t local_role;
73     bd_addr_t  remote_address;
74 } hfp_sdp_query_context_t;
75 
76 // globals
77 
78 static hfp_sdp_query_context_t sdp_query_context;
79 static btstack_context_callback_registration_t hfp_handle_sdp_client_query_request;
80 
81 static btstack_linked_list_t hfp_connections ;
82 
83 static btstack_packet_handler_t hfp_hf_callback;
84 static btstack_packet_handler_t hfp_ag_callback;
85 
86 static btstack_packet_handler_t hfp_hf_rfcomm_packet_handler;
87 static btstack_packet_handler_t hfp_ag_rfcomm_packet_handler;
88 
89 static hfp_connection_t * sco_establishment_active;
90 
91 static uint16_t hfp_allowed_sco_packet_types;
92 
93 // prototypes
94 static hfp_link_settings_t hfp_next_link_setting_for_connection(hfp_link_settings_t current_setting, hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported);
95 static void parse_sequence(hfp_connection_t * context);
96 
97 
98 static const char * hfp_hf_features[] = {
99         "EC and/or NR function",
100         "Three-way calling",
101         "CLI presentation capability",
102         "Voice recognition activation",
103         "Remote volume control",
104 
105         "Enhanced call status",
106         "Enhanced call control",
107 
108         "Codec negotiation",
109 
110         "HF Indicators",
111         "eSCO S4 (and T2) Settings Supported",
112         "Reserved for future definition"
113 };
114 
115 static const char * hfp_ag_features[] = {
116         "Three-way calling",
117         "EC and/or NR function",
118         "Voice recognition function",
119         "In-band ring tone capability",
120         "Attach a number to a voice tag",
121         "Ability to reject a call",
122         "Enhanced call status",
123         "Enhanced call control",
124         "Extended Error Result Codes",
125         "Codec negotiation",
126         "HF Indicators",
127         "eSCO S4 (and T2) Settings Supported",
128         "Reserved for future definition"
129 };
130 
131 static const char * hfp_enhanced_call_dir[] = {
132         "outgoing",
133         "incoming"
134 };
135 
136 static const char * hfp_enhanced_call_status[] = {
137         "active",
138         "held",
139         "outgoing dialing",
140         "outgoing alerting",
141         "incoming",
142         "incoming waiting",
143         "call held by response and hold"
144 };
145 
146 static const char * hfp_enhanced_call_mode[] = {
147         "voice",
148         "data",
149         "fax"
150 };
151 
152 static const char * hfp_enhanced_call_mpty[] = {
153         "not a conference call",
154         "conference call"
155 };
156 
157 const char * hfp_enhanced_call_dir2str(uint16_t index){
158     if (index <= HFP_ENHANCED_CALL_DIR_INCOMING) return hfp_enhanced_call_dir[index];
159     return "not defined";
160 }
161 
162 const char * hfp_enhanced_call_status2str(uint16_t index){
163     if (index <= HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD) return hfp_enhanced_call_status[index];
164     return "not defined";
165 }
166 
167 const char * hfp_enhanced_call_mode2str(uint16_t index){
168     if (index <= HFP_ENHANCED_CALL_MODE_FAX) return hfp_enhanced_call_mode[index];
169     return "not defined";
170 }
171 
172 const char * hfp_enhanced_call_mpty2str(uint16_t index){
173     if (index <= HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL) return hfp_enhanced_call_mpty[index];
174     return "not defined";
175 }
176 
177 static uint16_t hfp_parse_indicator_index(hfp_connection_t * hfp_connection){
178     uint16_t index = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
179 
180     if (index > HFP_MAX_NUM_INDICATORS){
181         log_info("ignoring invalid indicator index bigger then HFP_MAX_NUM_INDICATORS");
182         return HFP_MAX_NUM_INDICATORS - 1;
183     }
184 
185     // indicator index enumeration starts with 1, we substract 1 to store in array with starting index 0
186     if (index > 0){
187         index -= 1;
188     } else {
189         log_info("ignoring invalid indicator index 0");
190         return 0;
191     }
192     return index;
193 }
194 
195 static void hfp_next_indicators_index(hfp_connection_t * hfp_connection){
196     if (hfp_connection->parser_item_index < HFP_MAX_NUM_INDICATORS - 1){
197         hfp_connection->parser_item_index++;
198     } else {
199         log_info("Ignoring additional indicator");
200     }
201 }
202 
203 static void hfp_next_codec_index(hfp_connection_t * hfp_connection){
204     if (hfp_connection->parser_item_index < HFP_MAX_NUM_CODECS - 1){
205         hfp_connection->parser_item_index++;
206     } else {
207         log_info("Ignoring additional codec index");
208     }
209 }
210 
211 static void hfp_next_remote_call_services_index(hfp_connection_t * hfp_connection){
212     if (hfp_connection->remote_call_services_index < HFP_MAX_NUM_CALL_SERVICES - 1){
213         hfp_connection->remote_call_services_index++;
214     } else {
215         log_info("Ignoring additional remote_call_services");
216     }
217 }
218 
219 const char * hfp_hf_feature(int index){
220     if (index > HFP_HF_FEATURES_SIZE){
221         return hfp_hf_features[HFP_HF_FEATURES_SIZE];
222     }
223     return hfp_hf_features[index];
224 }
225 
226 const char * hfp_ag_feature(int index){
227     if (index > HFP_AG_FEATURES_SIZE){
228         return hfp_ag_features[HFP_AG_FEATURES_SIZE];
229     }
230     return hfp_ag_features[index];
231 }
232 
233 int send_str_over_rfcomm(uint16_t cid, char * command){
234     if (!rfcomm_can_send_packet_now(cid)) return 1;
235     log_info("HFP_TX %s", command);
236     int err = rfcomm_send(cid, (uint8_t*) command, strlen(command));
237     if (err){
238         log_error("rfcomm_send -> error 0x%02x \n", err);
239     }
240 #ifdef ENABLE_HFP_AT_MESSAGES
241     hfp_connection_t * hfp_connection = get_hfp_connection_context_for_rfcomm_cid(cid);
242     hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_AT_MESSAGE_SENT, command);
243 #endif
244     return 1;
245 }
246 
247 int hfp_supports_codec(uint8_t codec, int codecs_nr, uint8_t * codecs){
248 
249     // mSBC requires support for eSCO connections
250     if ((codec == HFP_CODEC_MSBC) && !hci_extended_sco_link_supported()) return 0;
251 
252     int i;
253     for (i = 0; i < codecs_nr; i++){
254         if (codecs[i] != codec) continue;
255         return 1;
256     }
257     return 0;
258 }
259 
260 void hfp_hf_drop_mSBC_if_eSCO_not_supported(uint8_t * codecs, uint8_t * codecs_nr){
261     if (hci_extended_sco_link_supported()) return;
262     uint8_t tmp_codecs[HFP_MAX_NUM_CODECS];
263     int i;
264     int tmp_codec_nr = 0;
265     for (i=0; i < *codecs_nr; i++){
266         if (codecs[i] == HFP_CODEC_MSBC) continue;
267         tmp_codecs[tmp_codec_nr++] = codecs[i];
268     }
269     *codecs_nr = tmp_codec_nr;
270     (void)memcpy(codecs, tmp_codecs, tmp_codec_nr);
271 }
272 
273 // UTILS
274 int get_bit(uint16_t bitmap, int position){
275     return (bitmap >> position) & 1;
276 }
277 
278 int store_bit(uint32_t bitmap, int position, uint8_t value){
279     if (value){
280         bitmap |= 1 << position;
281     } else {
282         bitmap &= ~ (1 << position);
283     }
284     return bitmap;
285 }
286 
287 int join(char * buffer, int buffer_size, uint8_t * values, int values_nr){
288     if (buffer_size < (values_nr * 3)) return 0;
289     int i;
290     int offset = 0;
291     for (i = 0; i < (values_nr-1); i++) {
292       offset += snprintf(buffer+offset, buffer_size-offset, "%d,", values[i]); // puts string into buffer
293     }
294     if (i<values_nr){
295         offset += snprintf(buffer+offset, buffer_size-offset, "%d", values[i]);
296     }
297     return offset;
298 }
299 
300 int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){
301     if (buffer_size < (values_nr * 3)) return 0;
302 
303     int i;
304     int offset = 0;
305     for (i = 0; i < (values_nr-1); i++) {
306       offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_bit(values,i)); // puts string into buffer
307     }
308 
309     if (i<values_nr){
310         offset += snprintf(buffer+offset, buffer_size-offset, "%d", get_bit(values,i));
311     }
312     return offset;
313 }
314 
315 static void hfp_emit_event_for_context(hfp_connection_t * hfp_connection, uint8_t * packet, uint16_t size){
316     if (!hfp_connection) return;
317     btstack_packet_handler_t callback = NULL;
318     switch (hfp_connection->local_role){
319         case HFP_ROLE_HF:
320             callback = hfp_hf_callback;
321             break;
322         case HFP_ROLE_AG:
323             callback = hfp_ag_callback;
324             break;
325         default:
326             return;
327     }
328     (*callback)(HCI_EVENT_PACKET, 0, packet, size);
329 }
330 
331 void hfp_emit_simple_event(hfp_connection_t * hfp_connection, uint8_t event_subtype){
332     hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
333     uint8_t event[5];
334     event[0] = HCI_EVENT_HFP_META;
335     event[1] = sizeof(event) - 2;
336     event[2] = event_subtype;
337     little_endian_store_16(event, 3, acl_handle);
338     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
339 }
340 
341 void hfp_emit_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, uint8_t value){
342     hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
343     uint8_t event[6];
344     event[0] = HCI_EVENT_HFP_META;
345     event[1] = sizeof(event) - 2;
346     event[2] = event_subtype;
347     little_endian_store_16(event, 3, acl_handle);
348     event[5] = value; // status 0 == OK
349     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
350 }
351 
352 void hfp_emit_slc_connection_event(hfp_connection_t * hfp_connection, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr){
353     btstack_assert(hfp_connection != NULL);
354     uint8_t event[12];
355     int pos = 0;
356     event[pos++] = HCI_EVENT_HFP_META;
357     event[pos++] = sizeof(event) - 2;
358     event[pos++] = HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
359     event[pos++] = status; // status 0 == OK
360     little_endian_store_16(event, pos, con_handle);
361     pos += 2;
362     reverse_bd_addr(addr,&event[pos]);
363     pos += 6;
364     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
365 }
366 
367 static void hfp_emit_audio_connection_released(hfp_connection_t * hfp_connection, hci_con_handle_t sco_handle){
368     btstack_assert(hfp_connection != NULL);
369     uint8_t event[7];
370     int pos = 0;
371     event[pos++] = HCI_EVENT_HFP_META;
372     event[pos++] = sizeof(event) - 2;
373     event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED;
374     little_endian_store_16(event, pos, hfp_connection->acl_handle);
375     pos += 2;
376     little_endian_store_16(event, pos, sco_handle);
377     pos += 2;
378     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
379 }
380 
381 void hfp_emit_sco_event(hfp_connection_t * hfp_connection, uint8_t status, hci_con_handle_t sco_handle, bd_addr_t addr, uint8_t  negotiated_codec){
382     btstack_assert(hfp_connection != NULL);
383     uint8_t event[15];
384     int pos = 0;
385     event[pos++] = HCI_EVENT_HFP_META;
386     event[pos++] = sizeof(event) - 2;
387     event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED;
388     little_endian_store_16(event, pos, hfp_connection->acl_handle);
389     pos += 2;
390     event[pos++] = status; // status 0 == OK
391     little_endian_store_16(event, pos, sco_handle);
392     pos += 2;
393     reverse_bd_addr(addr,&event[pos]);
394     pos += 6;
395     event[pos++] = negotiated_codec;
396     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
397 }
398 
399 void hfp_emit_string_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, const char * value){
400     btstack_assert(hfp_connection != NULL);
401 #ifdef ENABLE_HFP_AT_MESSAGES
402     uint8_t event[256];
403 #else
404     uint8_t event[40];
405 #endif
406     event[0] = HCI_EVENT_HFP_META;
407     event[1] = sizeof(event) - 2;
408     event[2] = event_subtype;
409     little_endian_store_16(event, 3, hfp_connection->acl_handle);
410     uint16_t size = btstack_min(strlen(value), sizeof(event) - 6);
411     strncpy((char*)&event[3], value, size);
412     event[5 + size] = 0;
413     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
414 }
415 
416 btstack_linked_list_t * hfp_get_connections(void){
417     return (btstack_linked_list_t *) &hfp_connections;
418 }
419 
420 hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){
421     btstack_linked_list_iterator_t it;
422     btstack_linked_list_iterator_init(&it, hfp_get_connections());
423     while (btstack_linked_list_iterator_has_next(&it)){
424         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
425         if (hfp_connection->rfcomm_cid == cid){
426             return hfp_connection;
427         }
428     }
429     return NULL;
430 }
431 
432 hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t hfp_role){
433     btstack_linked_list_iterator_t it;
434     btstack_linked_list_iterator_init(&it, hfp_get_connections());
435     while (btstack_linked_list_iterator_has_next(&it)){
436         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
437         if ((memcmp(hfp_connection->remote_addr, bd_addr, 6) == 0) && (hfp_connection->local_role == hfp_role)) {
438             return hfp_connection;
439         }
440     }
441     return NULL;
442 }
443 
444 hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle, hfp_role_t hfp_role){
445     btstack_linked_list_iterator_t it;
446     btstack_linked_list_iterator_init(&it, hfp_get_connections());
447     while (btstack_linked_list_iterator_has_next(&it)){
448         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
449         if ((hfp_connection->sco_handle == handle) && (hfp_connection->local_role == hfp_role)){
450             return hfp_connection;
451         }
452     }
453     return NULL;
454 }
455 
456 hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle, hfp_role_t hfp_role){
457     btstack_linked_list_iterator_t it;
458     btstack_linked_list_iterator_init(&it, hfp_get_connections());
459     while (btstack_linked_list_iterator_has_next(&it)){
460         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
461         if ((hfp_connection->acl_handle == handle) && (hfp_connection->local_role == hfp_role)){
462             return hfp_connection;
463         }
464     }
465     return NULL;
466 }
467 
468 void hfp_reset_context_flags(hfp_connection_t * hfp_connection){
469     if (!hfp_connection) return;
470     hfp_connection->ok_pending = 0;
471     hfp_connection->send_error = 0;
472 
473     hfp_connection->found_equal_sign = false;
474 
475     hfp_connection->change_status_update_for_individual_ag_indicators = 0;
476     hfp_connection->operator_name_changed = 0;
477 
478     hfp_connection->enable_extended_audio_gateway_error_report = 0;
479     hfp_connection->extended_audio_gateway_error = 0;
480 
481     // establish codecs hfp_connection
482     hfp_connection->suggested_codec = 0;
483     hfp_connection->negotiated_codec = 0;
484     hfp_connection->codec_confirmed = 0;
485 
486     hfp_connection->establish_audio_connection = 0;
487     hfp_connection->call_waiting_notification_enabled = 0;
488     hfp_connection->command = HFP_CMD_NONE;
489     hfp_connection->enable_status_update_for_ag_indicators = 0xFF;
490 }
491 
492 static hfp_connection_t * create_hfp_connection_context(void){
493     hfp_connection_t * hfp_connection = btstack_memory_hfp_connection_get();
494     if (!hfp_connection) return NULL;
495 
496     hfp_connection->state = HFP_IDLE;
497     hfp_connection->call_state = HFP_CALL_IDLE;
498     hfp_connection->codecs_state = HFP_CODECS_IDLE;
499 
500     hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
501     hfp_connection->command = HFP_CMD_NONE;
502 
503     hfp_connection->acl_handle = HCI_CON_HANDLE_INVALID;
504     hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID;
505 
506     hfp_reset_context_flags(hfp_connection);
507 
508     btstack_linked_list_add(&hfp_connections, (btstack_linked_item_t*)hfp_connection);
509     return hfp_connection;
510 }
511 
512 void hfp_finalize_connection_context(hfp_connection_t * hfp_connection){
513     btstack_linked_list_remove(&hfp_connections, (btstack_linked_item_t*) hfp_connection);
514     btstack_memory_hfp_connection_free(hfp_connection);
515 }
516 
517 static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t local_role){
518     hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr, local_role);
519     if (hfp_connection) return  hfp_connection;
520     hfp_connection = create_hfp_connection_context();
521     (void)memcpy(hfp_connection->remote_addr, bd_addr, 6);
522     hfp_connection->local_role = local_role;
523     log_info("Create HFP context %p: role %u, addr %s", hfp_connection, local_role, bd_addr_to_str(bd_addr));
524 
525     return hfp_connection;
526 }
527 
528 /* @param network.
529  * 0 == no ability to reject a call.
530  * 1 == ability to reject a call.
531  */
532 
533 /* @param suported_features
534  * HF bit 0: EC and/or NR function (yes/no, 1 = yes, 0 = no)
535  * HF bit 1: Call waiting or three-way calling(yes/no, 1 = yes, 0 = no)
536  * HF bit 2: CLI presentation capability (yes/no, 1 = yes, 0 = no)
537  * HF bit 3: Voice recognition activation (yes/no, 1= yes, 0 = no)
538  * HF bit 4: Remote volume control (yes/no, 1 = yes, 0 = no)
539  * HF bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
540  */
541  /* Bit position:
542  * AG bit 0: Three-way calling (yes/no, 1 = yes, 0 = no)
543  * AG bit 1: EC and/or NR function (yes/no, 1 = yes, 0 = no)
544  * AG bit 2: Voice recognition function (yes/no, 1 = yes, 0 = no)
545  * AG bit 3: In-band ring tone capability (yes/no, 1 = yes, 0 = no)
546  * AG bit 4: Attach a phone number to a voice tag (yes/no, 1 = yes, 0 = no)
547  * AG bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
548  */
549 
550 void hfp_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t service_uuid, int rfcomm_channel_nr, const char * name){
551     uint8_t* attribute;
552     de_create_sequence(service);
553 
554     // 0x0000 "Service Record Handle"
555     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
556     de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
557 
558     // 0x0001 "Service Class ID List"
559     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
560     attribute = de_push_sequence(service);
561     {
562         //  "UUID for Service"
563         de_add_number(attribute, DE_UUID, DE_SIZE_16, service_uuid);
564         de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_GENERIC_AUDIO);
565     }
566     de_pop_sequence(service, attribute);
567 
568     // 0x0004 "Protocol Descriptor List"
569     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
570     attribute = de_push_sequence(service);
571     {
572         uint8_t* l2cpProtocol = de_push_sequence(attribute);
573         {
574             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
575         }
576         de_pop_sequence(attribute, l2cpProtocol);
577 
578         uint8_t* rfcomm = de_push_sequence(attribute);
579         {
580             de_add_number(rfcomm,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_RFCOMM);  // rfcomm_service
581             de_add_number(rfcomm,  DE_UINT, DE_SIZE_8,  rfcomm_channel_nr);  // rfcomm channel
582         }
583         de_pop_sequence(attribute, rfcomm);
584     }
585     de_pop_sequence(service, attribute);
586 
587 
588     // 0x0005 "Public Browse Group"
589     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group
590     attribute = de_push_sequence(service);
591     {
592         de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT);
593     }
594     de_pop_sequence(service, attribute);
595 
596     // 0x0009 "Bluetooth Profile Descriptor List"
597     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
598     attribute = de_push_sequence(service);
599     {
600         uint8_t *sppProfile = de_push_sequence(attribute);
601         {
602             de_add_number(sppProfile,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HANDSFREE);
603             de_add_number(sppProfile,  DE_UINT, DE_SIZE_16, 0x0107); // Verision 1.7
604         }
605         de_pop_sequence(attribute, sppProfile);
606     }
607     de_pop_sequence(service, attribute);
608 
609     // 0x0100 "Service Name"
610     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
611     de_add_data(service,  DE_STRING, strlen(name), (uint8_t *) name);
612 }
613 
614 static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
615     UNUSED(packet_type);    // ok: handling own sdp events
616     UNUSED(channel);        // ok: no channel
617     UNUSED(size);           // ok: handling own sdp events
618 
619     hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(sdp_query_context.remote_address, sdp_query_context.local_role);
620     if (hfp_connection == NULL) {
621         log_info("connection with %s and local role %d not found", sdp_query_context.remote_address, sdp_query_context.local_role);
622         return;
623     }
624 
625     switch (hci_event_packet_get_type(packet)){
626         case SDP_EVENT_QUERY_RFCOMM_SERVICE:
627             hfp_connection->rfcomm_channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet);
628             break;
629         case SDP_EVENT_QUERY_COMPLETE:
630             if (hfp_connection->rfcomm_channel_nr > 0){
631                 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
632                 btstack_packet_handler_t packet_handler;
633                 switch (hfp_connection->local_role){
634                     case HFP_ROLE_AG:
635                         packet_handler = hfp_ag_rfcomm_packet_handler;
636                         break;
637                     case HFP_ROLE_HF:
638                         packet_handler = hfp_hf_rfcomm_packet_handler;
639                         break;
640                     default:
641                         btstack_assert(false);
642                         return;
643                 }
644 
645                 rfcomm_create_channel(packet_handler, hfp_connection->remote_addr, hfp_connection->rfcomm_channel_nr, NULL);
646 
647             } else {
648                 hfp_connection->state = HFP_IDLE;
649                 uint8_t status = sdp_event_query_complete_get_status(packet);
650                 if (status == ERROR_CODE_SUCCESS){
651                     // report service not found
652                     status = SDP_SERVICE_NOT_FOUND;
653                 }
654                 hfp_emit_slc_connection_event(hfp_connection, status, HCI_CON_HANDLE_INVALID, hfp_connection->remote_addr);
655                 log_info("rfcomm service not found, status 0x%02x", status);
656             }
657 
658             // register the SDP Query request to check if there is another connection waiting for the query
659             // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
660             (void) sdp_client_register_query_callback(&hfp_handle_sdp_client_query_request);
661             break;
662         default:
663             break;
664     }
665 }
666 
667 // returns 0 if unexpected error or no other link options remained, otherwise 1
668 static int hfp_handle_failed_sco_connection(uint8_t status){
669 
670     if (!sco_establishment_active){
671         log_info("(e)SCO Connection failed but not started by us");
672         return 0;
673     }
674 
675     log_info("(e)SCO Connection failed 0x%02x", status);
676     switch (status){
677         case ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE:
678         case ERROR_CODE_UNSPECIFIED_ERROR:
679         case ERROR_CODE_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES:
680             break;
681         default:
682             return 0;
683     }
684 
685     // note: eSCO_S4 supported flag not available, but it's only relevant for highest CVSD link setting (and the current failed)
686     hfp_link_settings_t next_setting = hfp_next_link_setting_for_connection(sco_establishment_active->link_setting, sco_establishment_active, false);
687 
688     // handle no valid setting found
689     if (next_setting == HFP_LINK_SETTINGS_NONE) {
690         if (sco_establishment_active->negotiated_codec == HFP_CODEC_MSBC){
691             log_info("T2/T1 failed, fallback to CVSD - D1");
692             sco_establishment_active->negotiated_codec = HFP_CODEC_CVSD;
693             sco_establishment_active->sco_for_msbc_failed = 1;
694             sco_establishment_active->command = HFP_CMD_AG_SEND_COMMON_CODEC;
695             sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1;
696         } else {
697             // no other options
698             return 0;
699         }
700     }
701 
702     log_info("e)SCO Connection: try new link_setting %d", next_setting);
703     sco_establishment_active->establish_audio_connection = 1;
704     sco_establishment_active->link_setting = next_setting;
705     sco_establishment_active = NULL;
706     return 1;
707 }
708 
709 
710 void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){
711     UNUSED(packet_type);
712     UNUSED(channel);    // ok: no channel
713     UNUSED(size);
714 
715     bd_addr_t event_addr;
716     hci_con_handle_t handle;
717     hfp_connection_t * hfp_connection = NULL;
718     uint8_t status;
719 
720     log_debug("HFP HCI event handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
721 
722     switch (hci_event_packet_get_type(packet)) {
723 
724         case HCI_EVENT_CONNECTION_REQUEST:
725             switch(hci_event_connection_request_get_link_type(packet)){
726                 case 0: //  SCO
727                 case 2: // eSCO
728                     hci_event_connection_request_get_bd_addr(packet, event_addr);
729                     hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
730                     if (!hfp_connection) break;
731                     if (hci_event_connection_request_get_link_type(packet) == 2){
732                         hfp_connection->accept_sco = 2;
733                     } else {
734                         hfp_connection->accept_sco = 1;
735                     }
736 #ifdef ENABLE_CC256X_ASSISTED_HFP
737                     hfp_cc256x_prepare_for_sco(hfp_connection);
738 #endif
739 #ifdef ENABLE_BCM_PCM_WBS
740                     hfp_bcm_prepare_for_sco(hfp_connection);
741 #endif
742                     log_info("accept sco %u\n", hfp_connection->accept_sco);
743                     sco_establishment_active = hfp_connection;
744                     break;
745                 default:
746                     break;
747             }
748             break;
749 
750         case HCI_EVENT_COMMAND_STATUS:
751             if (hci_event_command_status_get_command_opcode(packet) == hci_setup_synchronous_connection.opcode) {
752                 if (sco_establishment_active == NULL) break;
753                 status = hci_event_command_status_get_status(packet);
754                 if (status == ERROR_CODE_SUCCESS) break;
755 
756                 hfp_connection = sco_establishment_active;
757                 if (hfp_handle_failed_sco_connection(status)) break;
758                 hfp_connection->establish_audio_connection = 0;
759                 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
760                 hfp_emit_sco_event(hfp_connection, status, 0, hfp_connection->remote_addr, hfp_connection->negotiated_codec);
761             }
762             break;
763 
764         case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
765             if (sco_establishment_active == NULL) break;
766             hci_event_synchronous_connection_complete_get_bd_addr(packet, event_addr);
767             hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
768             if (!hfp_connection) {
769                 log_error("HFP: connection does not exist for remote with addr %s.", bd_addr_to_str(event_addr));
770                 return;
771             }
772 
773             status = hci_event_synchronous_connection_complete_get_status(packet);
774             if (status != ERROR_CODE_SUCCESS){
775                 hfp_connection->accept_sco = 0;
776                 if (hfp_handle_failed_sco_connection(status)) break;
777 
778                 hfp_connection->establish_audio_connection = 0;
779                 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
780                 hfp_emit_sco_event(hfp_connection, status, 0, event_addr, hfp_connection->negotiated_codec);
781                 break;
782             }
783 
784             uint16_t sco_handle = hci_event_synchronous_connection_complete_get_handle(packet);
785             uint8_t  link_type = hci_event_synchronous_connection_complete_get_link_type(packet);
786             uint8_t  transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet);  // measured in slots
787             uint8_t  retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots
788             uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes
789             uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes
790 
791             switch (link_type){
792                 case 0x00:
793                     log_info("SCO Connection established.");
794                     if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
795                     if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);
796                     if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length);
797                     if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length);
798                     break;
799                 case 0x02:
800                     log_info("eSCO Connection established. \n");
801                     break;
802                 default:
803                     log_error("(e)SCO reserved link_type 0x%2x", link_type);
804                     break;
805             }
806 
807             log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, "
808                  " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle,
809                  bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length,
810                  hci_event_synchronous_connection_complete_get_air_mode(packet));
811 
812             if (hfp_connection->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
813                 log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN");
814                 hfp_connection->state = HFP_W2_DISCONNECT_SCO;
815                 break;
816             }
817             hfp_connection->sco_handle = sco_handle;
818             hfp_connection->establish_audio_connection = 0;
819             hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
820             hfp_emit_sco_event(hfp_connection, status, sco_handle, event_addr, hfp_connection->negotiated_codec);
821             break;
822         }
823 
824         case HCI_EVENT_DISCONNECTION_COMPLETE:
825             handle = little_endian_read_16(packet,3);
826             hfp_connection = get_hfp_connection_context_for_sco_handle(handle, local_role);
827 
828             if (!hfp_connection) break;
829 
830 #ifdef ENABLE_CC256X_ASSISTED_HFP
831             hfp_connection->cc256x_send_wbs_disassociate = true;
832 #endif
833 #ifdef ENABLE_BCM_PCM_WBS
834             hfp_connection->bcm_send_disable_wbs = true;
835 #endif
836             hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID;
837             hfp_connection->release_audio_connection = 0;
838 
839             if (hfp_connection->state == HFP_W4_SCO_DISCONNECTED_TO_SHUTDOWN){
840                 // RFCOMM already closed -> remote power off
841 #if defined(ENABLE_CC256X_ASSISTED_HFP) || defined (ENABLE_BCM_PCM_WBS)
842                 hfp_connection->state = HFP_W4_WBS_SHUTDOWN;
843 #else
844                 hfp_finalize_connection_context(hfp_connection);
845 #endif
846                 break;
847             }
848 
849             hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
850             hfp_emit_audio_connection_released(hfp_connection, handle);
851 
852             if (hfp_connection->release_slc_connection){
853                 hfp_connection->release_slc_connection = 0;
854                 log_info("SCO disconnected, w2 disconnect RFCOMM\n");
855                 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
856             }
857             break;
858 
859         default:
860             break;
861     }
862 }
863 
864 
865 void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){
866     UNUSED(packet_type);
867     UNUSED(channel);    // ok: no channel
868     UNUSED(size);
869 
870     bd_addr_t event_addr;
871     uint16_t rfcomm_cid;
872     hfp_connection_t * hfp_connection = NULL;
873     uint8_t status;
874 
875     log_debug("HFP packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
876 
877     switch (hci_event_packet_get_type(packet)) {
878 
879         case RFCOMM_EVENT_INCOMING_CONNECTION:
880             // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
881             rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr);
882             hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr, local_role);
883             if (!hfp_connection){
884                 log_info("hfp: no memory to accept incoming connection - decline");
885                 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet));
886                 return;
887             }
888             if (hfp_connection->state != HFP_IDLE) {
889                 log_error("hfp: incoming connection but not idle, reject");
890                 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet));
891                 return;
892             }
893 
894             hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
895             hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
896             rfcomm_accept_connection(hfp_connection->rfcomm_cid);
897             break;
898 
899         case RFCOMM_EVENT_CHANNEL_OPENED:
900             // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
901 
902             rfcomm_event_channel_opened_get_bd_addr(packet, event_addr);
903             status = rfcomm_event_channel_opened_get_status(packet);
904 
905             hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
906             if (!hfp_connection || (hfp_connection->state != HFP_W4_RFCOMM_CONNECTED)) return;
907 
908             if (status) {
909                 hfp_emit_slc_connection_event(hfp_connection, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr);
910                 hfp_finalize_connection_context(hfp_connection);
911             } else {
912                 hfp_connection->acl_handle = rfcomm_event_channel_opened_get_con_handle(packet);
913                 hfp_connection->rfcomm_cid = rfcomm_event_channel_opened_get_rfcomm_cid(packet);
914                 bd_addr_copy(hfp_connection->remote_addr, event_addr);
915 
916                 switch (hfp_connection->state){
917                     case HFP_W4_RFCOMM_CONNECTED:
918                         hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
919                         break;
920                     case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
921                         hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
922                         break;
923                     default:
924                         break;
925                 }
926                 rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
927             }
928             break;
929 
930         case RFCOMM_EVENT_CHANNEL_CLOSED:
931             rfcomm_cid = little_endian_read_16(packet,2);
932             hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
933             if (!hfp_connection) break;
934             if (hfp_connection->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
935                 hfp_connection->state = HFP_IDLE;
936                 hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid, local_role);
937                 break;
938             }
939             if ( hfp_connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED){
940                 // service connection was released, this implicitly releases audio connection as well
941                 hfp_connection->release_audio_connection = 0;
942                 hci_con_handle_t sco_handle = hfp_connection->sco_handle;
943                 gap_disconnect(hfp_connection->sco_handle);
944                 hfp_connection->state = HFP_W4_SCO_DISCONNECTED_TO_SHUTDOWN;
945                 hfp_emit_audio_connection_released(hfp_connection, sco_handle);
946                 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
947             } else {
948                 // regular case
949                 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
950                 hfp_finalize_connection_context(hfp_connection);
951             }
952             break;
953 
954         default:
955             break;
956     }
957 }
958 // translates command string into hfp_command_t CMD
959 
960 typedef struct {
961     const char * command;
962     hfp_command_t command_id;
963 } hfp_command_entry_t;
964 
965 static hfp_command_entry_t hfp_ag_commmand_table[] = {
966     { "AT+BAC=",   HFP_CMD_AVAILABLE_CODECS },
967     { "AT+BCC",    HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP },
968     { "AT+BCS=",   HFP_CMD_HF_CONFIRMED_CODEC },
969     { "AT+BIA=",   HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, }, // +BIA:<enabled>,,<enabled>,,,<enabled>
970     { "AT+BIEV=",  HFP_CMD_HF_INDICATOR_STATUS },
971     { "AT+BIND=",  HFP_CMD_LIST_GENERIC_STATUS_INDICATORS },
972     { "AT+BIND=?", HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS },
973     { "AT+BIND?",  HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE },
974     { "AT+BINP",   HFP_CMD_HF_REQUEST_PHONE_NUMBER },
975     { "AT+BLDN",   HFP_CMD_REDIAL_LAST_NUMBER },
976     { "AT+BRSF=",  HFP_CMD_SUPPORTED_FEATURES },
977     { "AT+BTRH=",  HFP_CMD_RESPONSE_AND_HOLD_COMMAND },
978     { "AT+BTRH?",  HFP_CMD_RESPONSE_AND_HOLD_QUERY },
979     { "AT+BVRA=",  HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION },
980     { "AT+CCWA=",  HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION},
981     { "AT+CHLD=",  HFP_CMD_CALL_HOLD },
982     { "AT+CHLD=?", HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES },
983     { "AT+CHUP",   HFP_CMD_HANG_UP_CALL },
984     { "AT+CIND=?", HFP_CMD_RETRIEVE_AG_INDICATORS },
985     { "AT+CIND?",  HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS },
986     { "AT+CLCC",   HFP_CMD_LIST_CURRENT_CALLS },
987     { "AT+CLIP=",  HFP_CMD_ENABLE_CLIP},
988     { "AT+CMEE=",  HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR},
989     { "AT+CMER=",  HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE },
990     { "AT+CNUM",   HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION },
991     { "AT+COPS=",  HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT },
992     { "AT+COPS?",  HFP_CMD_QUERY_OPERATOR_SELECTION_NAME },
993     { "AT+NREC=",  HFP_CMD_TURN_OFF_EC_AND_NR, },
994     { "AT+VGM=",   HFP_CMD_SET_MICROPHONE_GAIN },
995     { "AT+VGS=",   HFP_CMD_SET_SPEAKER_GAIN },
996     { "AT+VTS:",   HFP_CMD_TRANSMIT_DTMF_CODES },
997     { "ATA",       HFP_CMD_CALL_ANSWERED },
998 };
999 
1000 static hfp_command_entry_t hfp_hf_commmand_table[] = {
1001     { "+BCS:",  HFP_CMD_AG_SUGGESTED_CODEC },
1002     { "+BIND:", HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS },
1003     { "+BINP",  HFP_CMD_AG_SENT_PHONE_NUMBER },
1004     { "+BRSF:", HFP_CMD_SUPPORTED_FEATURES },
1005     { "+BSIR:", HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING },
1006     { "+BTRH:", HFP_CMD_RESPONSE_AND_HOLD_STATUS },
1007     { "+BVRA:", HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION },
1008     { "+CCWA:", HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE, },
1009     { "+CHLD:", HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES },
1010     { "+CIEV:", HFP_CMD_TRANSFER_AG_INDICATOR_STATUS},
1011     { "+CIND:", HFP_CMD_RETRIEVE_AG_INDICATORS_GENERIC },
1012     { "+CLCC:", HFP_CMD_LIST_CURRENT_CALLS },
1013     { "+CLIP:", HFP_CMD_AG_SENT_CLIP_INFORMATION },
1014     { "+CME ERROR:", HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR },
1015     { "+CNUM:", HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION},
1016     { "+COPS:", HFP_CMD_QUERY_OPERATOR_SELECTION_NAME },
1017     { "+VGM:",  HFP_CMD_SET_MICROPHONE_GAIN },
1018     { "+VGS:",  HFP_CMD_SET_SPEAKER_GAIN},
1019     { "ERROR",  HFP_CMD_ERROR},
1020     { "NOP",    HFP_CMD_NONE}, // dummy command used by unit tests
1021     { "OK",     HFP_CMD_OK },
1022     { "RING",   HFP_CMD_RING },
1023 };
1024 
1025 static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){
1026 
1027     // table lookup based on role
1028     uint16_t num_entries;
1029     hfp_command_entry_t * table;
1030     if (isHandsFree == 0){
1031         table = hfp_ag_commmand_table;
1032         num_entries = sizeof(hfp_ag_commmand_table) / sizeof(hfp_command_entry_t);
1033     } else {
1034         table = hfp_hf_commmand_table;
1035         num_entries = sizeof(hfp_hf_commmand_table) / sizeof(hfp_command_entry_t);
1036     }
1037     // binary search
1038     uint16_t left = 0;
1039     uint16_t right = num_entries - 1;
1040     while (left <= right){
1041         uint16_t middle = left + (right - left) / 2;
1042         hfp_command_entry_t *entry = &table[middle];
1043         int match = strcmp(line_buffer, entry->command);
1044         if (match < 0){
1045             // search term is lower than middle element
1046             if (right == 0) break;
1047             right = middle - 1;
1048         } else if (match == 0){
1049             return entry->command_id;
1050         } else {
1051             // search term is higher than middle element
1052             left = middle + 1;
1053         }
1054     }
1055 
1056     // note: if parser in CMD_HEADER state would treats digits and maybe '+' as separator, match on "ATD" would work.
1057     // note: phone number is currently expected in line_buffer[3..]
1058     // prefix match on 'ATD', AG only
1059     if ((isHandsFree == 0) && (strncmp(line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0)){
1060         return HFP_CMD_CALL_PHONE_NUMBER;
1061     }
1062 
1063     // Valid looking, but unknown commands/responses
1064     if ((isHandsFree == 0) && (strncmp(line_buffer, "AT+", 3) == 0)){
1065         return HFP_CMD_UNKNOWN;
1066     }
1067 
1068     if ((isHandsFree != 0) && (strncmp(line_buffer, "+", 1) == 0)){
1069         return HFP_CMD_UNKNOWN;
1070     }
1071 
1072     return HFP_CMD_NONE;
1073 }
1074 
1075 static void hfp_parser_store_byte(hfp_connection_t * hfp_connection, uint8_t byte){
1076     if ((hfp_connection->line_size + 1 ) >= HFP_MAX_INDICATOR_DESC_SIZE) return;
1077     hfp_connection->line_buffer[hfp_connection->line_size++] = byte;
1078     hfp_connection->line_buffer[hfp_connection->line_size] = 0;
1079 }
1080 static int hfp_parser_is_buffer_empty(hfp_connection_t * hfp_connection){
1081     return hfp_connection->line_size == 0;
1082 }
1083 
1084 static int hfp_parser_is_end_of_line(uint8_t byte){
1085     return (byte == '\n') || (byte == '\r');
1086 }
1087 
1088 static void hfp_parser_reset_line_buffer(hfp_connection_t *hfp_connection) {
1089     hfp_connection->line_size = 0;
1090 }
1091 
1092 static void hfp_parser_store_if_token(hfp_connection_t * hfp_connection, uint8_t byte){
1093     switch (byte){
1094         case ',':
1095 		case '-':
1096         case ';':
1097         case '(':
1098         case ')':
1099         case '\n':
1100         case '\r':
1101             break;
1102         default:
1103             hfp_parser_store_byte(hfp_connection, byte);
1104             break;
1105     }
1106 }
1107 
1108 static bool hfp_parser_is_separator( uint8_t byte){
1109     switch (byte){
1110         case ',':
1111 		case '-':
1112         case ';':
1113         case '\n':
1114         case '\r':
1115             return true;
1116         default:
1117             return false;
1118     }
1119 }
1120 
1121 static bool hfp_parse_byte(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){
1122 
1123     // handle doubles quotes
1124     if (byte == '"'){
1125         hfp_connection->parser_quoted = !hfp_connection->parser_quoted;
1126         return true;
1127     }
1128     if (hfp_connection->parser_quoted) {
1129         hfp_parser_store_byte(hfp_connection, byte);
1130         return true;
1131     }
1132 
1133     // ignore spaces outside command or double quotes (required e.g. for '+CME ERROR:..") command
1134     if ((byte == ' ') && (hfp_connection->parser_state != HFP_PARSER_CMD_HEADER)) return true;
1135 
1136     bool processed = true;
1137 
1138     switch (hfp_connection->parser_state) {
1139         case HFP_PARSER_CMD_HEADER:
1140             switch (byte) {
1141                 case '\n':
1142                 case '\r':
1143                 case ';':
1144                     // ignore separator
1145                     break;
1146                 case ':':
1147                 case '?':
1148                     // store separator
1149                     hfp_parser_store_byte(hfp_connection, byte);
1150                     break;
1151                 case '=':
1152                     // equal sign: remember and wait for next char to decided between '=?' and '=\?'
1153                     hfp_connection->found_equal_sign = true;
1154                     hfp_parser_store_byte(hfp_connection, byte);
1155                     return true;
1156                 default:
1157                     // store if not lookahead
1158                     if (!hfp_connection->found_equal_sign) {
1159                         hfp_parser_store_byte(hfp_connection, byte);
1160                         return true;
1161                     }
1162                     // mark as lookahead
1163                     processed = false;
1164                     break;
1165             }
1166 
1167             // ignore empty tokens
1168             if (hfp_parser_is_buffer_empty(hfp_connection)) return true;
1169 
1170             // parse
1171             hfp_connection->command = parse_command((char *)hfp_connection->line_buffer, isHandsFree);
1172 
1173             // pick +CIND version based on connection state: descriptions during SLC vs. states later
1174             if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS_GENERIC){
1175                 switch(hfp_connection->state){
1176                     case HFP_W4_RETRIEVE_INDICATORS_STATUS:
1177                         hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS;
1178                         break;
1179                     case HFP_W4_RETRIEVE_INDICATORS:
1180                         hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS;
1181                         break;
1182                     default:
1183                         hfp_connection->command = HFP_CMD_UNKNOWN;
1184                         break;
1185                 }
1186             }
1187 
1188             log_info("command string '%s', handsfree %u -> cmd id %u", (char *)hfp_connection->line_buffer, isHandsFree, hfp_connection->command);
1189 
1190             // next state
1191             hfp_connection->found_equal_sign = false;
1192             hfp_parser_reset_line_buffer(hfp_connection);
1193             hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE;
1194 
1195             return processed;
1196 
1197         case HFP_PARSER_CMD_SEQUENCE:
1198             // handle empty fields
1199             if ((byte == ',' ) && (hfp_connection->line_size == 0)){
1200                 hfp_connection->line_buffer[0] = 0;
1201                 hfp_connection->ignore_value = 1;
1202                 parse_sequence(hfp_connection);
1203                 return true;
1204             }
1205 
1206             hfp_parser_store_if_token(hfp_connection, byte);
1207             if (!hfp_parser_is_separator(byte)) return true;
1208 
1209             // ignore empty tokens
1210             if (hfp_parser_is_buffer_empty(hfp_connection) && (hfp_connection->ignore_value == 0)) return true;
1211 
1212             parse_sequence(hfp_connection);
1213 
1214             hfp_parser_reset_line_buffer(hfp_connection);
1215 
1216             switch (hfp_connection->command){
1217                 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1218                 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1219                 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1220                 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1221                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1222                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1223                 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1224                 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1225                 case HFP_CMD_HF_INDICATOR_STATUS:
1226                     hfp_connection->parser_state = HFP_PARSER_SECOND_ITEM;
1227                     break;
1228                 default:
1229                     break;
1230             }
1231             return true;
1232 
1233         case HFP_PARSER_SECOND_ITEM:
1234 
1235             hfp_parser_store_if_token(hfp_connection, byte);
1236             if (!hfp_parser_is_separator(byte)) return true;
1237 
1238             switch (hfp_connection->command){
1239                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1240                     log_info("format %s, ", hfp_connection->line_buffer);
1241                     hfp_connection->network_operator.format =  btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1242                     break;
1243                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1244                     log_info("format %s \n", hfp_connection->line_buffer);
1245                     hfp_connection->network_operator.format =  btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1246                     break;
1247                 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
1248                 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
1249                 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1250                     hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].state = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1251                     break;
1252                 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1253                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1254                     log_info("%d \n", hfp_connection->ag_indicators[hfp_connection->parser_item_index].status);
1255                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].status_changed = 1;
1256                     break;
1257                 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1258                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].min_range = btstack_atoi((char *)hfp_connection->line_buffer);
1259                     log_info("%s, ", hfp_connection->line_buffer);
1260                     break;
1261                 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1262                 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1263                 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1264                     hfp_connection->bnip_type = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1265                     break;
1266                 case HFP_CMD_HF_INDICATOR_STATUS:
1267                     hfp_connection->parser_indicator_value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1268                     break;
1269                 default:
1270                     break;
1271             }
1272 
1273             hfp_parser_reset_line_buffer(hfp_connection);
1274 
1275             hfp_connection->parser_state = HFP_PARSER_THIRD_ITEM;
1276 
1277             return true;
1278 
1279         case HFP_PARSER_THIRD_ITEM:
1280 
1281             hfp_parser_store_if_token(hfp_connection, byte);
1282             if (!hfp_parser_is_separator(byte)) return true;
1283 
1284             switch (hfp_connection->command){
1285                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1286                     strncpy(hfp_connection->network_operator.name, (char *)hfp_connection->line_buffer, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE);
1287                     hfp_connection->network_operator.name[HFP_MAX_NETWORK_OPERATOR_NAME_SIZE - 1] = 0;
1288                     log_info("name %s\n", hfp_connection->line_buffer);
1289                     break;
1290                 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1291                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].max_range = btstack_atoi((char *)hfp_connection->line_buffer);
1292                     hfp_next_indicators_index(hfp_connection);
1293                     hfp_connection->ag_indicators_nr = hfp_connection->parser_item_index;
1294                     log_info("%s)\n", hfp_connection->line_buffer);
1295                     break;
1296                 default:
1297                     break;
1298             }
1299 
1300             hfp_parser_reset_line_buffer(hfp_connection);
1301 
1302             if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS){
1303                 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE;
1304             } else {
1305                 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
1306             }
1307             return true;
1308 
1309         default:
1310             btstack_assert(false);
1311             return true;
1312     }
1313 }
1314 
1315 void hfp_parse(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){
1316     bool processed = false;
1317     while (!processed){
1318         processed = hfp_parse_byte(hfp_connection, byte, isHandsFree);
1319     }
1320     // reset parser state on end-of-line
1321     if (hfp_parser_is_end_of_line(byte)){
1322         hfp_connection->parser_item_index = 0;
1323         hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
1324     }
1325 }
1326 
1327 static void parse_sequence(hfp_connection_t * hfp_connection){
1328     int value;
1329     switch (hfp_connection->command){
1330         case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS:
1331             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1332             int i;
1333             switch (hfp_connection->parser_item_index){
1334                 case 0:
1335                     for (i=0;i<hfp_connection->generic_status_indicators_nr;i++){
1336                         if (hfp_connection->generic_status_indicators[i].uuid == value){
1337                             hfp_connection->parser_indicator_index = i;
1338                             break;
1339                         }
1340                     }
1341                     break;
1342                 case 1:
1343                     if (hfp_connection->parser_indicator_index <0) break;
1344                     hfp_connection->generic_status_indicators[hfp_connection->parser_indicator_index].state = value;
1345                     log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n",
1346                      hfp_connection->parser_item_index, value);
1347                     break;
1348                 default:
1349                     break;
1350             }
1351             hfp_next_indicators_index(hfp_connection);
1352             break;
1353 
1354         case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
1355             switch(hfp_connection->parser_item_index){
1356                 case 0:
1357                     strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number));
1358                     hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0;
1359                     break;
1360                 case 1:
1361                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1362                     hfp_connection->bnip_type = value;
1363                     break;
1364                 default:
1365                     break;
1366             }
1367             // index > 2 are ignored in switch above
1368             hfp_connection->parser_item_index++;
1369             break;
1370         case HFP_CMD_LIST_CURRENT_CALLS:
1371             switch(hfp_connection->parser_item_index){
1372                 case 0:
1373                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1374                     hfp_connection->clcc_idx = value;
1375                     break;
1376                 case 1:
1377                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1378                     hfp_connection->clcc_dir = value;
1379                     break;
1380                 case 2:
1381                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1382                     hfp_connection->clcc_status = value;
1383                     break;
1384                 case 3:
1385                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1386                     hfp_connection->clcc_mode = value;
1387                     break;
1388                 case 4:
1389                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1390                     hfp_connection->clcc_mpty = value;
1391                     break;
1392                 case 5:
1393                     strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number));
1394                     hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0;
1395                     break;
1396                 case 6:
1397                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1398                     hfp_connection->bnip_type = value;
1399                     break;
1400                 default:
1401                     break;
1402             }
1403             // index > 6 are ignored in switch above
1404             hfp_connection->parser_item_index++;
1405             break;
1406         case HFP_CMD_SET_MICROPHONE_GAIN:
1407             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1408             hfp_connection->microphone_gain = value;
1409             log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value);
1410             break;
1411         case HFP_CMD_SET_SPEAKER_GAIN:
1412             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1413             hfp_connection->speaker_gain = value;
1414             log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value);
1415             break;
1416         case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION:
1417             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1418             hfp_connection->ag_activate_voice_recognition = value;
1419             log_info("hfp parse HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION %d\n", value);
1420             break;
1421         case HFP_CMD_TURN_OFF_EC_AND_NR:
1422             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1423             hfp_connection->ag_echo_and_noise_reduction = value;
1424             log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value);
1425             break;
1426         case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING:
1427             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1428             hfp_connection->remote_supported_features = store_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value);
1429             log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value);
1430             break;
1431         case HFP_CMD_HF_CONFIRMED_CODEC:
1432             hfp_connection->codec_confirmed = btstack_atoi((char*)hfp_connection->line_buffer);
1433             log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", hfp_connection->codec_confirmed);
1434             break;
1435         case HFP_CMD_AG_SUGGESTED_CODEC:
1436             hfp_connection->suggested_codec = btstack_atoi((char*)hfp_connection->line_buffer);
1437             log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", hfp_connection->suggested_codec);
1438             break;
1439         case HFP_CMD_SUPPORTED_FEATURES:
1440             hfp_connection->remote_supported_features = btstack_atoi((char*)hfp_connection->line_buffer);
1441             log_info("Parsed supported feature %d\n", (int) hfp_connection->remote_supported_features);
1442             break;
1443         case HFP_CMD_AVAILABLE_CODECS:
1444             log_info("Parsed codec %s\n", hfp_connection->line_buffer);
1445             hfp_connection->remote_codecs[hfp_connection->parser_item_index] = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer);
1446             hfp_next_codec_index(hfp_connection);
1447             hfp_connection->remote_codecs_nr = hfp_connection->parser_item_index;
1448             break;
1449         case HFP_CMD_RETRIEVE_AG_INDICATORS:
1450             strncpy((char *)hfp_connection->ag_indicators[hfp_connection->parser_item_index].name,  (char *)hfp_connection->line_buffer, HFP_MAX_INDICATOR_DESC_SIZE);
1451             hfp_connection->ag_indicators[hfp_connection->parser_item_index].name[HFP_MAX_INDICATOR_DESC_SIZE-1] = 0;
1452             hfp_connection->ag_indicators[hfp_connection->parser_item_index].index = hfp_connection->parser_item_index+1;
1453             log_info("Indicator %d: %s (", hfp_connection->ag_indicators_nr+1, hfp_connection->line_buffer);
1454             break;
1455         case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS:
1456             log_info("Parsed Indicator %d with status: %s\n", hfp_connection->parser_item_index+1, hfp_connection->line_buffer);
1457             hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = btstack_atoi((char *) hfp_connection->line_buffer);
1458             hfp_next_indicators_index(hfp_connection);
1459             break;
1460         case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
1461             hfp_next_indicators_index(hfp_connection);
1462             if (hfp_connection->parser_item_index != 4) break;
1463             log_info("Parsed Enable indicators: %s\n", hfp_connection->line_buffer);
1464             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1465             hfp_connection->enable_status_update_for_ag_indicators = (uint8_t) value;
1466             break;
1467         case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
1468             log_info("Parsed Support call hold: %s\n", hfp_connection->line_buffer);
1469             if (hfp_connection->line_size > 2 ) break;
1470             memcpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name, (char *)hfp_connection->line_buffer, HFP_CALL_SERVICE_SIZE-1);
1471             hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name[HFP_CALL_SERVICE_SIZE - 1] = 0;
1472             hfp_next_remote_call_services_index(hfp_connection);
1473             break;
1474         case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
1475         case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
1476             log_info("Parsed Generic status indicator: %s\n", hfp_connection->line_buffer);
1477             hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].uuid = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer);
1478             hfp_next_indicators_index(hfp_connection);
1479             hfp_connection->generic_status_indicators_nr = hfp_connection->parser_item_index;
1480             break;
1481         case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1482             // HF parses inital AG gen. ind. state
1483             log_info("Parsed List generic status indicator %s state: ", hfp_connection->line_buffer);
1484             hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection);
1485             break;
1486         case HFP_CMD_HF_INDICATOR_STATUS:
1487             hfp_connection->parser_indicator_index = hfp_parse_indicator_index(hfp_connection);
1488             log_info("Parsed HF indicator index %u", hfp_connection->parser_indicator_index);
1489             break;
1490         case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:
1491             // AG parses new gen. ind. state
1492             if (hfp_connection->ignore_value){
1493                 hfp_connection->ignore_value = 0;
1494                 log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", hfp_connection->parser_item_index,
1495                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled);
1496             }
1497             else if (hfp_connection->ag_indicators[hfp_connection->parser_item_index].mandatory){
1498                 log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n",
1499                     hfp_connection->parser_item_index, hfp_connection->ag_indicators[hfp_connection->parser_item_index].name);
1500             } else {
1501                 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1502                 hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled = value;
1503                 log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", hfp_connection->parser_item_index,
1504                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, value);
1505             }
1506             hfp_next_indicators_index(hfp_connection);
1507             break;
1508         case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1509             // indicators are indexed starting with 1
1510             hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection);
1511             log_info("Parsed status of the AG indicator %d, status ", hfp_connection->parser_item_index);
1512             break;
1513         case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1514             hfp_connection->network_operator.mode = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1515             log_info("Parsed network operator mode: %d, ", hfp_connection->network_operator.mode);
1516             break;
1517         case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1518             if (hfp_connection->line_buffer[0] == '3'){
1519                 log_info("Parsed Set network operator format : %s, ", hfp_connection->line_buffer);
1520                 break;
1521             }
1522             // TODO emit ERROR, wrong format
1523             log_info("ERROR Set network operator format: index %s not supported\n", hfp_connection->line_buffer);
1524             break;
1525         case HFP_CMD_ERROR:
1526             break;
1527         case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
1528             hfp_connection->extended_audio_gateway_error = 1;
1529             hfp_connection->extended_audio_gateway_error_value = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1530             break;
1531         case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR:
1532             hfp_connection->enable_extended_audio_gateway_error_report = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1533             hfp_connection->ok_pending = 1;
1534             hfp_connection->extended_audio_gateway_error = 0;
1535             break;
1536         case HFP_CMD_AG_SENT_PHONE_NUMBER:
1537         case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1538         case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1539             strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number));
1540             hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0;
1541             break;
1542         case HFP_CMD_CALL_HOLD:
1543             hfp_connection->ag_call_hold_action = hfp_connection->line_buffer[0] - '0';
1544             if (hfp_connection->line_buffer[1] != '\0'){
1545                 hfp_connection->call_index = btstack_atoi((char *)&hfp_connection->line_buffer[1]);
1546             }
1547             break;
1548         case HFP_CMD_RESPONSE_AND_HOLD_COMMAND:
1549             hfp_connection->ag_response_and_hold_action = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1550             break;
1551         case HFP_CMD_TRANSMIT_DTMF_CODES:
1552             hfp_connection->ag_dtmf_code = hfp_connection->line_buffer[0];
1553             break;
1554         case HFP_CMD_ENABLE_CLIP:
1555             hfp_connection->clip_enabled = hfp_connection->line_buffer[0] != '0';
1556             break;
1557         case HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION:
1558             hfp_connection->call_waiting_notification_enabled = hfp_connection->line_buffer[0] != '0';
1559             break;
1560         default:
1561             break;
1562     }
1563 }
1564 
1565 static void hfp_handle_start_sdp_client_query(void * context){
1566     UNUSED(context);
1567 
1568     btstack_linked_list_iterator_t it;
1569     btstack_linked_list_iterator_init(&it, &hfp_connections);
1570     while (btstack_linked_list_iterator_has_next(&it)){
1571         hfp_connection_t * connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
1572 
1573         if (connection->state != HFP_W2_SEND_SDP_QUERY) continue;
1574 
1575         connection->state = HFP_W4_SDP_QUERY_COMPLETE;
1576         sdp_query_context.local_role = connection->local_role;
1577         (void)memcpy(sdp_query_context.remote_address, connection->remote_addr, 6);
1578         sdp_client_query_rfcomm_channel_and_name_for_service_class_uuid(&handle_query_rfcomm_event, connection->remote_addr, connection->service_uuid);
1579         return;
1580     }
1581 }
1582 
1583 void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid, hfp_role_t local_role){
1584     hfp_connection_t * hfp_connection = provide_hfp_connection_context_for_bd_addr(bd_addr, local_role);
1585     log_info("hfp_connect %s, hfp_connection %p", bd_addr_to_str(bd_addr), hfp_connection);
1586 
1587     if (!hfp_connection) {
1588         log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr));
1589         return;
1590     }
1591     switch (hfp_connection->state){
1592         case HFP_W2_DISCONNECT_RFCOMM:
1593             hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
1594             return;
1595         case HFP_W4_RFCOMM_DISCONNECTED:
1596             hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART;
1597             return;
1598         case HFP_IDLE:
1599             (void)memcpy(hfp_connection->remote_addr, bd_addr, 6);
1600             hfp_connection->state = HFP_W2_SEND_SDP_QUERY;
1601             hfp_connection->service_uuid = service_uuid;
1602 
1603             hfp_handle_sdp_client_query_request.callback = &hfp_handle_start_sdp_client_query;
1604             // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
1605             (void) sdp_client_register_query_callback(&hfp_handle_sdp_client_query_request);
1606             break;
1607         default:
1608             break;
1609     }
1610 }
1611 
1612 void hfp_release_service_level_connection(hfp_connection_t * hfp_connection){
1613     if (!hfp_connection) return;
1614     hfp_release_audio_connection(hfp_connection);
1615 
1616     if (hfp_connection->state < HFP_W4_RFCOMM_CONNECTED){
1617         hfp_connection->state = HFP_IDLE;
1618         return;
1619     }
1620 
1621     if (hfp_connection->state == HFP_W4_RFCOMM_CONNECTED){
1622         hfp_connection->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
1623         return;
1624     }
1625 
1626     if (hfp_connection->state < HFP_W4_SCO_CONNECTED){
1627         hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
1628         return;
1629     }
1630 
1631     if (hfp_connection->state < HFP_W4_SCO_DISCONNECTED){
1632         hfp_connection->state = HFP_W2_DISCONNECT_SCO;
1633         return;
1634     }
1635 
1636     // HFP_W4_SCO_DISCONNECTED or later
1637     hfp_connection->release_slc_connection = 1;
1638 }
1639 
1640 void hfp_release_audio_connection(hfp_connection_t * hfp_connection){
1641     if (!hfp_connection) return;
1642     if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO) return;
1643     hfp_connection->release_audio_connection = 1;
1644 }
1645 
1646 static const struct link_settings {
1647     const uint16_t max_latency;
1648     const uint8_t  retransmission_effort;
1649     const uint16_t packet_types;
1650     const bool     eSCO;
1651     const uint8_t  codec;
1652 } hfp_link_settings [] = {
1653     { 0xffff, 0xff, SCO_PACKET_TYPES_HV1,  false, HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_D0
1654     { 0xffff, 0xff, SCO_PACKET_TYPES_HV3,  false, HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_D1
1655     { 0x0007, 0x01, SCO_PACKET_TYPES_EV3,  true,  HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_S1
1656     { 0x0007, 0x01, SCO_PACKET_TYPES_2EV3, true,  HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_S2
1657     { 0x000a, 0x01, SCO_PACKET_TYPES_2EV3, true,  HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_S3
1658     { 0x000c, 0x02, SCO_PACKET_TYPES_2EV3, true,  HFP_CODEC_CVSD }, // HFP_LINK_SETTINGS_S4
1659     { 0x0008, 0x02, SCO_PACKET_TYPES_EV3,  true,  HFP_CODEC_MSBC }, // HFP_LINK_SETTINGS_T1
1660     { 0x000d, 0x02, SCO_PACKET_TYPES_2EV3, true,  HFP_CODEC_MSBC }  // HFP_LINK_SETTINGS_T2
1661 };
1662 
1663 void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){
1664     // all packet types, fixed bandwidth
1665     int setting = hfp_connection->link_setting;
1666     log_info("hfp_setup_synchronous_connection using setting nr %u", setting);
1667     sco_establishment_active = hfp_connection;
1668     uint16_t sco_voice_setting = hci_get_sco_voice_setting();
1669     if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
1670 #ifdef ENABLE_BCM_PCM_WBS
1671         sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers
1672 #else
1673         sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise
1674 #endif
1675     }
1676     // get packet types - bits 6-9 are 'don't allow'
1677     uint16_t packet_types = hfp_link_settings[setting].packet_types ^ 0x03c0;
1678     hci_send_cmd(&hci_setup_synchronous_connection, hfp_connection->acl_handle, 8000, 8000, hfp_link_settings[setting].max_latency,
1679         sco_voice_setting, hfp_link_settings[setting].retransmission_effort, packet_types);
1680 }
1681 
1682 void hfp_accept_synchronous_connection(hfp_connection_t * hfp_connection, bool incoming_eSCO){
1683 
1684     // remote supported feature eSCO is set if link type is eSCO
1685     // eSCO: S4 - max latency == transmission interval = 0x000c == 12 ms,
1686     uint16_t max_latency;
1687     uint8_t  retransmission_effort;
1688     uint16_t packet_types;
1689 
1690     if (incoming_eSCO && hci_extended_sco_link_supported() && hci_remote_esco_supported(hfp_connection->acl_handle)){
1691         max_latency = 0x000c;
1692         retransmission_effort = 0x02;
1693         // eSCO: EV3 and 2-EV3
1694         packet_types = 0x0048;
1695     } else {
1696         max_latency = 0xffff;
1697         retransmission_effort = 0xff;
1698         // sco: HV1 and HV3
1699         packet_types = 0x005;
1700     }
1701 
1702     // mSBC only allows for transparent data
1703     uint16_t sco_voice_setting = hci_get_sco_voice_setting();
1704     if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
1705 #ifdef ENABLE_BCM_PCM_WBS
1706         sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers
1707 #else
1708         sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise
1709 #endif
1710     }
1711 
1712     // filter packet types
1713     packet_types &= hfp_get_sco_packet_types();
1714 
1715     // bits 6-9 are 'don't allow'
1716     packet_types ^= 0x3c0;
1717 
1718     log_info("HFP: sending hci_accept_connection_request, packet types 0x%04x, sco_voice_setting 0x%02x", packet_types, sco_voice_setting);
1719     hci_send_cmd(&hci_accept_synchronous_connection, hfp_connection->remote_addr, 8000, 8000, max_latency,
1720                  sco_voice_setting, retransmission_effort, packet_types);
1721 }
1722 
1723 #ifdef ENABLE_CC256X_ASSISTED_HFP
1724 void hfp_cc256x_prepare_for_sco(hfp_connection_t * hfp_connection){
1725     hfp_connection->cc256x_send_write_codec_config = true;
1726     if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
1727         hfp_connection->cc256x_send_wbs_associate = true;
1728     }
1729 }
1730 
1731 void hfp_cc256x_write_codec_config(hfp_connection_t * hfp_connection){
1732     uint32_t sample_rate_hz;
1733     uint16_t clock_rate_khz;
1734     if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
1735         clock_rate_khz = 512;
1736         sample_rate_hz = 16000;
1737     } else {
1738         clock_rate_khz = 256;
1739         sample_rate_hz = 8000;
1740     }
1741     uint8_t clock_direction = 0;        // master
1742     uint16_t frame_sync_duty_cycle = 0; // i2s with 50%
1743     uint8_t  frame_sync_edge = 1;       // rising edge
1744     uint8_t  frame_sync_polarity = 0;   // active high
1745     uint8_t  reserved = 0;
1746     uint16_t size = 16;
1747     uint16_t chan_1_offset = 1;
1748     uint16_t chan_2_offset = chan_1_offset + size;
1749     uint8_t  out_edge = 1;              // rising
1750     uint8_t  in_edge = 0;               // falling
1751     hci_send_cmd(&hci_ti_write_codec_config, clock_rate_khz, clock_direction, sample_rate_hz, frame_sync_duty_cycle,
1752                  frame_sync_edge, frame_sync_polarity, reserved,
1753                  size, chan_1_offset, out_edge, size, chan_1_offset, in_edge, reserved,
1754                  size, chan_2_offset, out_edge, size, chan_2_offset, in_edge, reserved);
1755 }
1756 #endif
1757 
1758 #ifdef ENABLE_BCM_PCM_WBS
1759 void hfp_bcm_prepare_for_sco(hfp_connection_t * hfp_connection){
1760     hfp_connection->bcm_send_write_i2spcm_interface_param = true;
1761     if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
1762         hfp_connection->bcm_send_enable_wbs = true;
1763     }
1764 }
1765 void hfp_bcm_write_i2spcm_interface_param(hfp_connection_t * hfp_connection){
1766     uint8_t sample_rate = (hfp_connection->negotiated_codec == HFP_CODEC_MSBC) ? 1 : 0;
1767     // i2s enable, master, 8/16 kHz, 512 kHz
1768     hci_send_cmd(&hci_bcm_write_i2spcm_interface_paramhci_bcm_write_i2spcm_interface_param, 1, 1, sample_rate, 2);
1769 }
1770 #endif
1771 
1772 void hfp_set_hf_callback(btstack_packet_handler_t callback){
1773     hfp_hf_callback = callback;
1774 }
1775 
1776 void hfp_set_ag_callback(btstack_packet_handler_t callback){
1777     hfp_ag_callback = callback;
1778 }
1779 
1780 void hfp_set_ag_rfcomm_packet_handler(btstack_packet_handler_t handler){
1781     hfp_ag_rfcomm_packet_handler = handler;
1782 }
1783 
1784 void hfp_set_hf_rfcomm_packet_handler(btstack_packet_handler_t handler){
1785     hfp_hf_rfcomm_packet_handler = handler;
1786 }
1787 
1788 void hfp_init(void){
1789     hfp_allowed_sco_packet_types = SCO_PACKET_TYPES_ALL;
1790 }
1791 
1792 void hfp_deinit(void){
1793     hfp_connections = NULL;
1794     hfp_hf_callback = NULL;
1795     hfp_ag_callback = NULL;
1796     hfp_hf_rfcomm_packet_handler = NULL;
1797     hfp_ag_rfcomm_packet_handler = NULL;
1798     sco_establishment_active = NULL;
1799     (void) memset(&sdp_query_context, 0, sizeof(hfp_sdp_query_context_t));
1800     (void) memset(&hfp_handle_sdp_client_query_request, 0, sizeof(btstack_context_callback_registration_t));
1801 }
1802 
1803 void hfp_set_sco_packet_types(uint16_t packet_types){
1804     hfp_allowed_sco_packet_types = packet_types;
1805 }
1806 
1807 uint16_t hfp_get_sco_packet_types(void){
1808     return hfp_allowed_sco_packet_types;
1809 }
1810 
1811 hfp_link_settings_t hfp_next_link_setting(hfp_link_settings_t current_setting, bool local_eSCO_supported, bool remote_eSCO_supported, bool eSCO_S4_supported, uint8_t negotiated_codec){
1812     int8_t setting = (int8_t) current_setting;
1813     bool can_use_eSCO = local_eSCO_supported && remote_eSCO_supported;
1814     while (setting > 0){
1815         setting--;
1816         // skip if eSCO required but not available
1817         if (hfp_link_settings[setting].eSCO && !can_use_eSCO) continue;
1818         // skip if S4 but not supported
1819         if ((setting == (int8_t) HFP_LINK_SETTINGS_S4) && !eSCO_S4_supported) continue;
1820         // skip wrong codec
1821         if ( hfp_link_settings[setting].codec != negotiated_codec) continue;
1822         // skip disabled packet types
1823         uint16_t required_packet_types = hfp_link_settings[setting].packet_types;
1824         uint16_t allowed_packet_types  = hfp_allowed_sco_packet_types;
1825         if ((required_packet_types & allowed_packet_types) == 0) continue;
1826 
1827         // found matching setting
1828         return (hfp_link_settings_t) setting;
1829     }
1830     return HFP_LINK_SETTINGS_NONE;
1831 }
1832 
1833 static hfp_link_settings_t hfp_next_link_setting_for_connection(hfp_link_settings_t current_setting, hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported){
1834     bool local_eSCO_supported  = hci_extended_sco_link_supported();
1835     bool remote_eSCO_supported = hci_remote_esco_supported(hfp_connection->acl_handle);
1836     uint8_t negotiated_codec   = hfp_connection->negotiated_codec;
1837     return  hfp_next_link_setting(current_setting, local_eSCO_supported, remote_eSCO_supported, eSCO_S4_supported, negotiated_codec);
1838 }
1839 
1840 void hfp_init_link_settings(hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported){
1841     // get highest possible link setting
1842     hfp_connection->link_setting = hfp_next_link_setting_for_connection(HFP_LINK_SETTINGS_NONE, hfp_connection, eSCO_S4_supported);
1843     log_info("hfp_init_link_settings: %u", hfp_connection->link_setting);
1844 }
1845 
1846 #define HFP_HF_RX_DEBUG_PRINT_LINE 80
1847 
1848 void hfp_log_rfcomm_message(const char * tag, uint8_t * packet, uint16_t size){
1849 #ifdef ENABLE_LOG_INFO
1850     // encode \n\r
1851     char printable[HFP_HF_RX_DEBUG_PRINT_LINE+2];
1852     int i = 0;
1853     int pos;
1854     for (pos=0 ; (pos < size) && (i < (HFP_HF_RX_DEBUG_PRINT_LINE - 3)) ; pos++){
1855         switch (packet[pos]){
1856             case '\n':
1857                 printable[i++] = '\\';
1858                 printable[i++] = 'n';
1859                 break;
1860             case '\r':
1861                 printable[i++] = '\\';
1862                 printable[i++] = 'r';
1863                 break;
1864             default:
1865                 printable[i++] = packet[pos];
1866                 break;
1867         }
1868     }
1869     printable[i] = 0;
1870     log_info("%s: '%s'", tag, printable);
1871 #endif
1872 }
1873