xref: /btstack/src/classic/hfp.c (revision 1a6822024624aab466a9aff5f67325f81ed6d5e2)
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 
39 #include "btstack_config.h"
40 
41 #include <stdint.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <inttypes.h>
46 
47 #include "btstack_debug.h"
48 #include "btstack_event.h"
49 #include "btstack_memory.h"
50 #include "btstack_run_loop.h"
51 #include "classic/core.h"
52 #include "classic/sdp_client_rfcomm.h"
53 #include "classic/sdp_server.h"
54 #include "classic/sdp_util.h"
55 #include "hci.h"
56 #include "hci_cmd.h"
57 #include "hci_dump.h"
58 #include "l2cap.h"
59 
60 #define HFP_HF_FEATURES_SIZE 10
61 #define HFP_AG_FEATURES_SIZE 12
62 
63 
64 static const char * hfp_hf_features[] = {
65     "EC and/or NR function",
66     "Three-way calling",
67     "CLI presentation capability",
68     "Voice recognition activation",
69     "Remote volume control",
70 
71     "Enhanced call status",
72     "Enhanced call control",
73 
74     "Codec negotiation",
75 
76     "HF Indicators",
77     "eSCO S4 (and T2) Settings Supported",
78     "Reserved for future definition"
79 };
80 
81 static const char * hfp_ag_features[] = {
82     "Three-way calling",
83     "EC and/or NR function",
84     "Voice recognition function",
85     "In-band ring tone capability",
86     "Attach a number to a voice tag",
87     "Ability to reject a call",
88     "Enhanced call status",
89     "Enhanced call control",
90     "Extended Error Result Codes",
91     "Codec negotiation",
92     "HF Indicators",
93     "eSCO S4 (and T2) Settings Supported",
94     "Reserved for future definition"
95 };
96 
97 static btstack_linked_list_t hfp_connections = NULL;
98 static void parse_sequence(hfp_connection_t * context);
99 static btstack_packet_handler_t hfp_callback;
100 static btstack_packet_handler_t rfcomm_packet_handler;
101 
102 static hfp_connection_t * sco_establishment_active;
103 
104 void hfp_set_callback(btstack_packet_handler_t callback){
105     hfp_callback = callback;
106 }
107 
108 const char * hfp_hf_feature(int index){
109     if (index > HFP_HF_FEATURES_SIZE){
110         return hfp_hf_features[HFP_HF_FEATURES_SIZE];
111     }
112     return hfp_hf_features[index];
113 }
114 
115 const char * hfp_ag_feature(int index){
116     if (index > HFP_AG_FEATURES_SIZE){
117         return hfp_ag_features[HFP_AG_FEATURES_SIZE];
118     }
119     return hfp_ag_features[index];
120 }
121 
122 int send_str_over_rfcomm(uint16_t cid, char * command){
123     if (!rfcomm_can_send_packet_now(cid)) return 1;
124     log_info("HFP_TX %s", command);
125     int err = rfcomm_send(cid, (uint8_t*) command, strlen(command));
126     if (err){
127         log_error("rfcomm_send -> error 0x%02x \n", err);
128     }
129     return 1;
130 }
131 
132 int hfp_supports_codec(uint8_t codec, int codecs_nr, uint8_t * codecs){
133 
134     // mSBC requires support for eSCO connections
135     if (codec == HFP_CODEC_MSBC && !hci_extended_sco_link_supported()) return 0;
136 
137     int i;
138     for (i = 0; i < codecs_nr; i++){
139         if (codecs[i] != codec) continue;
140         return 1;
141     }
142     return 0;
143 }
144 
145 void hfp_hf_drop_mSBC_if_eSCO_not_supported(uint8_t * codecs, uint8_t * codecs_nr){
146     if (hci_extended_sco_link_supported()) return;
147     uint8_t tmp_codecs[HFP_MAX_NUM_CODECS];
148     int i;
149     int tmp_codec_nr = 0;
150     for (i=0; i < *codecs_nr; i++){
151         if (codecs[i] == HFP_CODEC_MSBC) continue;
152         tmp_codecs[tmp_codec_nr++] = codecs[i];
153     }
154     *codecs_nr = tmp_codec_nr;
155     memcpy(codecs, tmp_codecs, tmp_codec_nr);
156 }
157 
158 // UTILS
159 int get_bit(uint16_t bitmap, int position){
160     return (bitmap >> position) & 1;
161 }
162 
163 int store_bit(uint32_t bitmap, int position, uint8_t value){
164     if (value){
165         bitmap |= 1 << position;
166     } else {
167         bitmap &= ~ (1 << position);
168     }
169     return bitmap;
170 }
171 
172 int join(char * buffer, int buffer_size, uint8_t * values, int values_nr){
173     if (buffer_size < values_nr * 3) return 0;
174     int i;
175     int offset = 0;
176     for (i = 0; i < values_nr-1; i++) {
177       offset += snprintf(buffer+offset, buffer_size-offset, "%d,", values[i]); // puts string into buffer
178     }
179     if (i<values_nr){
180         offset += snprintf(buffer+offset, buffer_size-offset, "%d", values[i]);
181     }
182     return offset;
183 }
184 
185 int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){
186     if (buffer_size < values_nr * 3) return 0;
187 
188     int i;
189     int offset = 0;
190     for (i = 0; i < values_nr-1; i++) {
191       offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_bit(values,i)); // puts string into buffer
192     }
193 
194     if (i<values_nr){
195         offset += snprintf(buffer+offset, buffer_size-offset, "%d", get_bit(values,i));
196     }
197     return offset;
198 }
199 
200 void hfp_emit_simple_event(btstack_packet_handler_t callback, uint8_t event_subtype){
201     if (!callback) return;
202     uint8_t event[3];
203     event[0] = HCI_EVENT_HFP_META;
204     event[1] = sizeof(event) - 2;
205     event[2] = event_subtype;
206     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
207 }
208 
209 void hfp_emit_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t value){
210     if (!callback) return;
211     uint8_t event[4];
212     event[0] = HCI_EVENT_HFP_META;
213     event[1] = sizeof(event) - 2;
214     event[2] = event_subtype;
215     event[3] = value; // status 0 == OK
216     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
217 }
218 
219 void hfp_emit_slc_connection_event(btstack_packet_handler_t callback, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr){
220     if (!callback) return;
221     uint8_t event[12];
222     int pos = 0;
223     event[pos++] = HCI_EVENT_HFP_META;
224     event[pos++] = sizeof(event) - 2;
225     event[pos++] = HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
226     event[pos++] = status; // status 0 == OK
227     little_endian_store_16(event, pos, con_handle);
228     pos += 2;
229     reverse_bd_addr(addr,&event[pos]);
230     pos += 6;
231     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
232 }
233 
234 static void hfp_emit_sco_event(btstack_packet_handler_t callback, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr, uint8_t  negotiated_codec){
235     if (!callback) return;
236     uint8_t event[13];
237     int pos = 0;
238     event[pos++] = HCI_EVENT_HFP_META;
239     event[pos++] = sizeof(event) - 2;
240     event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED;
241     event[pos++] = status; // status 0 == OK
242     little_endian_store_16(event, pos, con_handle);
243     pos += 2;
244     reverse_bd_addr(addr,&event[pos]);
245     pos += 6;
246     event[pos++] = negotiated_codec;
247     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
248 }
249 
250 void hfp_emit_string_event(btstack_packet_handler_t callback, uint8_t event_subtype, const char * value){
251     if (!callback) return;
252     uint8_t event[40];
253     event[0] = HCI_EVENT_HFP_META;
254     event[1] = sizeof(event) - 2;
255     event[2] = event_subtype;
256     int size = (strlen(value) < sizeof(event) - 4) ? (int) strlen(value) : sizeof(event) - 4;
257     strncpy((char*)&event[3], value, size);
258     event[3 + size] = 0;
259     (*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
260 }
261 
262 btstack_linked_list_t * hfp_get_connections(void){
263     return (btstack_linked_list_t *) &hfp_connections;
264 }
265 
266 hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){
267     btstack_linked_list_iterator_t it;
268     btstack_linked_list_iterator_init(&it, hfp_get_connections());
269     while (btstack_linked_list_iterator_has_next(&it)){
270         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
271         if (hfp_connection->rfcomm_cid == cid){
272             return hfp_connection;
273         }
274     }
275     return NULL;
276 }
277 
278 hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){
279     btstack_linked_list_iterator_t it;
280     btstack_linked_list_iterator_init(&it, hfp_get_connections());
281     while (btstack_linked_list_iterator_has_next(&it)){
282         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
283         if (memcmp(hfp_connection->remote_addr, bd_addr, 6) == 0) {
284             return hfp_connection;
285         }
286     }
287     return NULL;
288 }
289 
290 hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle){
291     btstack_linked_list_iterator_t it;
292     btstack_linked_list_iterator_init(&it, hfp_get_connections());
293     while (btstack_linked_list_iterator_has_next(&it)){
294         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
295         if (hfp_connection->sco_handle == handle){
296             return hfp_connection;
297         }
298     }
299     return NULL;
300 }
301 
302 hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle){
303     btstack_linked_list_iterator_t it;
304     btstack_linked_list_iterator_init(&it, hfp_get_connections());
305     while (btstack_linked_list_iterator_has_next(&it)){
306         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
307         if (hfp_connection->acl_handle == handle){
308             return hfp_connection;
309         }
310     }
311     return NULL;
312 }
313 
314 void hfp_reset_context_flags(hfp_connection_t * hfp_connection){
315     if (!hfp_connection) return;
316     hfp_connection->ok_pending = 0;
317     hfp_connection->send_error = 0;
318 
319     hfp_connection->keep_byte = 0;
320 
321     hfp_connection->change_status_update_for_individual_ag_indicators = 0;
322     hfp_connection->operator_name_changed = 0;
323 
324     hfp_connection->enable_extended_audio_gateway_error_report = 0;
325     hfp_connection->extended_audio_gateway_error = 0;
326 
327     // establish codecs hfp_connection
328     hfp_connection->suggested_codec = 0;
329     hfp_connection->negotiated_codec = 0;
330     hfp_connection->codec_confirmed = 0;
331 
332     hfp_connection->establish_audio_connection = 0;
333     hfp_connection->call_waiting_notification_enabled = 0;
334     hfp_connection->command = HFP_CMD_NONE;
335     hfp_connection->enable_status_update_for_ag_indicators = 0xFF;
336 }
337 
338 static hfp_connection_t * create_hfp_connection_context(void){
339     hfp_connection_t * hfp_connection = btstack_memory_hfp_connection_get();
340     if (!hfp_connection) return NULL;
341     // init state
342     memset(hfp_connection,0, sizeof(hfp_connection_t));
343 
344     hfp_connection->state = HFP_IDLE;
345     hfp_connection->call_state = HFP_CALL_IDLE;
346     hfp_connection->codecs_state = HFP_CODECS_IDLE;
347 
348     hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
349     hfp_connection->command = HFP_CMD_NONE;
350 
351     hfp_reset_context_flags(hfp_connection);
352 
353     btstack_linked_list_add(&hfp_connections, (btstack_linked_item_t*)hfp_connection);
354     return hfp_connection;
355 }
356 
357 static void remove_hfp_connection_context(hfp_connection_t * hfp_connection){
358     btstack_linked_list_remove(&hfp_connections, (btstack_linked_item_t*) hfp_connection);
359 }
360 
361 static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){
362     hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr);
363     if (hfp_connection) return  hfp_connection;
364     hfp_connection = create_hfp_connection_context();
365     memcpy(hfp_connection->remote_addr, bd_addr, 6);
366     return hfp_connection;
367 }
368 
369 /* @param network.
370  * 0 == no ability to reject a call.
371  * 1 == ability to reject a call.
372  */
373 
374 /* @param suported_features
375  * HF bit 0: EC and/or NR function (yes/no, 1 = yes, 0 = no)
376  * HF bit 1: Call waiting or three-way calling(yes/no, 1 = yes, 0 = no)
377  * HF bit 2: CLI presentation capability (yes/no, 1 = yes, 0 = no)
378  * HF bit 3: Voice recognition activation (yes/no, 1= yes, 0 = no)
379  * HF bit 4: Remote volume control (yes/no, 1 = yes, 0 = no)
380  * HF bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
381  */
382  /* Bit position:
383  * AG bit 0: Three-way calling (yes/no, 1 = yes, 0 = no)
384  * AG bit 1: EC and/or NR function (yes/no, 1 = yes, 0 = no)
385  * AG bit 2: Voice recognition function (yes/no, 1 = yes, 0 = no)
386  * AG bit 3: In-band ring tone capability (yes/no, 1 = yes, 0 = no)
387  * AG bit 4: Attach a phone number to a voice tag (yes/no, 1 = yes, 0 = no)
388  * AG bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
389  */
390 
391 void hfp_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t service_uuid, int rfcomm_channel_nr, const char * name){
392     uint8_t* attribute;
393     de_create_sequence(service);
394 
395     // 0x0000 "Service Record Handle"
396     de_add_number(service, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle);
397     de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
398 
399     // 0x0001 "Service Class ID List"
400     de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList);
401     attribute = de_push_sequence(service);
402     {
403         //  "UUID for Service"
404         de_add_number(attribute, DE_UUID, DE_SIZE_16, service_uuid);
405         de_add_number(attribute, DE_UUID, DE_SIZE_16, SDP_GenericAudio);
406     }
407     de_pop_sequence(service, attribute);
408 
409     // 0x0004 "Protocol Descriptor List"
410     de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_ProtocolDescriptorList);
411     attribute = de_push_sequence(service);
412     {
413         uint8_t* l2cpProtocol = de_push_sequence(attribute);
414         {
415             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, SDP_L2CAPProtocol);
416         }
417         de_pop_sequence(attribute, l2cpProtocol);
418 
419         uint8_t* rfcomm = de_push_sequence(attribute);
420         {
421             de_add_number(rfcomm,  DE_UUID, DE_SIZE_16, SDP_RFCOMMProtocol);  // rfcomm_service
422             de_add_number(rfcomm,  DE_UINT, DE_SIZE_8,  rfcomm_channel_nr);  // rfcomm channel
423         }
424         de_pop_sequence(attribute, rfcomm);
425     }
426     de_pop_sequence(service, attribute);
427 
428 
429     // 0x0005 "Public Browse Group"
430     de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_BrowseGroupList); // public browse group
431     attribute = de_push_sequence(service);
432     {
433         de_add_number(attribute,  DE_UUID, DE_SIZE_16, SDP_PublicBrowseGroup);
434     }
435     de_pop_sequence(service, attribute);
436 
437     // 0x0009 "Bluetooth Profile Descriptor List"
438     de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_BluetoothProfileDescriptorList);
439     attribute = de_push_sequence(service);
440     {
441         uint8_t *sppProfile = de_push_sequence(attribute);
442         {
443             de_add_number(sppProfile,  DE_UUID, DE_SIZE_16, SDP_Handsfree);
444             de_add_number(sppProfile,  DE_UINT, DE_SIZE_16, 0x0107); // Verision 1.7
445         }
446         de_pop_sequence(attribute, sppProfile);
447     }
448     de_pop_sequence(service, attribute);
449 
450     // 0x0100 "Service Name"
451     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
452     de_add_data(service,  DE_STRING, strlen(name), (uint8_t *) name);
453 }
454 
455 static hfp_connection_t * connection_doing_sdp_query = NULL;
456 
457 static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
458     UNUSED(packet_type);
459     UNUSED(channel);
460     UNUSED(size);
461 
462     hfp_connection_t * hfp_connection = connection_doing_sdp_query;
463 
464     if ( hfp_connection->state != HFP_W4_SDP_QUERY_COMPLETE) return;
465 
466     switch (hci_event_packet_get_type(packet)){
467         case SDP_EVENT_QUERY_RFCOMM_SERVICE:
468             if (!hfp_connection) {
469                 log_error("handle_query_rfcomm_event alloc connection for RFCOMM port %u failed", sdp_event_query_rfcomm_service_get_rfcomm_channel(packet));
470                 return;
471             }
472             hfp_connection->rfcomm_channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet);
473             break;
474         case SDP_EVENT_QUERY_COMPLETE:
475             connection_doing_sdp_query = NULL;
476             if (hfp_connection->rfcomm_channel_nr > 0){
477                 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
478                 log_info("HFP: SDP_EVENT_QUERY_COMPLETE context %p, addr %s, state %d", hfp_connection, bd_addr_to_str( hfp_connection->remote_addr),  hfp_connection->state);
479                 rfcomm_create_channel(rfcomm_packet_handler, hfp_connection->remote_addr, hfp_connection->rfcomm_channel_nr, NULL);
480                 break;
481             }
482             log_info("rfcomm service not found, status %u.", sdp_event_query_complete_get_status(packet));
483             break;
484         default:
485             break;
486     }
487 }
488 
489 static void hfp_handle_failed_sco_connection(uint8_t status){
490 
491     if (!sco_establishment_active){
492         log_error("(e)SCO Connection failed but not started by us");
493         return;
494     }
495     log_error("(e)SCO Connection failed status 0x%02x", status);
496 
497     // invalid params / unspecified error
498     if (status != 0x11 && status != 0x1f) return;
499 
500      switch (sco_establishment_active->link_setting){
501         case HFP_LINK_SETTINGS_D0:
502             return; // no other option left
503         case HFP_LINK_SETTINGS_D1:
504             sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D0;
505             break;
506         case HFP_LINK_SETTINGS_S1:
507             sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1;
508             break;
509         case HFP_LINK_SETTINGS_S2:
510             sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S1;
511             break;
512         case HFP_LINK_SETTINGS_S3:
513             sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S2;
514             break;
515         case HFP_LINK_SETTINGS_S4:
516             sco_establishment_active->link_setting = HFP_LINK_SETTINGS_S3;
517             break;
518         case HFP_LINK_SETTINGS_T1:
519             log_info("T1 failed, fallback to CVSD - D1");
520             sco_establishment_active->negotiated_codec = HFP_CODEC_CVSD;
521             sco_establishment_active->sco_for_msbc_failed = 1;
522             sco_establishment_active->command = HFP_CMD_AG_SEND_COMMON_CODEC;
523             sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1;
524             break;
525         case HFP_LINK_SETTINGS_T2:
526             sco_establishment_active->link_setting = HFP_LINK_SETTINGS_T1;
527             break;
528     }
529     sco_establishment_active->establish_audio_connection = 1;
530     sco_establishment_active = 0;
531 }
532 
533 
534 void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
535     UNUSED(channel);
536 
537     bd_addr_t event_addr;
538     uint16_t rfcomm_cid, handle;
539     hfp_connection_t * hfp_connection = NULL;
540     uint8_t status;
541 
542     log_info("AG packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
543 
544     switch (hci_event_packet_get_type(packet)) {
545         case HCI_EVENT_CONNECTION_REQUEST:
546             // printf("hfp HCI_EVENT_CONNECTION_REQUEST\n");
547             switch(hci_event_connection_request_get_link_type(packet)){
548                 case 0: //  SCO
549                 case 2: // eSCO
550                     hci_event_connection_request_get_bd_addr(packet, event_addr);
551                     hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
552                     if (!hfp_connection) break;
553                     hfp_connection->hf_accept_sco = 1;
554                     break;
555                 default:
556                     break;
557             }
558             break;
559 
560         case RFCOMM_EVENT_INCOMING_CONNECTION:
561             // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
562             rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr);
563             hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr);
564             if (!hfp_connection || hfp_connection->state != HFP_IDLE) return;
565 
566             hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
567             hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
568             // printf("RFCOMM channel %u requested for %s\n", hfp_connection->rfcomm_cid, bd_addr_to_str(hfp_connection->remote_addr));
569             rfcomm_accept_connection(hfp_connection->rfcomm_cid);
570             break;
571 
572         case RFCOMM_EVENT_CHANNEL_OPENED:
573             // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
574 
575             rfcomm_event_channel_opened_get_bd_addr(packet, event_addr);
576             status = rfcomm_event_channel_opened_get_status(packet);
577 
578             hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
579             if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return;
580 
581             if (status) {
582                 hfp_emit_slc_connection_event(hfp_callback, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr);
583                 remove_hfp_connection_context(hfp_connection);
584             } else {
585                 hfp_connection->acl_handle = rfcomm_event_channel_opened_get_con_handle(packet);
586                 hfp_connection->rfcomm_cid = rfcomm_event_channel_opened_get_rfcomm_cid(packet);
587                 bd_addr_copy(hfp_connection->remote_addr, event_addr);
588                 // uint16_t mtu = rfcomm_event_channel_opened_get_max_frame_size(packet);
589                 // printf("RFCOMM channel open succeeded. hfp_connection %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", hfp_connection, hfp_connection->rfcomm_cid, mtu);
590 
591                 switch (hfp_connection->state){
592                     case HFP_W4_RFCOMM_CONNECTED:
593                         hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
594                         break;
595                     case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
596                         hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
597                         // printf("Shutting down RFCOMM.\n");
598                         break;
599                     default:
600                         break;
601                 }
602                 rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
603             }
604             break;
605 
606         case HCI_EVENT_COMMAND_STATUS:
607             if (hci_event_command_status_get_command_opcode(packet) == hci_setup_synchronous_connection.opcode) {
608                 status = hci_event_command_status_get_status(packet);
609                 if (status) {
610                     hfp_handle_failed_sco_connection(hci_event_command_status_get_status(packet));
611                }
612             }
613             break;
614 
615         case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
616             hci_event_synchronous_connection_complete_get_bd_addr(packet, event_addr);
617             hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
618             if (!hfp_connection) {
619                 log_error("HFP: connection does not exist for remote with addr %s.", bd_addr_to_str(event_addr));
620                 return;
621             }
622 
623             status = hci_event_synchronous_connection_complete_get_status(packet);
624             if (status != 0){
625                 hfp_connection->hf_accept_sco = 0;
626                 hfp_handle_failed_sco_connection(status);
627                 break;
628             }
629 
630             uint16_t sco_handle = hci_event_synchronous_connection_complete_get_handle(packet);
631             uint8_t  link_type = hci_event_synchronous_connection_complete_get_link_type(packet);
632             uint8_t  transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet);  // measured in slots
633             uint8_t  retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots
634             uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes
635             uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes
636             uint8_t  air_mode = hci_event_synchronous_connection_complete_get_air_mode(packet);
637 
638             switch (link_type){
639                 case 0x00:
640                     log_info("SCO Connection established.");
641                     if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
642                     if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);
643                     if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length);
644                     if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length);
645                     break;
646                 case 0x02:
647                     log_info("eSCO Connection established. \n");
648                     break;
649                 default:
650                     log_error("(e)SCO reserved link_type 0x%2x", link_type);
651                     break;
652             }
653             log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, "
654                  " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle,
655                  bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);
656 
657             hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
658 
659             if (!hfp_connection) {
660                 log_error("SCO link created, hfp_connection for address %s not found.", bd_addr_to_str(event_addr));
661                 break;
662             }
663 
664             if (hfp_connection->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
665                 log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN");
666                 hfp_connection->state = HFP_W2_DISCONNECT_SCO;
667                 break;
668             }
669             hfp_connection->sco_handle = sco_handle;
670             hfp_connection->establish_audio_connection = 0;
671             hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
672             hfp_emit_sco_event(hfp_callback, packet[2], sco_handle, event_addr, hfp_connection->negotiated_codec);
673             break;
674         }
675 
676         case RFCOMM_EVENT_CHANNEL_CLOSED:
677             rfcomm_cid = little_endian_read_16(packet,2);
678             hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
679             if (!hfp_connection) break;
680             if (hfp_connection->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
681                 hfp_connection->state = HFP_IDLE;
682                 hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid);
683                 break;
684             }
685 
686             hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
687             remove_hfp_connection_context(hfp_connection);
688             break;
689 
690         case HCI_EVENT_DISCONNECTION_COMPLETE:
691             handle = little_endian_read_16(packet,3);
692             hfp_connection = get_hfp_connection_context_for_sco_handle(handle);
693 
694             if (!hfp_connection) break;
695 
696             if (hfp_connection->state != HFP_W4_SCO_DISCONNECTED){
697                 log_info("Received gap disconnect in wrong hfp state");
698             }
699             log_info("Check SCO handle: incoming 0x%02x, hfp_connection 0x%02x\n", handle, hfp_connection->sco_handle);
700 
701             if (handle == hfp_connection->sco_handle){
702                 log_info("SCO disconnected, w2 disconnect RFCOMM\n");
703                 hfp_connection->sco_handle = 0;
704                 hfp_connection->release_audio_connection = 0;
705                 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
706                 hfp_emit_event(hfp_callback, HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED, 0);
707                 break;
708             }
709             break;
710 
711         default:
712             break;
713     }
714 }
715 
716 // translates command string into hfp_command_t CMD
717 static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){
718     int offset = isHandsFree ? 0 : 2;
719 
720     if (strncmp(line_buffer+offset, HFP_LIST_CURRENT_CALLS, strlen(HFP_LIST_CURRENT_CALLS)) == 0){
721         return HFP_CMD_LIST_CURRENT_CALLS;
722     }
723 
724     if (strncmp(line_buffer+offset, HFP_SUBSCRIBER_NUMBER_INFORMATION, strlen(HFP_SUBSCRIBER_NUMBER_INFORMATION)) == 0){
725         return HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION;
726     }
727 
728     if (strncmp(line_buffer+offset, HFP_PHONE_NUMBER_FOR_VOICE_TAG, strlen(HFP_PHONE_NUMBER_FOR_VOICE_TAG)) == 0){
729         if (isHandsFree) return HFP_CMD_AG_SENT_PHONE_NUMBER;
730         return HFP_CMD_HF_REQUEST_PHONE_NUMBER;
731     }
732 
733     if (strncmp(line_buffer+offset, HFP_TRANSMIT_DTMF_CODES, strlen(HFP_TRANSMIT_DTMF_CODES)) == 0){
734         return HFP_CMD_TRANSMIT_DTMF_CODES;
735     }
736 
737     if (strncmp(line_buffer+offset, HFP_SET_MICROPHONE_GAIN, strlen(HFP_SET_MICROPHONE_GAIN)) == 0){
738         return HFP_CMD_SET_MICROPHONE_GAIN;
739     }
740 
741     if (strncmp(line_buffer+offset, HFP_SET_SPEAKER_GAIN, strlen(HFP_SET_SPEAKER_GAIN)) == 0){
742         return HFP_CMD_SET_SPEAKER_GAIN;
743     }
744 
745     if (strncmp(line_buffer+offset, HFP_ACTIVATE_VOICE_RECOGNITION, strlen(HFP_ACTIVATE_VOICE_RECOGNITION)) == 0){
746         if (isHandsFree) return HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION;
747         return HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION;
748     }
749 
750     if (strncmp(line_buffer+offset, HFP_TURN_OFF_EC_AND_NR, strlen(HFP_TURN_OFF_EC_AND_NR)) == 0){
751         return HFP_CMD_TURN_OFF_EC_AND_NR;
752     }
753 
754     if (strncmp(line_buffer, HFP_CALL_ANSWERED, strlen(HFP_CALL_ANSWERED)) == 0){
755         return HFP_CMD_CALL_ANSWERED;
756     }
757 
758     if (strncmp(line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){
759         return HFP_CMD_CALL_PHONE_NUMBER;
760     }
761 
762     if (strncmp(line_buffer+offset, HFP_REDIAL_LAST_NUMBER, strlen(HFP_REDIAL_LAST_NUMBER)) == 0){
763         return HFP_CMD_REDIAL_LAST_NUMBER;
764     }
765 
766     if (strncmp(line_buffer+offset, HFP_CHANGE_IN_BAND_RING_TONE_SETTING, strlen(HFP_CHANGE_IN_BAND_RING_TONE_SETTING)) == 0){
767         return HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING;
768     }
769 
770     if (strncmp(line_buffer+offset, HFP_HANG_UP_CALL, strlen(HFP_HANG_UP_CALL)) == 0){
771         return HFP_CMD_HANG_UP_CALL;
772     }
773 
774     if (strncmp(line_buffer+offset, HFP_ERROR, strlen(HFP_ERROR)) == 0){
775         return HFP_CMD_ERROR;
776     }
777 
778     if (strncmp(line_buffer+offset, HFP_RING, strlen(HFP_RING)) == 0){
779         return HFP_CMD_RING;
780     }
781 
782     if (isHandsFree && strncmp(line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){
783         return HFP_CMD_OK;
784     }
785 
786     if (strncmp(line_buffer+offset, HFP_SUPPORTED_FEATURES, strlen(HFP_SUPPORTED_FEATURES)) == 0){
787         return HFP_CMD_SUPPORTED_FEATURES;
788     }
789 
790     if (strncmp(line_buffer+offset, HFP_TRANSFER_HF_INDICATOR_STATUS, strlen(HFP_TRANSFER_HF_INDICATOR_STATUS)) == 0){
791         return HFP_CMD_HF_INDICATOR_STATUS;
792     }
793 
794     if (strncmp(line_buffer+offset, HFP_RESPONSE_AND_HOLD, strlen(HFP_RESPONSE_AND_HOLD)) == 0){
795         if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "?", 1) == 0){
796             return HFP_CMD_RESPONSE_AND_HOLD_QUERY;
797         }
798         if (strncmp(line_buffer+strlen(HFP_RESPONSE_AND_HOLD)+offset, "=", 1) == 0){
799             return HFP_CMD_RESPONSE_AND_HOLD_COMMAND;
800         }
801         return HFP_CMD_RESPONSE_AND_HOLD_STATUS;
802     }
803 
804     if (strncmp(line_buffer+offset, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){
805         if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "?", 1) == 0){
806             return HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS;
807         }
808 
809         if (strncmp(line_buffer+strlen(HFP_INDICATOR)+offset, "=?", 2) == 0){
810             return HFP_CMD_RETRIEVE_AG_INDICATORS;
811         }
812     }
813 
814     if (strncmp(line_buffer+offset, HFP_AVAILABLE_CODECS, strlen(HFP_AVAILABLE_CODECS)) == 0){
815         return HFP_CMD_AVAILABLE_CODECS;
816     }
817 
818     if (strncmp(line_buffer+offset, HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, strlen(HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS)) == 0){
819         return HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE;
820     }
821 
822     if (strncmp(line_buffer+offset, HFP_ENABLE_CLIP, strlen(HFP_ENABLE_CLIP)) == 0){
823         if (isHandsFree) return HFP_CMD_AG_SENT_CLIP_INFORMATION;
824         return HFP_CMD_ENABLE_CLIP;
825     }
826 
827     if (strncmp(line_buffer+offset, HFP_ENABLE_CALL_WAITING_NOTIFICATION, strlen(HFP_ENABLE_CALL_WAITING_NOTIFICATION)) == 0){
828         if (isHandsFree) return HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE;
829         return HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION;
830     }
831 
832     if (strncmp(line_buffer+offset, HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)) == 0){
833 
834         if (isHandsFree) return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES;
835 
836         if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=?", 2) == 0){
837             return HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES;
838         }
839         if (strncmp(line_buffer+strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)+offset, "=", 1) == 0){
840             return HFP_CMD_CALL_HOLD;
841         }
842 
843         return HFP_CMD_UNKNOWN;
844     }
845 
846     if (strncmp(line_buffer+offset, HFP_GENERIC_STATUS_INDICATOR, strlen(HFP_GENERIC_STATUS_INDICATOR)) == 0){
847         if (isHandsFree) {
848             return HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS;
849         }
850         if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=?", 2) == 0){
851             return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS;
852         }
853         if (strncmp(line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=", 1) == 0){
854             return HFP_CMD_LIST_GENERIC_STATUS_INDICATORS;
855         }
856         return HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE;
857     }
858 
859     if (strncmp(line_buffer+offset, HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS, strlen(HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS)) == 0){
860         return HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE;
861     }
862 
863 
864     if (strncmp(line_buffer+offset, HFP_QUERY_OPERATOR_SELECTION, strlen(HFP_QUERY_OPERATOR_SELECTION)) == 0){
865         if (strncmp(line_buffer+strlen(HFP_QUERY_OPERATOR_SELECTION)+offset, "=", 1) == 0){
866             return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT;
867         }
868         return HFP_CMD_QUERY_OPERATOR_SELECTION_NAME;
869     }
870 
871     if (strncmp(line_buffer+offset, HFP_TRANSFER_AG_INDICATOR_STATUS, strlen(HFP_TRANSFER_AG_INDICATOR_STATUS)) == 0){
872         return HFP_CMD_TRANSFER_AG_INDICATOR_STATUS;
873     }
874 
875     if (isHandsFree && strncmp(line_buffer+offset, HFP_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){
876         return HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR;
877     }
878 
879     if (!isHandsFree && strncmp(line_buffer+offset, HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){
880         return HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR;
881     }
882 
883     if (strncmp(line_buffer+offset, HFP_TRIGGER_CODEC_CONNECTION_SETUP, strlen(HFP_TRIGGER_CODEC_CONNECTION_SETUP)) == 0){
884         return HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP;
885     }
886 
887     if (strncmp(line_buffer+offset, HFP_CONFIRM_COMMON_CODEC, strlen(HFP_CONFIRM_COMMON_CODEC)) == 0){
888         if (isHandsFree){
889             return HFP_CMD_AG_SUGGESTED_CODEC;
890         } else {
891             return HFP_CMD_HF_CONFIRMED_CODEC;
892         }
893     }
894 
895     if (strncmp(line_buffer+offset, "AT+", 3) == 0){
896         log_info("process unknown HF command %s \n", line_buffer);
897         return HFP_CMD_UNKNOWN;
898     }
899 
900     if (strncmp(line_buffer+offset, "+", 1) == 0){
901         log_info(" process unknown AG command %s \n", line_buffer);
902         return HFP_CMD_UNKNOWN;
903     }
904 
905     if (strncmp(line_buffer+offset, "NOP", 3) == 0){
906         return HFP_CMD_NONE;
907     }
908 
909     return HFP_CMD_NONE;
910 }
911 
912 static void hfp_parser_store_byte(hfp_connection_t * hfp_connection, uint8_t byte){
913     // printf("hfp_parser_store_byte %c at pos %u\n", (char) byte, context->line_size);
914     // TODO: add limit
915     hfp_connection->line_buffer[hfp_connection->line_size++] = byte;
916     hfp_connection->line_buffer[hfp_connection->line_size] = 0;
917 }
918 static int hfp_parser_is_buffer_empty(hfp_connection_t * hfp_connection){
919     return hfp_connection->line_size == 0;
920 }
921 
922 static int hfp_parser_is_end_of_line(uint8_t byte){
923     return byte == '\n' || byte == '\r';
924 }
925 
926 static int hfp_parser_is_end_of_header(uint8_t byte){
927     return hfp_parser_is_end_of_line(byte) || byte == ':' || byte == '?';
928 }
929 
930 static int hfp_parser_found_separator(hfp_connection_t * hfp_connection, uint8_t byte){
931     if (hfp_connection->keep_byte == 1) return 1;
932 
933     int found_separator =   byte == ',' || byte == '\n'|| byte == '\r'||
934                             byte == ')' || byte == '(' || byte == ':' ||
935                             byte == '-' || byte == '"' ||  byte == '?'|| byte == '=';
936     return found_separator;
937 }
938 
939 static void hfp_parser_next_state(hfp_connection_t * hfp_connection, uint8_t byte){
940     hfp_connection->line_size = 0;
941     if (hfp_parser_is_end_of_line(byte)){
942         hfp_connection->parser_item_index = 0;
943         hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
944         return;
945     }
946     switch (hfp_connection->parser_state){
947         case HFP_PARSER_CMD_HEADER:
948             hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE;
949             if (hfp_connection->keep_byte == 1){
950                 hfp_parser_store_byte(hfp_connection, byte);
951                 hfp_connection->keep_byte = 0;
952             }
953             break;
954         case HFP_PARSER_CMD_SEQUENCE:
955             switch (hfp_connection->command){
956                 case HFP_CMD_AG_SENT_PHONE_NUMBER:
957                 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
958                 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
959                 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
960                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
961                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
962                 case HFP_CMD_RETRIEVE_AG_INDICATORS:
963                 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
964                 case HFP_CMD_HF_INDICATOR_STATUS:
965                     hfp_connection->parser_state = HFP_PARSER_SECOND_ITEM;
966                     break;
967                 default:
968                     break;
969             }
970             break;
971         case HFP_PARSER_SECOND_ITEM:
972             hfp_connection->parser_state = HFP_PARSER_THIRD_ITEM;
973             break;
974         case HFP_PARSER_THIRD_ITEM:
975             if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS){
976                 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE;
977                 break;
978             }
979             hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
980             break;
981     }
982 }
983 
984 void hfp_parse(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){
985     // handle ATD<dial_string>;
986     if (strncmp((const char*)hfp_connection->line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0){
987         // check for end-of-line or ';'
988         if (byte == ';' || hfp_parser_is_end_of_line(byte)){
989             hfp_connection->line_buffer[hfp_connection->line_size] = 0;
990             hfp_connection->line_size = 0;
991             hfp_connection->command = HFP_CMD_CALL_PHONE_NUMBER;
992         } else {
993             hfp_connection->line_buffer[hfp_connection->line_size++] = byte;
994         }
995         return;
996     }
997 
998     // TODO: handle space inside word
999     if (byte == ' ' && hfp_connection->parser_state > HFP_PARSER_CMD_HEADER) return;
1000 
1001     if (byte == ',' && hfp_connection->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){
1002         if (hfp_connection->line_size == 0){
1003             hfp_connection->line_buffer[0] = 0;
1004             hfp_connection->ignore_value = 1;
1005             parse_sequence(hfp_connection);
1006             return;
1007         }
1008     }
1009 
1010     if (!hfp_parser_found_separator(hfp_connection, byte)){
1011         hfp_parser_store_byte(hfp_connection, byte);
1012         return;
1013     }
1014 
1015     if (hfp_parser_is_end_of_line(byte)) {
1016         if (hfp_parser_is_buffer_empty(hfp_connection)){
1017             hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
1018         }
1019     }
1020     if (hfp_parser_is_buffer_empty(hfp_connection)) return;
1021 
1022     switch (hfp_connection->parser_state){
1023         case HFP_PARSER_CMD_HEADER: // header
1024             if (byte == '='){
1025                 hfp_connection->keep_byte = 1;
1026                 hfp_parser_store_byte(hfp_connection, byte);
1027                 return;
1028             }
1029 
1030             if (byte == '?'){
1031                 hfp_connection->keep_byte = 0;
1032                 hfp_parser_store_byte(hfp_connection, byte);
1033                 return;
1034             }
1035 
1036             if (byte == ','){
1037                 hfp_connection->resolve_byte = 1;
1038             }
1039 
1040             // printf(" parse header 2 %s, keep separator $ %d\n", hfp_connection->line_buffer, hfp_connection->keep_byte);
1041             if (hfp_parser_is_end_of_header(byte) || hfp_connection->keep_byte == 1){
1042                 // printf(" parse header 3 %s, keep separator $ %d\n", hfp_connection->line_buffer, hfp_connection->keep_byte);
1043                 char * line_buffer = (char *)hfp_connection->line_buffer;
1044                 hfp_connection->command = parse_command(line_buffer, isHandsFree);
1045 
1046                 /* resolve command name according to hfp_connection */
1047                 if (hfp_connection->command == HFP_CMD_UNKNOWN){
1048                     switch(hfp_connection->state){
1049                         case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
1050                             hfp_connection->command = HFP_CMD_LIST_GENERIC_STATUS_INDICATORS;
1051                             break;
1052                         case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
1053                             hfp_connection->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS;
1054                             break;
1055                         case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
1056                             hfp_connection->command = HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE;
1057                             break;
1058                         case HFP_W4_RETRIEVE_INDICATORS_STATUS:
1059                             hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS;
1060                             break;
1061                         case HFP_W4_RETRIEVE_INDICATORS:
1062                             hfp_connection->send_ag_indicators_segment = 0;
1063                             hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS;
1064                             break;
1065                         default:
1066                             break;
1067                     }
1068                 }
1069             }
1070             break;
1071 
1072         case HFP_PARSER_CMD_SEQUENCE:
1073             parse_sequence(hfp_connection);
1074             break;
1075         case HFP_PARSER_SECOND_ITEM:
1076             switch (hfp_connection->command){
1077                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1078                     log_info("format %s, ", hfp_connection->line_buffer);
1079                     hfp_connection->network_operator.format =  btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1080                     break;
1081                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1082                     log_info("format %s \n", hfp_connection->line_buffer);
1083                     hfp_connection->network_operator.format =  btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1084                     break;
1085                 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
1086                 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
1087                 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1088                     hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].state = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1089                     break;
1090                 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1091                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1092                     log_info("%d \n", hfp_connection->ag_indicators[hfp_connection->parser_item_index].status);
1093                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].status_changed = 1;
1094                     break;
1095                 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1096                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].min_range = btstack_atoi((char *)hfp_connection->line_buffer);
1097                     log_info("%s, ", hfp_connection->line_buffer);
1098                     break;
1099                 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1100                 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1101                 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1102                     hfp_connection->bnip_type = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1103                     break;
1104                 default:
1105                     break;
1106             }
1107             break;
1108 
1109         case HFP_PARSER_THIRD_ITEM:
1110              switch (hfp_connection->command){
1111                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1112                     strcpy(hfp_connection->network_operator.name, (char *)hfp_connection->line_buffer);
1113                     log_info("name %s\n", hfp_connection->line_buffer);
1114                     break;
1115                 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1116                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].max_range = btstack_atoi((char *)hfp_connection->line_buffer);
1117                     hfp_connection->parser_item_index++;
1118                     hfp_connection->ag_indicators_nr = hfp_connection->parser_item_index;
1119                     log_info("%s)\n", hfp_connection->line_buffer);
1120                     break;
1121                 default:
1122                     break;
1123             }
1124             break;
1125     }
1126     hfp_parser_next_state(hfp_connection, byte);
1127 
1128     if (hfp_connection->resolve_byte && hfp_connection->command == HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE){
1129         hfp_connection->resolve_byte = 0;
1130         hfp_connection->ignore_value = 1;
1131         parse_sequence(hfp_connection);
1132         hfp_connection->line_buffer[0] = 0;
1133         hfp_connection->line_size = 0;
1134     }
1135 }
1136 
1137 static void parse_sequence(hfp_connection_t * hfp_connection){
1138     int value;
1139     switch (hfp_connection->command){
1140         case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS:
1141             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1142             int i;
1143             switch (hfp_connection->parser_item_index){
1144                 case 0:
1145                     for (i=0;i<hfp_connection->generic_status_indicators_nr;i++){
1146                         if (hfp_connection->generic_status_indicators[i].uuid == value){
1147                             hfp_connection->parser_indicator_index = i;
1148                             break;
1149                         }
1150                     }
1151                     break;
1152                 case 1:
1153                     if (hfp_connection->parser_indicator_index <0) break;
1154                     hfp_connection->generic_status_indicators[hfp_connection->parser_indicator_index].state = value;
1155                     log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n",
1156                      hfp_connection->parser_item_index, value);
1157                     break;
1158                 default:
1159                     break;
1160             }
1161             hfp_connection->parser_item_index++;
1162             break;
1163 
1164         case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
1165             switch(hfp_connection->parser_item_index){
1166                 case 0:
1167                     strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number));
1168                     hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0;
1169                     break;
1170                 case 1:
1171                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1172                     hfp_connection->bnip_type = value;
1173                     break;
1174                 default:
1175                     break;
1176             }
1177             hfp_connection->parser_item_index++;
1178             break;
1179         case HFP_CMD_LIST_CURRENT_CALLS:
1180             switch(hfp_connection->parser_item_index){
1181                 case 0:
1182                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1183                     hfp_connection->clcc_idx = value;
1184                     break;
1185                 case 1:
1186                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1187                     hfp_connection->clcc_dir = value;
1188                     break;
1189                 case 2:
1190                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1191                     hfp_connection->clcc_status = value;
1192                     break;
1193                 case 3:
1194                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1195                     hfp_connection->clcc_mpty = value;
1196                     break;
1197                 case 4:
1198                     strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number));
1199                     hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0;
1200                     break;
1201                 case 5:
1202                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1203                     hfp_connection->bnip_type = value;
1204                     break;
1205                 default:
1206                     break;
1207             }
1208             hfp_connection->parser_item_index++;
1209             break;
1210         case HFP_CMD_SET_MICROPHONE_GAIN:
1211             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1212             hfp_connection->microphone_gain = value;
1213             log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value);
1214             break;
1215         case HFP_CMD_SET_SPEAKER_GAIN:
1216             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1217             hfp_connection->speaker_gain = value;
1218             log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value);
1219             break;
1220         case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION:
1221             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1222             hfp_connection->ag_activate_voice_recognition = value;
1223             log_info("hfp parse HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION %d\n", value);
1224             break;
1225         case HFP_CMD_TURN_OFF_EC_AND_NR:
1226             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1227             hfp_connection->ag_echo_and_noise_reduction = value;
1228             log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value);
1229             break;
1230         case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING:
1231             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1232             hfp_connection->remote_supported_features = store_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value);
1233             log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value);
1234             break;
1235         case HFP_CMD_HF_CONFIRMED_CODEC:
1236             hfp_connection->codec_confirmed = btstack_atoi((char*)hfp_connection->line_buffer);
1237             log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", hfp_connection->codec_confirmed);
1238             break;
1239         case HFP_CMD_AG_SUGGESTED_CODEC:
1240             hfp_connection->suggested_codec = btstack_atoi((char*)hfp_connection->line_buffer);
1241             log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", hfp_connection->suggested_codec);
1242             break;
1243         case HFP_CMD_SUPPORTED_FEATURES:
1244             hfp_connection->remote_supported_features = btstack_atoi((char*)hfp_connection->line_buffer);
1245             log_info("Parsed supported feature %d\n", hfp_connection->remote_supported_features);
1246             break;
1247         case HFP_CMD_AVAILABLE_CODECS:
1248             log_info("Parsed codec %s\n", hfp_connection->line_buffer);
1249             hfp_connection->remote_codecs[hfp_connection->parser_item_index] = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer);
1250             hfp_connection->parser_item_index++;
1251             hfp_connection->remote_codecs_nr = hfp_connection->parser_item_index;
1252             break;
1253         case HFP_CMD_RETRIEVE_AG_INDICATORS:
1254             strcpy((char *)hfp_connection->ag_indicators[hfp_connection->parser_item_index].name,  (char *)hfp_connection->line_buffer);
1255             hfp_connection->ag_indicators[hfp_connection->parser_item_index].index = hfp_connection->parser_item_index+1;
1256             log_info("Indicator %d: %s (", hfp_connection->ag_indicators_nr+1, hfp_connection->line_buffer);
1257             break;
1258         case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS:
1259             log_info("Parsed Indicator %d with status: %s\n", hfp_connection->parser_item_index+1, hfp_connection->line_buffer);
1260             hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = btstack_atoi((char *) hfp_connection->line_buffer);
1261             hfp_connection->parser_item_index++;
1262             break;
1263         case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
1264             hfp_connection->parser_item_index++;
1265             if (hfp_connection->parser_item_index != 4) break;
1266             log_info("Parsed Enable indicators: %s\n", hfp_connection->line_buffer);
1267             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1268             hfp_connection->enable_status_update_for_ag_indicators = (uint8_t) value;
1269             break;
1270         case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
1271             log_info("Parsed Support call hold: %s\n", hfp_connection->line_buffer);
1272             if (hfp_connection->line_size > 2 ) break;
1273             strcpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_nr].name,  (char *)hfp_connection->line_buffer);
1274             hfp_connection->remote_call_services_nr++;
1275             break;
1276         case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
1277         case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
1278             log_info("Parsed Generic status indicator: %s\n", hfp_connection->line_buffer);
1279             hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].uuid = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer);
1280             hfp_connection->parser_item_index++;
1281             hfp_connection->generic_status_indicators_nr = hfp_connection->parser_item_index;
1282             break;
1283         case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1284             // HF parses inital AG gen. ind. state
1285             log_info("Parsed List generic status indicator %s state: ", hfp_connection->line_buffer);
1286             hfp_connection->parser_item_index = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1287             break;
1288         case HFP_CMD_HF_INDICATOR_STATUS:
1289             hfp_connection->parser_indicator_index = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1290             log_info("Parsed HF indicator index %u", hfp_connection->parser_indicator_index);
1291             break;
1292         case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:
1293             // AG parses new gen. ind. state
1294             if (hfp_connection->ignore_value){
1295                 hfp_connection->ignore_value = 0;
1296                 log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", hfp_connection->parser_item_index,
1297                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled);
1298             }
1299             else if (hfp_connection->ag_indicators[hfp_connection->parser_item_index].mandatory){
1300                 log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n",
1301                     hfp_connection->parser_item_index, hfp_connection->ag_indicators[hfp_connection->parser_item_index].name);
1302             } else {
1303                 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1304                 hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled = value;
1305                 log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", hfp_connection->parser_item_index,
1306                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, value);
1307             }
1308             hfp_connection->parser_item_index++;
1309             break;
1310         case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1311             // indicators are indexed starting with 1
1312             hfp_connection->parser_item_index = btstack_atoi((char *)&hfp_connection->line_buffer[0]) - 1;
1313             log_info("Parsed status of the AG indicator %d, status ", hfp_connection->parser_item_index);
1314             break;
1315         case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1316             hfp_connection->network_operator.mode = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1317             log_info("Parsed network operator mode: %d, ", hfp_connection->network_operator.mode);
1318             break;
1319         case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1320             if (hfp_connection->line_buffer[0] == '3'){
1321                 log_info("Parsed Set network operator format : %s, ", hfp_connection->line_buffer);
1322                 break;
1323             }
1324             // TODO emit ERROR, wrong format
1325             log_info("ERROR Set network operator format: index %s not supported\n", hfp_connection->line_buffer);
1326             break;
1327         case HFP_CMD_ERROR:
1328             break;
1329         case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
1330             hfp_connection->extended_audio_gateway_error = 1;
1331             hfp_connection->extended_audio_gateway_error_value = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1332             break;
1333         case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR:
1334             hfp_connection->enable_extended_audio_gateway_error_report = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1335             hfp_connection->ok_pending = 1;
1336             hfp_connection->extended_audio_gateway_error = 0;
1337             break;
1338         case HFP_CMD_AG_SENT_PHONE_NUMBER:
1339         case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1340         case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1341             strncpy(hfp_connection->bnip_number, (char *)hfp_connection->line_buffer, sizeof(hfp_connection->bnip_number));
1342             hfp_connection->bnip_number[sizeof(hfp_connection->bnip_number)-1] = 0;
1343             break;
1344         default:
1345             break;
1346     }
1347 }
1348 
1349 void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){
1350     hfp_connection_t * hfp_connection = provide_hfp_connection_context_for_bd_addr(bd_addr);
1351     log_info("hfp_connect %s, hfp_connection %p", bd_addr_to_str(bd_addr), hfp_connection);
1352 
1353     if (!hfp_connection) {
1354         log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr));
1355         return;
1356     }
1357 
1358     switch (hfp_connection->state){
1359         case HFP_W2_DISCONNECT_RFCOMM:
1360             hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
1361             return;
1362         case HFP_W4_RFCOMM_DISCONNECTED:
1363             hfp_connection->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART;
1364             return;
1365         case HFP_IDLE:
1366             memcpy(hfp_connection->remote_addr, bd_addr, 6);
1367             hfp_connection->state = HFP_W4_SDP_QUERY_COMPLETE;
1368             connection_doing_sdp_query = hfp_connection;
1369             hfp_connection->service_uuid = service_uuid;
1370             sdp_client_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, hfp_connection->remote_addr, service_uuid);
1371             break;
1372         default:
1373             break;
1374     }
1375 }
1376 
1377 void hfp_release_service_level_connection(hfp_connection_t * hfp_connection){
1378     if (!hfp_connection) return;
1379     hfp_release_audio_connection(hfp_connection);
1380 
1381     if (hfp_connection->state < HFP_W4_RFCOMM_CONNECTED){
1382         hfp_connection->state = HFP_IDLE;
1383         return;
1384     }
1385 
1386     if (hfp_connection->state == HFP_W4_RFCOMM_CONNECTED){
1387         hfp_connection->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
1388         return;
1389     }
1390 
1391     if (hfp_connection->state < HFP_W4_SCO_CONNECTED){
1392         hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
1393         return;
1394     }
1395 
1396     if (hfp_connection->state < HFP_W4_SCO_DISCONNECTED){
1397         hfp_connection->state = HFP_W2_DISCONNECT_SCO;
1398         return;
1399     }
1400 
1401     return;
1402 }
1403 
1404 void hfp_release_audio_connection(hfp_connection_t * hfp_connection){
1405     if (!hfp_connection) return;
1406     if (hfp_connection->state >= HFP_W2_DISCONNECT_SCO) return;
1407     hfp_connection->release_audio_connection = 1;
1408 }
1409 
1410 static const struct link_settings {
1411     const uint16_t max_latency;
1412     const uint8_t  retransmission_effort;
1413     const uint16_t packet_types;
1414 } hfp_link_settings [] = {
1415     { 0xffff, 0xff, 0x03c1 }, // HFP_LINK_SETTINGS_D0,   HV1
1416     { 0xffff, 0xff, 0x03c4 }, // HFP_LINK_SETTINGS_D1,   HV3
1417     { 0x0007, 0x01, 0x03c8 }, // HFP_LINK_SETTINGS_S1,   EV3
1418     { 0x0007, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S2, 2-EV3
1419     { 0x000a, 0x01, 0x0380 }, // HFP_LINK_SETTINGS_S3, 2-EV3
1420     { 0x000c, 0x02, 0x0380 }, // HFP_LINK_SETTINGS_S4, 2-EV3
1421     { 0x0008, 0x02, 0x03c8 }, // HFP_LINK_SETTINGS_T1,   EV3
1422     { 0x000d, 0x02, 0x0380 }  // HFP_LINK_SETTINGS_T2, 2-EV3
1423 };
1424 
1425 void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){
1426     // all packet types, fixed bandwidth
1427     int setting = hfp_connection->link_setting;
1428     log_info("hfp_setup_synchronous_connection using setting nr %u", setting);
1429     sco_establishment_active = hfp_connection;
1430     uint16_t sco_voice_setting = hci_get_sco_voice_setting();
1431     if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
1432         sco_voice_setting = 0x0043; // Transparent data
1433     }
1434     hci_send_cmd(&hci_setup_synchronous_connection, hfp_connection->acl_handle, 8000, 8000, hfp_link_settings[setting].max_latency,
1435         sco_voice_setting, hfp_link_settings[setting].retransmission_effort, hfp_link_settings[setting].packet_types); // all types 0x003f, only 2-ev3 0x380
1436 }
1437 
1438 void hfp_set_packet_handler_for_rfcomm_connections(btstack_packet_handler_t handler){
1439     rfcomm_packet_handler = handler;
1440 }
1441 
1442