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