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