xref: /btstack/src/classic/hfp.c (revision f05358500e612946f8c340b1f11e5703dafd65f8)
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 BLUEKITCHEN
24  * GMBH 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 <string.h>
46 #include <inttypes.h>
47 
48 #include "bluetooth_sdp.h"
49 #include "btstack_debug.h"
50 #include "btstack_event.h"
51 #include "btstack_memory.h"
52 #include "btstack_run_loop.h"
53 #include "classic/sdp_client_rfcomm.h"
54 #include "classic/sdp_server.h"
55 #include "classic/sdp_util.h"
56 #include "classic/sdp_client.h"
57 #include "hci.h"
58 #include "hci_cmd.h"
59 #include "hci_dump.h"
60 
61 #if defined(ENABLE_CC256X_ASSISTED_HFP) && !defined(ENABLE_SCO_OVER_PCM)
62 #error "Assisted HFP is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM"
63 #endif
64 
65 #if defined(ENABLE_BCM_PCM_WBS) && !defined(ENABLE_SCO_OVER_PCM)
66 #error "WBS for PCM is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM"
67 #endif
68 
69 #define HFP_HF_FEATURES_SIZE 10
70 #define HFP_AG_FEATURES_SIZE 12
71 
72 typedef struct {
73     hfp_role_t local_role;
74     bd_addr_t  remote_address;
75 } hfp_sdp_query_context_t;
76 
77 // globals
78 
79 static btstack_linked_list_t hfp_connections ;
80 
81 static btstack_packet_handler_t hfp_hf_callback;
82 static btstack_packet_handler_t hfp_ag_callback;
83 
84 static btstack_packet_handler_t hfp_hf_rfcomm_packet_handler;
85 static btstack_packet_handler_t hfp_ag_rfcomm_packet_handler;
86 
87 static uint8_t  hfp_hf_indicators_nr;
88 static const uint8_t * hfp_hf_indicators;
89 
90 static uint16_t hfp_allowed_sco_packet_types;
91 static hfp_connection_t * hfp_sco_establishment_active;
92 
93 static hfp_sdp_query_context_t                 hfp_sdp_query_context;
94 static btstack_context_callback_registration_t hfp_sdp_query_request;
95 
96 
97 
98 
99 
100 // custom commands
101 static btstack_linked_list_t hfp_custom_commands_ag;
102 static btstack_linked_list_t hfp_custom_commands_hf;
103 
104 // prototypes
105 static hfp_link_settings_t hfp_next_link_setting_for_connection(hfp_link_settings_t current_setting, hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported);
106 static void parse_sequence(hfp_connection_t * context);
107 
108 
109 #define CODEC_MASK_CVSD   (1 << HFP_CODEC_CVSD)
110 #define CODEC_MASK_OTHER ((1 << HFP_CODEC_MSBC) | (1 << HFP_CODEC_LC3_SWB))
111 
112 static const struct {
113     const uint16_t max_latency;
114     const uint8_t  retransmission_effort;
115     const uint16_t packet_types;
116     const uint8_t  codec_mask;
117 } hfp_link_settings [] = {
118         {0x0004, 0xff, SCO_PACKET_TYPES_HV1,  CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_D0
119         {0x0005, 0xff, SCO_PACKET_TYPES_HV3,  CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_D1
120         {0x0007, 0x01, SCO_PACKET_TYPES_EV3,  CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_S1
121         {0x0007, 0x01, SCO_PACKET_TYPES_2EV3, CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_S2
122         {0x000a, 0x01, SCO_PACKET_TYPES_2EV3, CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_S3
123         {0x000c, 0x02, SCO_PACKET_TYPES_2EV3, CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_S4
124         {0x0008, 0x02, SCO_PACKET_TYPES_EV3,  CODEC_MASK_OTHER}, // HFP_LINK_SETTINGS_T1
125         {0x000d, 0x02, SCO_PACKET_TYPES_2EV3, CODEC_MASK_OTHER}  // HFP_LINK_SETTINGS_T2
126 };
127 
128 #ifdef ENABLE_HFP_HF_SAFE_SETTINGS
129 // HFP v1.9, table 6.10 'mandatory safe settings' for eSCO + similar entries for SCO
130 static const struct hfp_mandatory_safe_setting {
131     const uint8_t codec_mask;
132     const bool secure_connection_in_use;
133     hfp_link_settings_t link_setting;
134 } hfp_mandatory_safe_settings[] = {
135         { CODEC_MASK_CVSD,  false, HFP_LINK_SETTINGS_D1},
136         { CODEC_MASK_CVSD,  true,  HFP_LINK_SETTINGS_D1},
137         { CODEC_MASK_CVSD,  false, HFP_LINK_SETTINGS_S1},
138         { CODEC_MASK_CVSD,  true,  HFP_LINK_SETTINGS_S4},
139         { CODEC_MASK_OTHER, false, HFP_LINK_SETTINGS_T1},
140         { CODEC_MASK_OTHER, true,  HFP_LINK_SETTINGS_T2},
141 };
142 #endif
143 
144 static const char * hfp_hf_features[] = {
145         "EC and/or NR function",
146         "Three-way calling",
147         "CLI presentation capability",
148         "Voice recognition activation",
149         "Remote volume control",
150 
151         "Enhanced call status",
152         "Enhanced call control",
153 
154         "Codec negotiation",
155 
156         "HF Indicators",
157         "eSCO S4 (and T2) Settings Supported",
158         "Reserved for future definition"
159 };
160 
161 static const char * hfp_ag_features[] = {
162         "Three-way calling",
163         "EC and/or NR function",
164         "Voice recognition function",
165         "In-band ring tone capability",
166         "Attach a number to a voice tag",
167         "Ability to reject a call",
168         "Enhanced call status",
169         "Enhanced call control",
170         "Extended Error Result Codes",
171         "Codec negotiation",
172         "HF Indicators",
173         "eSCO S4 (and T2) Settings Supported",
174         "Reserved for future definition"
175 };
176 
177 static const char * hfp_enhanced_call_dir[] = {
178         "outgoing",
179         "incoming"
180 };
181 
182 static const char * hfp_enhanced_call_status[] = {
183         "active",
184         "held",
185         "outgoing dialing",
186         "outgoing alerting",
187         "incoming",
188         "incoming waiting",
189         "call held by response and hold"
190 };
191 
192 static const char * hfp_enhanced_call_mode[] = {
193         "voice",
194         "data",
195         "fax"
196 };
197 
198 static const char * hfp_enhanced_call_mpty[] = {
199         "not a conference call",
200         "conference call"
201 };
202 
203 const char * hfp_enhanced_call_dir2str(uint16_t index){
204     if (index <= HFP_ENHANCED_CALL_DIR_INCOMING) return hfp_enhanced_call_dir[index];
205     return "not defined";
206 }
207 
208 const char * hfp_enhanced_call_status2str(uint16_t index){
209     if (index <= HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD) return hfp_enhanced_call_status[index];
210     return "not defined";
211 }
212 
213 const char * hfp_enhanced_call_mode2str(uint16_t index){
214     if (index <= HFP_ENHANCED_CALL_MODE_FAX) return hfp_enhanced_call_mode[index];
215     return "not defined";
216 }
217 
218 const char * hfp_enhanced_call_mpty2str(uint16_t index){
219     if (index <= HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL) return hfp_enhanced_call_mpty[index];
220     return "not defined";
221 }
222 
223 static uint16_t hfp_parse_indicator_index(hfp_connection_t * hfp_connection){
224     uint16_t index = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
225 
226     if (index > HFP_MAX_NUM_INDICATORS){
227         log_info("ignoring invalid indicator index bigger then HFP_MAX_NUM_INDICATORS");
228         return HFP_MAX_NUM_INDICATORS - 1;
229     }
230 
231     // indicator index enumeration starts with 1, we substract 1 to store in array with starting index 0
232     if (index > 0){
233         index -= 1;
234     } else {
235         log_info("ignoring invalid indicator index 0");
236         return 0;
237     }
238     return index;
239 }
240 
241 static void hfp_next_indicators_index(hfp_connection_t * hfp_connection){
242     if (hfp_connection->parser_item_index < HFP_MAX_NUM_INDICATORS - 1){
243         hfp_connection->parser_item_index++;
244     } else {
245         log_info("Ignoring additional indicator");
246     }
247 }
248 
249 static void hfp_next_codec_index(hfp_connection_t * hfp_connection){
250     if (hfp_connection->parser_item_index < HFP_MAX_NUM_CODECS - 1){
251         hfp_connection->parser_item_index++;
252     } else {
253         log_info("Ignoring additional codec index");
254     }
255 }
256 
257 static void hfp_next_remote_call_services_index(hfp_connection_t * hfp_connection){
258     if (hfp_connection->remote_call_services_index < HFP_MAX_NUM_CALL_SERVICES - 1){
259         hfp_connection->remote_call_services_index++;
260     } else {
261         log_info("Ignoring additional remote_call_services");
262     }
263 }
264 
265 const char * hfp_hf_feature(int index){
266     if (index > HFP_HF_FEATURES_SIZE){
267         return hfp_hf_features[HFP_HF_FEATURES_SIZE];
268     }
269     return hfp_hf_features[index];
270 }
271 
272 const char * hfp_ag_feature(int index){
273     if (index > HFP_AG_FEATURES_SIZE){
274         return hfp_ag_features[HFP_AG_FEATURES_SIZE];
275     }
276     return hfp_ag_features[index];
277 }
278 
279 int send_str_over_rfcomm(uint16_t cid, const char * command){
280     if (!rfcomm_can_send_packet_now(cid)) return 1;
281     log_info("HFP_TX %s", command);
282     int err = rfcomm_send(cid, (uint8_t*) command, (uint16_t) strlen(command));
283     if (err){
284         log_error("rfcomm_send -> error 0x%02x \n", err);
285     }
286 #ifdef ENABLE_HFP_AT_MESSAGES
287     hfp_connection_t * hfp_connection = get_hfp_connection_context_for_rfcomm_cid(cid);
288     hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_AT_MESSAGE_SENT, command);
289 #endif
290     return 1;
291 }
292 
293 int hfp_supports_codec(uint8_t codec, int codecs_nr, uint8_t * codecs){
294 
295     // mSBC requires support for eSCO connections
296     if ((codec == HFP_CODEC_MSBC) && !hci_extended_sco_link_supported()) return 0;
297 
298     int i;
299     for (i = 0; i < codecs_nr; i++){
300         if (codecs[i] != codec) continue;
301         return 1;
302     }
303     return 0;
304 }
305 
306 void hfp_hf_drop_mSBC_if_eSCO_not_supported(uint8_t * codecs, uint8_t * codecs_nr){
307     if (hci_extended_sco_link_supported()) return;
308     uint8_t i;
309     int filtered_codec_count = 0;
310     for (i=0; i < *codecs_nr; i++){
311         if (codecs[i] != HFP_CODEC_MSBC) {
312             codecs[filtered_codec_count++] = codecs[i];
313         }
314     }
315     *codecs_nr = filtered_codec_count;
316 }
317 
318 // UTILS
319 int get_bit(uint16_t bitmap, int position){
320     return (bitmap >> position) & 1;
321 }
322 
323 int store_bit(uint32_t bitmap, int position, uint8_t value){
324     if (value){
325         bitmap |= 1 << position;
326     } else {
327         bitmap &= ~ (1 << position);
328     }
329     return bitmap;
330 }
331 
332 int join(char * buffer, int buffer_size, uint8_t * values, int values_nr){
333     if (buffer_size < (values_nr * 3)) return 0;
334     int i;
335     int offset = 0;
336     for (i = 0; i < (values_nr-1); i++) {
337       offset += snprintf(buffer+offset, buffer_size-offset, "%d,", values[i]); // puts string into buffer
338     }
339     if (i<values_nr){
340         offset += snprintf(buffer+offset, buffer_size-offset, "%d", values[i]);
341     }
342     return offset;
343 }
344 
345 int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){
346     if (buffer_size < (values_nr * 3)) return 0;
347 
348     int i;
349     int offset = 0;
350     for (i = 0; i < (values_nr-1); i++) {
351       offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_bit(values,i)); // puts string into buffer
352     }
353 
354     if (i<values_nr){
355         offset += snprintf(buffer+offset, buffer_size-offset, "%d", get_bit(values,i));
356     }
357     return offset;
358 }
359 static void hfp_emit_event_for_role(hfp_role_t local_role, uint8_t * packet, uint16_t size){
360     switch (local_role){
361         case HFP_ROLE_HF:
362             (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, packet, size);
363             break;
364         case HFP_ROLE_AG:
365             (*hfp_ag_callback)(HCI_EVENT_PACKET, 0, packet, size);
366             break;
367         default:
368             btstack_unreachable();
369             break;
370     }
371 }
372 
373 static void hfp_emit_event_for_context(hfp_connection_t * hfp_connection, uint8_t * packet, uint16_t size){
374     if (!hfp_connection) return;
375     hfp_emit_event_for_role(hfp_connection->local_role, packet, size);
376 }
377 
378 void hfp_emit_simple_event(hfp_connection_t * hfp_connection, uint8_t event_subtype){
379     hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
380     uint8_t event[5];
381     event[0] = HCI_EVENT_HFP_META;
382     event[1] = sizeof(event) - 2;
383     event[2] = event_subtype;
384     little_endian_store_16(event, 3, acl_handle);
385     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
386 }
387 
388 void hfp_emit_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, uint8_t value){
389     hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
390     uint8_t event[6];
391     event[0] = HCI_EVENT_HFP_META;
392     event[1] = sizeof(event) - 2;
393     event[2] = event_subtype;
394     little_endian_store_16(event, 3, acl_handle);
395     event[5] = value; // status 0 == OK
396     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
397 }
398 
399 void hfp_emit_voice_recognition_enabled(hfp_connection_t * hfp_connection, uint8_t status){
400     btstack_assert(hfp_connection != NULL);
401 
402     uint8_t event[7];
403     event[0] = HCI_EVENT_HFP_META;
404     event[1] = sizeof(event) - 2;
405     event[2] = HFP_SUBEVENT_VOICE_RECOGNITION_ACTIVATED;
406 
407     little_endian_store_16(event, 3, hfp_connection->acl_handle);
408     event[5] = status; // 0:success
409     event[6] = hfp_connection->enhanced_voice_recognition_enabled ? 1 : 0;
410     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
411 }
412 
413 void hfp_emit_voice_recognition_disabled(hfp_connection_t * hfp_connection, uint8_t status){
414     btstack_assert(hfp_connection != NULL);
415 
416     uint8_t event[6];
417     event[0] = HCI_EVENT_HFP_META;
418     event[1] = sizeof(event) - 2;
419     event[2] = HFP_SUBEVENT_VOICE_RECOGNITION_DEACTIVATED;
420 
421     little_endian_store_16(event, 3, hfp_connection->acl_handle);
422     event[5] = status; // 0:success
423     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
424 }
425 
426 void hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection_t * hfp_connection, uint8_t status){
427     hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
428 
429     uint8_t event[6];
430     event[0] = HCI_EVENT_HFP_META;
431     event[1] = sizeof(event) - 2;
432     event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_HF_READY_FOR_AUDIO;
433     little_endian_store_16(event, 3, acl_handle);
434     event[5] = status;
435     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
436 }
437 
438 void hfp_emit_enhanced_voice_recognition_state_event(hfp_connection_t * hfp_connection, uint8_t status){
439     hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
440 
441     uint8_t event[6];
442     event[0] = HCI_EVENT_HFP_META;
443     event[1] = sizeof(event) - 2;
444     switch (hfp_connection->ag_vra_state){
445         case HFP_VOICE_RECOGNITION_STATE_AG_READY_TO_ACCEPT_AUDIO_INPUT:
446             event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_READY_TO_ACCEPT_AUDIO_INPUT;
447             break;
448         case HFP_VOICE_RECOGNITION_STATE_AG_IS_STARTING_SOUND:
449             event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_IS_STARTING_SOUND;
450             break;
451         case HFP_VOICE_RECOGNITION_STATE_AG_IS_PROCESSING_AUDIO_INPUT:
452             event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_IS_PROCESSING_AUDIO_INPUT;
453             break;
454         default:
455             btstack_unreachable();
456             break;
457     }
458 
459     little_endian_store_16(event, 3, acl_handle);
460     event[5] = status;
461     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
462 }
463 
464 void hfp_emit_slc_connection_event(hfp_role_t local_role, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr){
465     uint8_t event[12];
466     int pos = 0;
467     event[pos++] = HCI_EVENT_HFP_META;
468     event[pos++] = sizeof(event) - 2;
469     event[pos++] = HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
470     little_endian_store_16(event, pos, con_handle);
471     pos += 2;
472     event[pos++] = status; // status 0 == OK
473     reverse_bd_addr(addr,&event[pos]);
474     pos += 6;
475     hfp_emit_event_for_role(local_role, event, sizeof(event));
476 }
477 
478 static void hfp_emit_audio_connection_released(hfp_connection_t * hfp_connection, hci_con_handle_t sco_handle){
479     btstack_assert(hfp_connection != NULL);
480     uint8_t event[7];
481     int pos = 0;
482     event[pos++] = HCI_EVENT_HFP_META;
483     event[pos++] = sizeof(event) - 2;
484     event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED;
485     little_endian_store_16(event, pos, hfp_connection->acl_handle);
486     pos += 2;
487     little_endian_store_16(event, pos, sco_handle);
488     pos += 2;
489     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
490 }
491 
492 void hfp_emit_sco_connection_established(hfp_connection_t *hfp_connection, uint8_t status, uint8_t negotiated_codec,
493                                          uint16_t rx_packet_length, uint16_t tx_packet_length) {
494     btstack_assert(hfp_connection != NULL);
495     uint8_t event[21];
496     int pos = 0;
497     event[pos++] = HCI_EVENT_HFP_META;
498     event[pos++] = sizeof(event) - 2;
499     event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED;
500     little_endian_store_16(event, pos, hfp_connection->acl_handle);
501     pos += 2;
502     event[pos++] = status; // status 0 == OK
503     little_endian_store_16(event, pos, hfp_connection->sco_handle);
504     pos += 2;
505     reverse_bd_addr(hfp_connection->remote_addr,&event[pos]);
506     pos += 6;
507     event[pos++] = negotiated_codec;
508     little_endian_store_16(event, pos, hfp_connection->packet_types);
509     pos += 2;
510     little_endian_store_16(event, pos, rx_packet_length);
511     pos += 2;
512     little_endian_store_16(event, pos, tx_packet_length);
513     pos += 2;
514     hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
515 }
516 
517 void hfp_emit_string_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, const char * value){
518     btstack_assert(hfp_connection != NULL);
519 #ifdef ENABLE_HFP_AT_MESSAGES
520     uint8_t event[256];
521 #else
522     uint8_t event[40];
523 #endif
524     uint16_t string_len = btstack_min((uint16_t) strlen(value), sizeof(event) - 6);
525     event[0] = HCI_EVENT_HFP_META;
526     event[1] = 4 + string_len;
527     event[2] = event_subtype;
528     little_endian_store_16(event, 3, hfp_connection->acl_handle);
529     memcpy((char*)&event[5], value, string_len);
530     event[5 + string_len] = 0;
531     hfp_emit_event_for_context(hfp_connection, event, 6 + string_len);
532 }
533 
534 btstack_linked_list_t * hfp_get_connections(void){
535     return (btstack_linked_list_t *) &hfp_connections;
536 }
537 
538 hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){
539     btstack_linked_list_iterator_t it;
540     btstack_linked_list_iterator_init(&it, hfp_get_connections());
541     while (btstack_linked_list_iterator_has_next(&it)){
542         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
543         if (hfp_connection->rfcomm_cid == cid){
544             return hfp_connection;
545         }
546     }
547     return NULL;
548 }
549 
550 hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t hfp_role){
551     btstack_linked_list_iterator_t it;
552     btstack_linked_list_iterator_init(&it, hfp_get_connections());
553     while (btstack_linked_list_iterator_has_next(&it)){
554         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
555         if ((memcmp(hfp_connection->remote_addr, bd_addr, 6) == 0) && (hfp_connection->local_role == hfp_role)) {
556             return hfp_connection;
557         }
558     }
559     return NULL;
560 }
561 
562 hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle, hfp_role_t hfp_role){
563     btstack_linked_list_iterator_t it;
564     btstack_linked_list_iterator_init(&it, hfp_get_connections());
565     while (btstack_linked_list_iterator_has_next(&it)){
566         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
567         if ((hfp_connection->sco_handle == handle) && (hfp_connection->local_role == hfp_role)){
568             return hfp_connection;
569         }
570     }
571     return NULL;
572 }
573 
574 hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle, hfp_role_t hfp_role){
575     btstack_linked_list_iterator_t it;
576     btstack_linked_list_iterator_init(&it, hfp_get_connections());
577     while (btstack_linked_list_iterator_has_next(&it)){
578         hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
579         if ((hfp_connection->acl_handle == handle) && (hfp_connection->local_role == hfp_role)){
580             return hfp_connection;
581         }
582     }
583     return NULL;
584 }
585 
586 
587 static void hfp_reset_voice_recognition(hfp_connection_t * hfp_connection){
588     btstack_assert(hfp_connection != NULL);
589     hfp_voice_recognition_activation_status_t current_vra_state = hfp_connection->vra_state;
590     hfp_connection->vra_state = HFP_VRA_VOICE_RECOGNITION_OFF;
591 
592     if (current_vra_state != HFP_VRA_VOICE_RECOGNITION_OFF){
593         hfp_emit_voice_recognition_disabled(hfp_connection, ERROR_CODE_SUCCESS);
594     } else if (hfp_connection->vra_state_requested != HFP_VRA_VOICE_RECOGNITION_OFF){
595         hfp_emit_voice_recognition_disabled(hfp_connection, ERROR_CODE_SUCCESS);
596     }
597 
598     hfp_connection->vra_state_requested = HFP_VRA_VOICE_RECOGNITION_OFF;
599     hfp_connection->activate_voice_recognition = false;
600     hfp_connection->deactivate_voice_recognition = false;
601     hfp_connection->enhanced_voice_recognition_enabled = false;
602     hfp_connection->ag_vra_status = 0;
603     hfp_connection->ag_vra_state = HFP_VOICE_RECOGNITION_STATE_AG_READY;
604 }
605 
606 void hfp_reset_context_flags(hfp_connection_t * hfp_connection){
607     if (!hfp_connection) return;
608     hfp_connection->ok_pending = 0;
609     hfp_connection->send_error = 0;
610 
611     hfp_connection->found_equal_sign = false;
612 
613     hfp_connection->change_status_update_for_individual_ag_indicators = 0;
614     hfp_connection->operator_name_changed = 0;
615 
616     hfp_connection->enable_extended_audio_gateway_error_report = 0;
617     hfp_connection->extended_audio_gateway_error = 0;
618 
619     // establish codecs hfp_connection
620     hfp_connection->suggested_codec = 0;
621     hfp_connection->negotiated_codec = 0;
622     hfp_connection->codec_confirmed = 0;
623 
624     hfp_connection->establish_audio_connection = 0;
625     hfp_connection->call_waiting_notification_enabled = 0;
626     hfp_connection->command = HFP_CMD_NONE;
627     hfp_connection->enable_status_update_for_ag_indicators = 0xFF;
628     hfp_connection->clip_have_alpha = false;
629     hfp_reset_voice_recognition(hfp_connection);
630 }
631 
632 static hfp_connection_t * create_hfp_connection_context(void){
633     hfp_connection_t * hfp_connection = btstack_memory_hfp_connection_get();
634     if (!hfp_connection) return NULL;
635 
636     hfp_connection->state = HFP_IDLE;
637     hfp_connection->call_state = HFP_CALL_IDLE;
638     hfp_connection->codecs_state = HFP_CODECS_IDLE;
639 
640     hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
641 
642     hfp_connection->acl_handle = HCI_CON_HANDLE_INVALID;
643     hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID;
644 
645     hfp_reset_context_flags(hfp_connection);
646 
647     btstack_linked_list_add(&hfp_connections, (btstack_linked_item_t*)hfp_connection);
648     return hfp_connection;
649 }
650 
651 void hfp_finalize_connection_context(hfp_connection_t * hfp_connection){
652     btstack_linked_list_remove(&hfp_connections, (btstack_linked_item_t*) hfp_connection);
653     btstack_memory_hfp_connection_free(hfp_connection);
654 }
655 
656 static hfp_connection_t * hfp_create_connection(bd_addr_t bd_addr, hfp_role_t local_role){
657     hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr, local_role);
658     if (hfp_connection) return  hfp_connection;
659     hfp_connection = create_hfp_connection_context();
660     if (!hfp_connection) {
661         return NULL;
662     }
663     (void)memcpy(hfp_connection->remote_addr, bd_addr, 6);
664     hfp_connection->local_role = local_role;
665     log_info("Create HFP context %p: role %u, addr %s", hfp_connection, local_role, bd_addr_to_str(bd_addr));
666 
667 #ifdef ENABLE_NXP_PCM_WBS
668     hfp_connection->nxp_start_audio_handle = HCI_CON_HANDLE_INVALID;
669     hfp_connection->nxp_stop_audio_handle = HCI_CON_HANDLE_INVALID;
670 #endif
671 
672     return hfp_connection;
673 }
674 
675 /* @param network.
676  * 0 == no ability to reject a call.
677  * 1 == ability to reject a call.
678  */
679 
680 /* @param suported_features
681  * HF bit 0: EC and/or NR function (yes/no, 1 = yes, 0 = no)
682  * HF bit 1: Call waiting or three-way calling(yes/no, 1 = yes, 0 = no)
683  * HF bit 2: CLI presentation capability (yes/no, 1 = yes, 0 = no)
684  * HF bit 3: Voice recognition activation (yes/no, 1= yes, 0 = no)
685  * HF bit 4: Remote volume control (yes/no, 1 = yes, 0 = no)
686  * HF bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
687  */
688  /* Bit position:
689  * AG bit 0: Three-way calling (yes/no, 1 = yes, 0 = no)
690  * AG bit 1: EC and/or NR function (yes/no, 1 = yes, 0 = no)
691  * AG bit 2: Voice recognition function (yes/no, 1 = yes, 0 = no)
692  * AG bit 3: In-band ring tone capability (yes/no, 1 = yes, 0 = no)
693  * AG bit 4: Attach a phone number to a voice tag (yes/no, 1 = yes, 0 = no)
694  * AG bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
695  */
696 
697 void hfp_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t service_uuid, int rfcomm_channel_nr, const char * name){
698     uint8_t* attribute;
699     de_create_sequence(service);
700 
701     // 0x0000 "Service Record Handle"
702     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
703     de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
704 
705     // 0x0001 "Service Class ID List"
706     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
707     attribute = de_push_sequence(service);
708     {
709         //  "UUID for Service"
710         de_add_number(attribute, DE_UUID, DE_SIZE_16, service_uuid);
711         de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_GENERIC_AUDIO);
712     }
713     de_pop_sequence(service, attribute);
714 
715     // 0x0004 "Protocol Descriptor List"
716     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
717     attribute = de_push_sequence(service);
718     {
719         uint8_t* l2cpProtocol = de_push_sequence(attribute);
720         {
721             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
722         }
723         de_pop_sequence(attribute, l2cpProtocol);
724 
725         uint8_t* rfcomm = de_push_sequence(attribute);
726         {
727             de_add_number(rfcomm,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_RFCOMM);  // rfcomm_service
728             de_add_number(rfcomm,  DE_UINT, DE_SIZE_8,  rfcomm_channel_nr);  // rfcomm channel
729         }
730         de_pop_sequence(attribute, rfcomm);
731     }
732     de_pop_sequence(service, attribute);
733 
734 
735     // 0x0005 "Public Browse Group"
736     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group
737     attribute = de_push_sequence(service);
738     {
739         de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT);
740     }
741     de_pop_sequence(service, attribute);
742 
743     // 0x0009 "Bluetooth Profile Descriptor List"
744     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
745     attribute = de_push_sequence(service);
746     {
747         uint8_t *sppProfile = de_push_sequence(attribute);
748         {
749             de_add_number(sppProfile,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HANDSFREE);
750             de_add_number(sppProfile,  DE_UINT, DE_SIZE_16, 0x0109); // Version 1.9
751         }
752         de_pop_sequence(attribute, sppProfile);
753     }
754     de_pop_sequence(service, attribute);
755 
756     // 0x0100 "Service Name"
757     if (strlen(name) > 0){
758         de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
759         de_add_data(service,  DE_STRING, (uint16_t) strlen(name), (uint8_t *) name);
760     }
761 }
762 
763 static void hfp_handle_slc_setup_error(hfp_connection_t * hfp_connection, uint8_t status){
764     // cache fields for event
765     hfp_role_t local_role = hfp_connection->local_role;
766     bd_addr_t remote_addr;
767     // cppcheck-suppress uninitvar ; remote_addr is reported as uninitialized although it's the destination of the memcpy
768     (void)memcpy(remote_addr, hfp_connection->remote_addr, 6);
769     // finalize connection struct
770     hfp_finalize_connection_context(hfp_connection);
771     // emit event
772     hfp_emit_slc_connection_event(local_role, status, HCI_CON_HANDLE_INVALID, remote_addr);
773 }
774 
775 static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
776     UNUSED(packet_type);    // ok: handling own sdp events
777     UNUSED(channel);        // ok: no channel
778     UNUSED(size);           // ok: handling own sdp events
779 
780     hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(hfp_sdp_query_context.remote_address, hfp_sdp_query_context.local_role);
781     if (hfp_connection == NULL) {
782         log_info("connection with %s and local role %d not found", hfp_sdp_query_context.remote_address, hfp_sdp_query_context.local_role);
783         return;
784     }
785 
786     switch (hci_event_packet_get_type(packet)){
787         case SDP_EVENT_QUERY_RFCOMM_SERVICE:
788             hfp_connection->rfcomm_channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet);
789             break;
790         case SDP_EVENT_QUERY_COMPLETE:
791             if (hfp_connection->rfcomm_channel_nr > 0){
792                 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
793                 btstack_packet_handler_t packet_handler;
794                 switch (hfp_connection->local_role){
795                     case HFP_ROLE_AG:
796                         packet_handler = hfp_ag_rfcomm_packet_handler;
797                         break;
798                     case HFP_ROLE_HF:
799                         packet_handler = hfp_hf_rfcomm_packet_handler;
800                         break;
801                     default:
802                         btstack_assert(false);
803                         return;
804                 }
805 
806                 rfcomm_create_channel(packet_handler, hfp_connection->remote_addr, hfp_connection->rfcomm_channel_nr, NULL);
807 
808             } else {
809                 uint8_t status = sdp_event_query_complete_get_status(packet);
810                 if (status == ERROR_CODE_SUCCESS){
811                     // report service not found
812                     status = SDP_SERVICE_NOT_FOUND;
813                 }
814                 hfp_handle_slc_setup_error(hfp_connection, status);
815                 log_info("rfcomm service not found, status 0x%02x", status);
816             }
817 
818             // register the SDP Query request to check if there is another connection waiting for the query
819             // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
820             (void) sdp_client_register_query_callback(&hfp_sdp_query_request);
821             break;
822         default:
823             break;
824     }
825 }
826 
827 // returns 0 if unexpected error or no other link options remained, otherwise 1
828 static int hfp_handle_failed_sco_connection(uint8_t status){
829 
830     if (hfp_sco_establishment_active->accept_sco != 0){
831         log_info("(e)SCO Connection failed but not started by us");
832         return 0;
833     }
834 
835     log_info("(e)SCO Connection failed 0x%02x", status);
836     switch (status){
837         case ERROR_CODE_INVALID_LMP_PARAMETERS_INVALID_LL_PARAMETERS:
838         case ERROR_CODE_SCO_AIR_MODE_REJECTED:
839         case ERROR_CODE_SCO_INTERVAL_REJECTED:
840         case ERROR_CODE_SCO_OFFSET_REJECTED:
841         case ERROR_CODE_UNSPECIFIED_ERROR:
842         case ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE:
843         case ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE_UNSUPPORTED_LMP_FEATURE:
844             break;
845         default:
846             return 0;
847     }
848 
849     // note: eSCO_S4 supported flag not available, but it's only relevant for highest CVSD link setting (and the current failed)
850     hfp_link_settings_t next_setting = hfp_next_link_setting_for_connection(hfp_sco_establishment_active->link_setting, hfp_sco_establishment_active, false);
851 
852     // handle no valid setting found
853     if (next_setting == HFP_LINK_SETTINGS_NONE) {
854         if (hfp_sco_establishment_active->negotiated_codec == HFP_CODEC_MSBC){
855             log_info("T2/T1 failed, fallback to CVSD - D1");
856             hfp_sco_establishment_active->negotiated_codec = HFP_CODEC_CVSD;
857             hfp_sco_establishment_active->sco_for_msbc_failed = 1;
858             hfp_sco_establishment_active->ag_send_common_codec = true;
859             hfp_sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1;
860         } else {
861             // no other options
862             return 0;
863         }
864     }
865 
866     log_info("e)SCO Connection: try new link_setting %d", next_setting);
867     hfp_sco_establishment_active->establish_audio_connection = 1;
868     hfp_sco_establishment_active->link_setting = next_setting;
869     hfp_sco_establishment_active->accept_sco = 0;
870     hfp_sco_establishment_active = NULL;
871     return 1;
872 }
873 
874 void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){
875     UNUSED(packet_type);
876     UNUSED(channel);    // ok: no channel
877     UNUSED(size);
878 
879     bd_addr_t event_addr;
880     hci_con_handle_t handle;
881     hfp_connection_t * hfp_connection = NULL;
882     uint8_t status;
883 
884     log_debug("HFP HCI event handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
885 
886     switch (hci_event_packet_get_type(packet)) {
887 
888         case HCI_EVENT_CONNECTION_REQUEST:
889             switch(hci_event_connection_request_get_link_type(packet)){
890                 case 0: //  SCO
891                 case 2: // eSCO
892                     hci_event_connection_request_get_bd_addr(packet, event_addr);
893                     hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
894                     if (!hfp_connection) break;
895                     if (hci_event_connection_request_get_link_type(packet) == 2){
896                         hfp_connection->accept_sco = 2;
897                     } else {
898                         hfp_connection->accept_sco = 1;
899                     }
900                     // configure SBC coded if needed
901                     hfp_prepare_for_sco(hfp_connection);
902                     log_info("accept sco %u\n", hfp_connection->accept_sco);
903                     break;
904                 default:
905                     break;
906             }
907             break;
908 
909         case HCI_EVENT_COMMAND_STATUS:
910             if (hci_event_command_status_get_command_opcode(packet) == hci_setup_synchronous_connection.opcode) {
911                 if (hfp_sco_establishment_active == NULL) break;
912                 status = hci_event_command_status_get_status(packet);
913                 if (status == ERROR_CODE_SUCCESS) break;
914 
915                 hfp_connection = hfp_sco_establishment_active;
916                 if (hfp_handle_failed_sco_connection(status)) break;
917 
918                 hfp_connection->accept_sco = 0;
919                 hfp_connection->establish_audio_connection = 0;
920                 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
921                 hfp_sco_establishment_active = NULL;
922                 hfp_emit_sco_connection_established(hfp_connection, status,
923                                                     hfp_connection->negotiated_codec, 0, 0);
924             }
925             break;
926 
927         case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
928             if (hfp_sco_establishment_active == NULL) break;
929 
930             hfp_connection = hfp_sco_establishment_active;
931 
932             status = hci_event_synchronous_connection_complete_get_status(packet);
933             if (status != ERROR_CODE_SUCCESS){
934                 if (hfp_handle_failed_sco_connection(status)) break;
935 
936                 hfp_connection->accept_sco = 0;
937                 hfp_connection->establish_audio_connection = 0;
938                 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
939                 hfp_sco_establishment_active = NULL;
940                 hfp_emit_sco_connection_established(hfp_connection, status,
941                                                     hfp_connection->negotiated_codec, 0, 0);
942                 break;
943             }
944 
945             uint16_t sco_handle = hci_event_synchronous_connection_complete_get_handle(packet);
946             uint8_t  link_type = hci_event_synchronous_connection_complete_get_link_type(packet);
947             uint8_t  transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet);  // measured in slots
948             uint8_t  retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots
949             uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes
950             uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes
951 
952             switch (link_type){
953                 case 0x00:
954                     log_info("SCO Connection established.");
955                     if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
956                     if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);
957                     if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length);
958                     if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length);
959                     break;
960                 case 0x02:
961                     log_info("eSCO Connection established. \n");
962                     break;
963                 default:
964                     log_error("(e)SCO reserved link_type 0x%2x", link_type);
965                     break;
966             }
967 
968             log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, "
969                  " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle,
970                  bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length,
971                  hci_event_synchronous_connection_complete_get_air_mode(packet));
972 
973             if (hfp_connection->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
974                 log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN");
975                 hfp_connection->state = HFP_W2_DISCONNECT_SCO;
976                 break;
977             }
978             hfp_connection->sco_handle = sco_handle;
979             hfp_connection->accept_sco = 0;
980             hfp_connection->establish_audio_connection = 0;
981 
982             hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
983 
984             switch (hfp_connection->vra_state){
985                 case HFP_VRA_VOICE_RECOGNITION_ACTIVATED:
986                     hfp_connection->ag_audio_connection_opened_before_vra = false;
987                     break;
988                 default:
989                     hfp_connection->ag_audio_connection_opened_before_vra = true;
990                     break;
991             }
992 
993             hfp_sco_establishment_active = NULL;
994 
995             hfp_emit_sco_connection_established(hfp_connection, status,
996                                                 hfp_connection->negotiated_codec, rx_packet_length, tx_packet_length);
997 
998 #ifdef ENABLE_NXP_PCM_WBS
999             hfp_connection->nxp_start_audio_handle = hfp_connection->sco_handle;
1000 #endif
1001             break;
1002         }
1003 
1004         case HCI_EVENT_DISCONNECTION_COMPLETE:
1005             handle = little_endian_read_16(packet,3);
1006             hfp_connection = get_hfp_connection_context_for_sco_handle(handle, local_role);
1007 
1008             if (!hfp_connection) break;
1009 
1010 #ifdef ENABLE_CC256X_ASSISTED_HFP
1011             hfp_connection->cc256x_send_wbs_disassociate = true;
1012 #endif
1013 #ifdef ENABLE_BCM_PCM_WBS
1014             hfp_connection->bcm_send_disable_wbs = true;
1015 #endif
1016 #ifdef ENABLE_NXP_PCM_WBS
1017             hfp_connection->nxp_stop_audio_handle = hfp_connection->sco_handle;
1018 #endif
1019 
1020             if (hfp_connection->sco_handle == handle){
1021                 hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID;
1022                 hfp_connection->release_audio_connection = 0;
1023                 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
1024                 hfp_emit_audio_connection_released(hfp_connection, handle);
1025 
1026                 hfp_connection->ag_audio_connection_opened_before_vra = false;
1027 
1028                 if (hfp_connection->acl_handle == HCI_CON_HANDLE_INVALID){
1029                     hfp_reset_voice_recognition(hfp_connection);
1030                     hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
1031                     hfp_finalize_connection_context(hfp_connection);
1032                     break;
1033                 } else if (hfp_connection->release_slc_connection == 1){
1034                     hfp_connection->release_slc_connection = 0;
1035                     hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
1036                     rfcomm_disconnect(hfp_connection->acl_handle);
1037                 }
1038             }
1039 
1040             if (hfp_connection->state == HFP_W4_SCO_DISCONNECTED_TO_SHUTDOWN){
1041                 // RFCOMM already closed -> remote power off
1042 #if defined(ENABLE_CC256X_ASSISTED_HFP) || defined (ENABLE_BCM_PCM_WBS)
1043                 hfp_connection->state = HFP_W4_WBS_SHUTDOWN;
1044 #else
1045                 hfp_finalize_connection_context(hfp_connection);
1046 #endif
1047                 break;
1048             }
1049             break;
1050 
1051         default:
1052             break;
1053     }
1054 }
1055 
1056 
1057 void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){
1058     UNUSED(packet_type);
1059     UNUSED(channel);    // ok: no channel
1060     UNUSED(size);
1061 
1062     bd_addr_t event_addr;
1063     uint16_t rfcomm_cid;
1064     hfp_connection_t * hfp_connection = NULL;
1065     uint8_t status;
1066 
1067     log_debug("HFP packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
1068 
1069     switch (hci_event_packet_get_type(packet)) {
1070 
1071         case RFCOMM_EVENT_INCOMING_CONNECTION:
1072             // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
1073             rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr);
1074             hfp_connection = hfp_create_connection(event_addr, local_role);
1075             if (!hfp_connection){
1076                 log_info("hfp: no memory to accept incoming connection - decline");
1077                 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet));
1078                 return;
1079             }
1080             if (hfp_connection->state != HFP_IDLE) {
1081                 log_error("hfp: incoming connection but not idle, reject");
1082                 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet));
1083                 return;
1084             }
1085 
1086             hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
1087             hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
1088             rfcomm_accept_connection(hfp_connection->rfcomm_cid);
1089             break;
1090 
1091         case RFCOMM_EVENT_CHANNEL_OPENED:
1092             rfcomm_event_channel_opened_get_bd_addr(packet, event_addr);
1093 
1094             hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
1095             btstack_assert(hfp_connection != NULL);
1096 
1097             if (hfp_connection->state != HFP_W4_RFCOMM_CONNECTED){
1098                 break;
1099             }
1100 
1101             status = rfcomm_event_channel_opened_get_status(packet);
1102             if (status != ERROR_CODE_SUCCESS) {
1103                 hfp_handle_slc_setup_error(hfp_connection, status);
1104                 break;
1105             }
1106 
1107             hfp_connection->acl_handle = rfcomm_event_channel_opened_get_con_handle(packet);
1108             hfp_connection->rfcomm_cid = rfcomm_event_channel_opened_get_rfcomm_cid(packet);
1109             hfp_connection->rfcomm_mtu = rfcomm_event_channel_opened_get_max_frame_size(packet);
1110             bd_addr_copy(hfp_connection->remote_addr, event_addr);
1111             hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
1112 
1113             rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
1114             break;
1115 
1116         case RFCOMM_EVENT_CHANNEL_CLOSED:
1117             rfcomm_cid = little_endian_read_16(packet,2);
1118             hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
1119             if (!hfp_connection) break;
1120             switch (hfp_connection->state){
1121                 case HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART:
1122                     hfp_connection->acl_handle = HCI_CON_HANDLE_INVALID;
1123                     hfp_connection->state = HFP_IDLE;
1124                     hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid, local_role);
1125                     break;
1126 
1127                 case HFP_AUDIO_CONNECTION_ESTABLISHED:
1128                     // service connection was released, this implicitly releases audio connection as well
1129                     hfp_connection->release_audio_connection = 0;
1130                     hfp_connection->acl_handle = HCI_CON_HANDLE_INVALID;
1131                     hfp_connection->state = HFP_W4_SCO_DISCONNECTED_TO_SHUTDOWN;
1132                     gap_disconnect(hfp_connection->sco_handle);
1133                     break;
1134 
1135                 default:
1136                     // regular case
1137                     hfp_reset_voice_recognition(hfp_connection);
1138                     hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
1139                     hfp_finalize_connection_context(hfp_connection);
1140                     break;
1141             }
1142             break;
1143 
1144         default:
1145             break;
1146     }
1147 }
1148 // translates command string into hfp_command_t CMD
1149 
1150 typedef struct {
1151     const char * command;
1152     hfp_command_t command_id;
1153 } hfp_command_entry_t;
1154 
1155 static hfp_command_entry_t hfp_ag_command_table[] = {
1156     { "AT+BAC=",   HFP_CMD_AVAILABLE_CODECS },
1157     { "AT+BCC",    HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP },
1158     { "AT+BCS=",   HFP_CMD_HF_CONFIRMED_CODEC },
1159     { "AT+BIA=",   HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, }, // +BIA:<enabled>,,<enabled>,,,<enabled>
1160     { "AT+BIEV=",  HFP_CMD_HF_INDICATOR_STATUS },
1161     { "AT+BIND=",  HFP_CMD_LIST_GENERIC_STATUS_INDICATORS },
1162     { "AT+BIND=?", HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS },
1163     { "AT+BIND?",  HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE },
1164     { "AT+BINP=",  HFP_CMD_HF_REQUEST_PHONE_NUMBER },
1165     { "AT+BLDN",   HFP_CMD_REDIAL_LAST_NUMBER },
1166     { "AT+BRSF=",  HFP_CMD_SUPPORTED_FEATURES },
1167     { "AT+BTRH=",  HFP_CMD_RESPONSE_AND_HOLD_COMMAND },
1168     { "AT+BTRH?",  HFP_CMD_RESPONSE_AND_HOLD_QUERY },
1169     { "AT+BVRA=",  HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION },
1170     { "AT+CCWA=",  HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION},
1171     { "AT+CHLD=",  HFP_CMD_CALL_HOLD },
1172     { "AT+CHLD=?", HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES },
1173     { "AT+CHUP",   HFP_CMD_HANG_UP_CALL },
1174     { "AT+CIND=?", HFP_CMD_RETRIEVE_AG_INDICATORS },
1175     { "AT+CIND?",  HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS },
1176     { "AT+CLCC",   HFP_CMD_LIST_CURRENT_CALLS },
1177     { "AT+CLIP=",  HFP_CMD_ENABLE_CLIP},
1178     { "AT+CMEE=",  HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR},
1179     { "AT+CMER=",  HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE },
1180     { "AT+CNUM",   HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION },
1181     { "AT+COPS=",  HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT },
1182     { "AT+COPS?",  HFP_CMD_QUERY_OPERATOR_SELECTION_NAME },
1183     { "AT+NREC=",  HFP_CMD_TURN_OFF_EC_AND_NR, },
1184     { "AT+VGM=",   HFP_CMD_SET_MICROPHONE_GAIN },
1185     { "AT+VGS=",   HFP_CMD_SET_SPEAKER_GAIN },
1186     { "AT+VTS=",   HFP_CMD_TRANSMIT_DTMF_CODES },
1187     { "ATA",       HFP_CMD_CALL_ANSWERED },
1188 };
1189 
1190 static hfp_command_entry_t hfp_hf_command_table[] = {
1191     { "+BCS:",  HFP_CMD_AG_SUGGESTED_CODEC },
1192     { "+BIND:", HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS },
1193     { "+BINP:", HFP_CMD_AG_SENT_PHONE_NUMBER },
1194     { "+BRSF:", HFP_CMD_SUPPORTED_FEATURES },
1195     { "+BSIR:", HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING },
1196     { "+BTRH:", HFP_CMD_RESPONSE_AND_HOLD_STATUS },
1197     { "+BVRA:", HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION },
1198     { "+CCWA:", HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE, },
1199     { "+CHLD:", HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES },
1200     { "+CIEV:", HFP_CMD_TRANSFER_AG_INDICATOR_STATUS},
1201     { "+CIND:", HFP_CMD_RETRIEVE_AG_INDICATORS_GENERIC },
1202     { "+CLCC:", HFP_CMD_LIST_CURRENT_CALLS },
1203     { "+CLIP:", HFP_CMD_AG_SENT_CLIP_INFORMATION },
1204     { "+CME ERROR:", HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR },
1205     { "+CNUM:", HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION},
1206     { "+COPS:", HFP_CMD_QUERY_OPERATOR_SELECTION_NAME },
1207     { "+VGM:",  HFP_CMD_SET_MICROPHONE_GAIN },
1208     { "+VGM=",  HFP_CMD_SET_MICROPHONE_GAIN },
1209     { "+VGS:",  HFP_CMD_SET_SPEAKER_GAIN},
1210     { "+VGS=",  HFP_CMD_SET_SPEAKER_GAIN},
1211     { "ERROR",  HFP_CMD_ERROR},
1212     { "NOP",    HFP_CMD_NONE}, // dummy command used by unit tests
1213     { "OK",     HFP_CMD_OK },
1214     { "RING",   HFP_CMD_RING },
1215 };
1216 
1217 static const hfp_custom_at_command_t *
1218 hfp_custom_command_lookup(bool isHandsFree, const char *text) {
1219     btstack_linked_list_t * custom_commands = isHandsFree ? &hfp_custom_commands_hf : &hfp_custom_commands_ag;
1220     btstack_linked_list_iterator_t it;
1221     btstack_linked_list_iterator_init(&it, custom_commands);
1222     while (btstack_linked_list_iterator_has_next(&it)) {
1223         hfp_custom_at_command_t *at_command = (hfp_custom_at_command_t *) btstack_linked_list_iterator_next(&it);
1224         int match = strcmp(text, at_command->command);
1225         if (match == 0) {
1226             return at_command;
1227         }
1228     }
1229     return NULL;
1230 }
1231 
1232 static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){
1233 
1234     // check for custom commands, AG only
1235     const hfp_custom_at_command_t * custom_at_command = hfp_custom_command_lookup(isHandsFree, line_buffer);
1236     if (custom_at_command != NULL){
1237         return HFP_CMD_CUSTOM_MESSAGE;
1238     }
1239 
1240     // table lookup based on role
1241     uint16_t num_entries;
1242     hfp_command_entry_t * table;
1243     if (isHandsFree == 0){
1244         table = hfp_ag_command_table;
1245         num_entries = sizeof(hfp_ag_command_table) / sizeof(hfp_command_entry_t);
1246     } else {
1247         table = hfp_hf_command_table;
1248         num_entries = sizeof(hfp_hf_command_table) / sizeof(hfp_command_entry_t);
1249     }
1250     // binary search
1251     uint16_t left = 0;
1252     uint16_t right = num_entries - 1;
1253     while (left <= right){
1254         uint16_t middle = left + (right - left) / 2;
1255         hfp_command_entry_t *entry = &table[middle];
1256         int match = strcmp(line_buffer, entry->command);
1257         if (match < 0){
1258             // search term is lower than middle element
1259             if (right == 0) break;
1260             right = middle - 1;
1261         } else if (match == 0){
1262             return entry->command_id;
1263         } else {
1264             // search term is higher than middle element
1265             left = middle + 1;
1266         }
1267     }
1268 
1269     // note: if parser in CMD_HEADER state would treats digits and maybe '+' as separator, match on "ATD" would work.
1270     // note: phone number is currently expected in line_buffer[3..]
1271     // prefix match on 'ATD', AG only
1272     if ((isHandsFree == 0) && (strncmp(line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0)){
1273         return HFP_CMD_CALL_PHONE_NUMBER;
1274     }
1275 
1276     // Valid looking, but unknown commands/responses
1277     if ((isHandsFree == 0) && (strncmp(line_buffer, "AT+", 3) == 0)){
1278         return HFP_CMD_UNKNOWN;
1279     }
1280 
1281     if ((isHandsFree != 0) && (strncmp(line_buffer, "+", 1) == 0)){
1282         return HFP_CMD_UNKNOWN;
1283     }
1284 
1285     return HFP_CMD_NONE;
1286 }
1287 
1288 static void hfp_parser_store_byte(hfp_connection_t * hfp_connection, uint8_t byte){
1289     if ((hfp_connection->line_size + 1) >= HFP_MAX_VR_TEXT_SIZE) return;
1290     hfp_connection->line_buffer[hfp_connection->line_size++] = byte;
1291     hfp_connection->line_buffer[hfp_connection->line_size] = 0;
1292 }
1293 static int hfp_parser_is_buffer_empty(hfp_connection_t * hfp_connection){
1294     return hfp_connection->line_size == 0;
1295 }
1296 
1297 static int hfp_parser_is_end_of_line(uint8_t byte){
1298     return (byte == '\n') || (byte == '\r');
1299 }
1300 
1301 void hfp_parser_reset_line_buffer(hfp_connection_t *hfp_connection) {
1302     hfp_connection->line_size = 0;
1303     // we don't set the first byte to '\0' to allow access to last argument e.g. in hfp_hf_handle_rfcommand
1304 }
1305 
1306 static void hfp_parser_store_if_token(hfp_connection_t * hfp_connection, uint8_t byte){
1307     switch (byte){
1308         case ',':
1309 		case '-':
1310         case ';':
1311         case '(':
1312         case ')':
1313         case '\n':
1314         case '\r':
1315             break;
1316         default:
1317             hfp_parser_store_byte(hfp_connection, byte);
1318             break;
1319     }
1320 }
1321 
1322 static bool hfp_parser_is_separator( uint8_t byte){
1323     switch (byte){
1324         case ',':
1325 		case '-':
1326         case ';':
1327         case '\n':
1328         case '\r':
1329             return true;
1330         default:
1331             return false;
1332     }
1333 }
1334 
1335 // returns true if received bytes was processed. Otherwise, functions will be called with same byte again
1336 // this is used to for a one byte lookahead, where an unexpected byte is pushed back by returning false
1337 static bool hfp_parse_byte(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){
1338 
1339 #ifdef HFP_DEBUG
1340     if (byte >= ' '){
1341         printf("Parse  '%c' - state %u, buffer %s\n", byte, hfp_connection->parser_state, hfp_connection->line_buffer);
1342     } else {
1343         printf("Parse 0x%02x - state %u, buffer %s\n", byte, hfp_connection->parser_state, hfp_connection->line_buffer);
1344     }
1345 #endif
1346 
1347     // handle doubles quotes
1348     if (byte == '"'){
1349         hfp_connection->parser_quoted = !hfp_connection->parser_quoted;
1350         return true;
1351     }
1352     if (hfp_connection->parser_quoted) {
1353         hfp_parser_store_byte(hfp_connection, byte);
1354         return true;
1355     }
1356 
1357     // ignore spaces outside command or double quotes (required e.g. for '+CME ERROR:..") command
1358     if ((byte == ' ') && (hfp_connection->parser_state != HFP_PARSER_CMD_HEADER)) return true;
1359 
1360     bool processed = true;
1361 
1362     switch (hfp_connection->parser_state) {
1363         case HFP_PARSER_CMD_HEADER:
1364             switch (byte) {
1365                 case '\n':
1366                 case '\r':
1367                 case ';':
1368                     // ignore separator
1369                     break;
1370                 case ':':
1371                 case '?':
1372                     // store separator
1373                     hfp_parser_store_byte(hfp_connection, byte);
1374                     break;
1375                 case '=':
1376                     // equal sign: remember and wait for next char to decided between '=?' and '=\?'
1377                     hfp_connection->found_equal_sign = true;
1378                     hfp_parser_store_byte(hfp_connection, byte);
1379                     return true;
1380                 default:
1381                     // store if not lookahead
1382                     if (!hfp_connection->found_equal_sign) {
1383                         hfp_parser_store_byte(hfp_connection, byte);
1384                         return true;
1385                     }
1386                     // mark as lookahead
1387                     processed = false;
1388                     break;
1389             }
1390 
1391             // ignore empty tokens
1392             if (hfp_parser_is_buffer_empty(hfp_connection)) return true;
1393 
1394             // parse
1395             hfp_connection->command = parse_command((char *)hfp_connection->line_buffer, isHandsFree);
1396 
1397             // pick +CIND version based on connection state: descriptions during SLC vs. states later
1398             if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS_GENERIC){
1399                 switch(hfp_connection->state){
1400                     case HFP_W4_RETRIEVE_INDICATORS_STATUS:
1401                         hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS;
1402                         break;
1403                     case HFP_W4_RETRIEVE_INDICATORS:
1404                         hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS;
1405                         break;
1406                     default:
1407                         hfp_connection->command = HFP_CMD_UNKNOWN;
1408                         break;
1409                 }
1410             }
1411 
1412             log_info("command string '%s', handsfree %u -> cmd id %u", (char *)hfp_connection->line_buffer, isHandsFree, hfp_connection->command);
1413 
1414             // store command id for custom command and just store rest of line
1415             if (hfp_connection->command == HFP_CMD_CUSTOM_MESSAGE){
1416                 const hfp_custom_at_command_t * at_command = hfp_custom_command_lookup(isHandsFree, (const char *) hfp_connection->line_buffer);
1417                 hfp_connection->custom_at_command_id = at_command->command_id;
1418                 hfp_connection->parser_state = HFP_PARSER_CUSTOM_COMMAND;
1419                 return processed;
1420             }
1421 
1422             // next state
1423             hfp_parser_reset_line_buffer(hfp_connection);
1424             hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE;
1425 
1426             return processed;
1427 
1428         case HFP_PARSER_CMD_SEQUENCE:
1429             // handle empty fields
1430             if ((byte == ',' ) && (hfp_connection->line_size == 0)){
1431                 hfp_connection->line_buffer[0] = 0;
1432                 hfp_connection->ignore_value = 1;
1433                 parse_sequence(hfp_connection);
1434                 return true;
1435             }
1436 
1437             hfp_parser_store_if_token(hfp_connection, byte);
1438             if (!hfp_parser_is_separator(byte)) return true;
1439 
1440             // ignore empty tokens
1441             switch (hfp_connection->command){
1442                 case HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION:
1443                     // don't ignore empty string
1444                     break;
1445                 default:
1446                     if (hfp_parser_is_buffer_empty(hfp_connection) && (hfp_connection->ignore_value == 0)) {
1447                         return true;
1448                     }
1449                     break;
1450             }
1451 
1452             parse_sequence(hfp_connection);
1453 
1454             hfp_parser_reset_line_buffer(hfp_connection);
1455 
1456             switch (hfp_connection->command){
1457                 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1458                 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1459                 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1460                 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1461                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1462                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1463                 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1464                 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1465                 case HFP_CMD_HF_INDICATOR_STATUS:
1466                     hfp_connection->parser_state = HFP_PARSER_SECOND_ITEM;
1467                     break;
1468                 default:
1469                     break;
1470             }
1471             return true;
1472 
1473         case HFP_PARSER_SECOND_ITEM:
1474 
1475             hfp_parser_store_if_token(hfp_connection, byte);
1476             if (!hfp_parser_is_separator(byte)) return true;
1477 
1478             switch (hfp_connection->command){
1479                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1480                     log_info("format %s, ", hfp_connection->line_buffer);
1481                     hfp_connection->network_operator.format =  btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1482                     break;
1483                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1484                     log_info("format %s \n", hfp_connection->line_buffer);
1485                     hfp_connection->network_operator.format =  btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1486                     break;
1487                 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
1488                 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
1489                 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1490                     hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].state = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1491                     break;
1492                 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1493                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1494                     log_info("%d \n", hfp_connection->ag_indicators[hfp_connection->parser_item_index].status);
1495                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].status_changed = 1;
1496                     break;
1497                 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1498                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].min_range = btstack_atoi((char *)hfp_connection->line_buffer);
1499                     log_info("%s, ", hfp_connection->line_buffer);
1500                     break;
1501                 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1502                 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1503                 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1504                     hfp_connection->bnip_type = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1505                     break;
1506                 case HFP_CMD_HF_INDICATOR_STATUS:
1507                     hfp_connection->parser_indicator_value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1508                     break;
1509                 default:
1510                     break;
1511             }
1512 
1513             hfp_parser_reset_line_buffer(hfp_connection);
1514 
1515             hfp_connection->parser_state = HFP_PARSER_THIRD_ITEM;
1516 
1517             return true;
1518 
1519         case HFP_PARSER_THIRD_ITEM:
1520 
1521             hfp_parser_store_if_token(hfp_connection, byte);
1522             if (!hfp_parser_is_separator(byte)) return true;
1523 
1524             switch (hfp_connection->command){
1525                 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1526                     btstack_strcpy(hfp_connection->network_operator.name, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE,  (char *)hfp_connection->line_buffer);
1527                     break;
1528                 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1529                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].max_range = btstack_atoi((char *)hfp_connection->line_buffer);
1530                     hfp_next_indicators_index(hfp_connection);
1531                     hfp_connection->ag_indicators_nr = hfp_connection->parser_item_index;
1532                     break;
1533                 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1534                 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1535                     // track if last argument exists
1536                     hfp_connection->clip_have_alpha = hfp_connection->line_size != 0;
1537                     break;
1538                 default:
1539                     break;
1540             }
1541 
1542             hfp_parser_reset_line_buffer(hfp_connection);
1543 
1544             if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS){
1545                 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE;
1546             }
1547             return true;
1548 
1549         case HFP_PARSER_CUSTOM_COMMAND:
1550             if (hfp_parser_is_end_of_line(byte) == false){
1551                 hfp_parser_store_byte(hfp_connection, byte);
1552             }
1553             return true;
1554 
1555         default:
1556             btstack_assert(false);
1557             return true;
1558     }
1559 }
1560 
1561 void hfp_parse(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){
1562     bool processed = false;
1563     while (!processed){
1564         processed = hfp_parse_byte(hfp_connection, byte, isHandsFree);
1565     }
1566     // reset parser state on end-of-line
1567     if (hfp_parser_is_end_of_line(byte)){
1568         hfp_connection->found_equal_sign = false;
1569         hfp_connection->parser_item_index = 0;
1570         hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
1571     }
1572 }
1573 
1574 static void parse_sequence(hfp_connection_t * hfp_connection){
1575     int value;
1576     switch (hfp_connection->command){
1577         case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS:
1578             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1579             int i;
1580             switch (hfp_connection->parser_item_index){
1581                 case 0:
1582                     for (i=0;i<hfp_connection->generic_status_indicators_nr;i++){
1583                         if (hfp_connection->generic_status_indicators[i].uuid == value){
1584                             hfp_connection->parser_indicator_index = i;
1585                             break;
1586                         }
1587                     }
1588                     break;
1589                 case 1:
1590                     if (hfp_connection->parser_indicator_index <0) break;
1591                     hfp_connection->generic_status_indicators[hfp_connection->parser_indicator_index].state = value;
1592                     log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n",
1593                      hfp_connection->parser_item_index, value);
1594                     break;
1595                 default:
1596                     break;
1597             }
1598             hfp_next_indicators_index(hfp_connection);
1599             break;
1600 
1601         case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
1602             switch(hfp_connection->parser_item_index){
1603                 case 0:
1604                     // <alpha>: This optional field is not supported, and shall be left blank.
1605                     break;
1606                 case 1:
1607                     // <number>: Quoted string containing the phone number in the format specified by <type>.
1608                     btstack_strcpy(hfp_connection->bnip_number, sizeof(hfp_connection->bnip_number), (char *)hfp_connection->line_buffer);
1609                     break;
1610                 case 2:
1611                     /*
1612                       <type> field specifies the format of the phone number provided, and can be one of the following values:
1613                       - values 128-143: The phone number format may be a national or international format, and may contain prefix and/or escape digits. No changes on the number presentation are required.
1614                      - values 144-159: The phone number format is an international number, including the country code prefix. If the plus sign ("+") is not included as part of the number and shall be added by the AG as needed.
1615                      - values 160-175: National number. No prefix nor escape digits included.
1616                      */
1617                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1618                     hfp_connection->bnip_type = value;
1619                     break;
1620                 case 3:
1621                     // <speed>: This optional field is not supported, and shall be left blank.
1622                     break;
1623                 case 4:
1624                     // <service>: Indicates which service this phone number relates to. Shall be either 4 (voice) or 5 (fax).
1625                 default:
1626                     break;
1627             }
1628             // index > 2 are ignored in switch above
1629             hfp_connection->parser_item_index++;
1630             break;
1631         case HFP_CMD_LIST_CURRENT_CALLS:
1632             switch(hfp_connection->parser_item_index){
1633                 case 0:
1634                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1635                     hfp_connection->clcc_idx = value;
1636                     break;
1637                 case 1:
1638                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1639                     hfp_connection->clcc_dir = value;
1640                     break;
1641                 case 2:
1642                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1643                     hfp_connection->clcc_status = value;
1644                     break;
1645                 case 3:
1646                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1647                     hfp_connection->clcc_mode = value;
1648                     break;
1649                 case 4:
1650                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1651                     hfp_connection->clcc_mpty = value;
1652                     break;
1653                 case 5:
1654                     btstack_strcpy(hfp_connection->bnip_number, sizeof(hfp_connection->bnip_number), (char *)hfp_connection->line_buffer);
1655                     break;
1656                 case 6:
1657                     value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1658                     hfp_connection->bnip_type = value;
1659                     break;
1660                 default:
1661                     break;
1662             }
1663             // index > 6 are ignored in switch above
1664             hfp_connection->parser_item_index++;
1665             break;
1666         case HFP_CMD_SET_MICROPHONE_GAIN:
1667             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1668             hfp_connection->microphone_gain = value;
1669             log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value);
1670             break;
1671         case HFP_CMD_SET_SPEAKER_GAIN:
1672             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1673             hfp_connection->speaker_gain = value;
1674             log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value);
1675             break;
1676         case HFP_CMD_TURN_OFF_EC_AND_NR:
1677             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1678             hfp_connection->ag_echo_and_noise_reduction = value;
1679             log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value);
1680             break;
1681         case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING:
1682             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1683             hfp_connection->remote_supported_features = store_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value);
1684             log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value);
1685             break;
1686         case HFP_CMD_HF_CONFIRMED_CODEC:
1687             hfp_connection->codec_confirmed = btstack_atoi((char*)hfp_connection->line_buffer);
1688             log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", hfp_connection->codec_confirmed);
1689             break;
1690         case HFP_CMD_AG_SUGGESTED_CODEC:
1691             hfp_connection->suggested_codec = btstack_atoi((char*)hfp_connection->line_buffer);
1692             log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", hfp_connection->suggested_codec);
1693             break;
1694         case HFP_CMD_SUPPORTED_FEATURES:
1695             hfp_connection->remote_supported_features = btstack_atoi((char*)hfp_connection->line_buffer);
1696             log_info("Parsed supported feature %d\n", (int) hfp_connection->remote_supported_features);
1697             break;
1698         case HFP_CMD_AVAILABLE_CODECS:
1699             log_info("Parsed codec %s\n", hfp_connection->line_buffer);
1700             hfp_connection->remote_codecs[hfp_connection->parser_item_index] = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1701             hfp_next_codec_index(hfp_connection);
1702             hfp_connection->remote_codecs_nr = hfp_connection->parser_item_index;
1703             break;
1704         case HFP_CMD_RETRIEVE_AG_INDICATORS:
1705             btstack_strcpy((char *)hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, HFP_MAX_INDICATOR_DESC_SIZE, (char *)hfp_connection->line_buffer);
1706             hfp_connection->ag_indicators[hfp_connection->parser_item_index].index = hfp_connection->parser_item_index+1;
1707             log_info("Indicator %d: %s (", hfp_connection->ag_indicators_nr+1, hfp_connection->line_buffer);
1708             break;
1709         case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS:
1710             log_info("Parsed Indicator %d with status: %s\n", hfp_connection->parser_item_index+1, hfp_connection->line_buffer);
1711             hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = btstack_atoi((char *) hfp_connection->line_buffer);
1712             hfp_next_indicators_index(hfp_connection);
1713             break;
1714         case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
1715             hfp_next_indicators_index(hfp_connection);
1716             if (hfp_connection->parser_item_index != 4) break;
1717             log_info("Parsed Enable indicators: %s\n", hfp_connection->line_buffer);
1718             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1719             hfp_connection->enable_status_update_for_ag_indicators = (uint8_t) value;
1720             break;
1721         case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
1722             log_info("Parsed Support call hold: %s\n", hfp_connection->line_buffer);
1723             if (hfp_connection->line_size > 2 ) break;
1724             memcpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name, (char *)hfp_connection->line_buffer, HFP_CALL_SERVICE_SIZE-1);
1725             hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name[HFP_CALL_SERVICE_SIZE - 1] = 0;
1726             hfp_next_remote_call_services_index(hfp_connection);
1727             break;
1728         case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
1729         case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
1730             log_info("Parsed Generic status indicator: %s\n", hfp_connection->line_buffer);
1731             hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].uuid = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer);
1732             hfp_next_indicators_index(hfp_connection);
1733             hfp_connection->generic_status_indicators_nr = hfp_connection->parser_item_index;
1734             break;
1735         case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1736             // HF parses inital AG gen. ind. state
1737             log_info("Parsed List generic status indicator %s state: ", hfp_connection->line_buffer);
1738             hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection);
1739             break;
1740         case HFP_CMD_HF_INDICATOR_STATUS:
1741             hfp_connection->parser_indicator_index = hfp_parse_indicator_index(hfp_connection);
1742             log_info("Parsed HF indicator index %u", hfp_connection->parser_indicator_index);
1743             break;
1744         case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:
1745             // AG parses new gen. ind. state
1746             if (hfp_connection->ignore_value){
1747                 hfp_connection->ignore_value = 0;
1748                 log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", hfp_connection->parser_item_index,
1749                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled);
1750             }
1751             else if (hfp_connection->ag_indicators[hfp_connection->parser_item_index].mandatory){
1752                 log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n",
1753                     hfp_connection->parser_item_index, hfp_connection->ag_indicators[hfp_connection->parser_item_index].name);
1754             } else {
1755                 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1756                 hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled = value;
1757                 log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", hfp_connection->parser_item_index,
1758                     hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, value);
1759             }
1760             hfp_next_indicators_index(hfp_connection);
1761             break;
1762         case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1763             // indicators are indexed starting with 1
1764             hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection);
1765             log_info("Parsed status of the AG indicator %d, status ", hfp_connection->parser_item_index);
1766             break;
1767         case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1768             hfp_connection->network_operator.mode = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1769             log_info("Parsed network operator mode: %d, ", hfp_connection->network_operator.mode);
1770             break;
1771         case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1772             if (hfp_connection->line_buffer[0] == '3'){
1773                 log_info("Parsed Set network operator format : %s, ", hfp_connection->line_buffer);
1774                 break;
1775             }
1776             // TODO emit ERROR, wrong format
1777             log_info("ERROR Set network operator format: index %s not supported\n", hfp_connection->line_buffer);
1778             break;
1779         case HFP_CMD_ERROR:
1780             break;
1781         case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
1782             hfp_connection->extended_audio_gateway_error = 1;
1783             hfp_connection->extended_audio_gateway_error_value = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1784             break;
1785         case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR:
1786             hfp_connection->enable_extended_audio_gateway_error_report = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1787             hfp_connection->extended_audio_gateway_error = 0;
1788             break;
1789         case HFP_CMD_AG_SENT_PHONE_NUMBER:
1790         case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1791         case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1792             btstack_strcpy((char *)hfp_connection->bnip_number, sizeof(hfp_connection->bnip_number), (char *)hfp_connection->line_buffer);
1793             break;
1794         case HFP_CMD_CALL_HOLD:
1795             hfp_connection->ag_call_hold_action = hfp_connection->line_buffer[0] - '0';
1796             if (hfp_connection->line_buffer[1] != '\0'){
1797                 hfp_connection->call_index = btstack_atoi((char *)&hfp_connection->line_buffer[1]);
1798             }
1799             break;
1800         case HFP_CMD_RESPONSE_AND_HOLD_COMMAND:
1801             hfp_connection->ag_response_and_hold_action = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1802             break;
1803         case HFP_CMD_TRANSMIT_DTMF_CODES:
1804             hfp_connection->ag_dtmf_code = hfp_connection->line_buffer[0];
1805             break;
1806         case HFP_CMD_ENABLE_CLIP:
1807             hfp_connection->clip_enabled = hfp_connection->line_buffer[0] != '0';
1808             break;
1809         case HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION:
1810             hfp_connection->call_waiting_notification_enabled = hfp_connection->line_buffer[0] != '0';
1811             break;
1812         case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION:
1813             value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1814             hfp_connection->ag_activate_voice_recognition_value = value;
1815             break;
1816         case HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION:
1817             switch(hfp_connection->parser_item_index){
1818                 case 0:
1819                     hfp_connection->ag_vra_status = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1820                     break;
1821                 case 1:
1822                     hfp_connection->ag_vra_state = (hfp_voice_recognition_state_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1823                     break;
1824                 case 2:
1825                     hfp_connection->ag_msg.text_id = 0;
1826                     for (i = 0 ; i < 4; i++){
1827                         hfp_connection->ag_msg.text_id = (hfp_connection->ag_msg.text_id << 4) | nibble_for_char(hfp_connection->line_buffer[i]);
1828                     }
1829                     break;
1830                 case 3:
1831                     hfp_connection->ag_msg.text_type = (hfp_text_type_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1832                     break;
1833                 case 4:
1834                     hfp_connection->ag_msg.text_operation = (hfp_text_operation_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1835                     break;
1836                 case 5:
1837                     hfp_connection->line_buffer[hfp_connection->line_size] = 0;
1838                     hfp_connection->ag_vra_msg_length = hfp_connection->line_size + 1;
1839                     break;
1840                 default:
1841                     break;
1842             }
1843             hfp_connection->parser_item_index++;
1844             break;
1845         default:
1846             break;
1847     }
1848 }
1849 
1850 static void hfp_handle_start_sdp_client_query(void * context){
1851     UNUSED(context);
1852 
1853     btstack_linked_list_iterator_t it;
1854     btstack_linked_list_iterator_init(&it, &hfp_connections);
1855     while (btstack_linked_list_iterator_has_next(&it)){
1856         hfp_connection_t * connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
1857 
1858         if (connection->state != HFP_W2_SEND_SDP_QUERY) continue;
1859 
1860         connection->state = HFP_W4_SDP_QUERY_COMPLETE;
1861         hfp_sdp_query_context.local_role = connection->local_role;
1862         (void)memcpy(hfp_sdp_query_context.remote_address, connection->remote_addr, 6);
1863         sdp_client_query_rfcomm_channel_and_name_for_service_class_uuid(&handle_query_rfcomm_event, connection->remote_addr, connection->service_uuid);
1864         return;
1865     }
1866 }
1867 
1868 uint8_t hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid, hfp_role_t local_role){
1869     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr, local_role);
1870     if (connection != NULL){
1871         // allow to call hfp_establish_service_level_connection after SLC was triggered remotely
1872         // @note this also allows to call hfp_establish_service_level_connection again before SLC is complete
1873         if (connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){
1874             return ERROR_CODE_SUCCESS;
1875         } else {
1876             return ERROR_CODE_COMMAND_DISALLOWED;
1877         }
1878     }
1879 
1880     connection = hfp_create_connection(bd_addr, local_role);
1881     if (!connection){
1882         return BTSTACK_MEMORY_ALLOC_FAILED;
1883     }
1884 
1885     connection->state = HFP_W2_SEND_SDP_QUERY;
1886 
1887     bd_addr_copy(connection->remote_addr, bd_addr);
1888     connection->service_uuid = service_uuid;
1889 
1890     if (local_role == HFP_ROLE_HF) {
1891         // setup HF Indicators
1892         uint8_t i;
1893         for (i=0; i < hfp_hf_indicators_nr; i++){
1894             connection->generic_status_indicators[i].uuid = hfp_hf_indicators[i];
1895             connection->generic_status_indicators[i].state = 0;
1896         }
1897     }
1898 
1899     hfp_sdp_query_request.callback = &hfp_handle_start_sdp_client_query;
1900     // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
1901     (void) sdp_client_register_query_callback(&hfp_sdp_query_request);
1902     return ERROR_CODE_SUCCESS;
1903 }
1904 
1905 void hfp_trigger_release_service_level_connection(hfp_connection_t * hfp_connection){
1906     // called internally, NULL check already performed
1907     btstack_assert(hfp_connection != NULL);
1908 
1909     hfp_trigger_release_audio_connection(hfp_connection);
1910     if (hfp_connection->state < HFP_W4_RFCOMM_CONNECTED){
1911         hfp_connection->state = HFP_IDLE;
1912         return;
1913     }
1914 
1915     if (hfp_connection->state == HFP_W4_RFCOMM_CONNECTED){
1916         hfp_connection->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
1917         return;
1918     }
1919     hfp_connection->release_slc_connection = 1;
1920     if (hfp_connection->state < HFP_W4_SCO_CONNECTED){
1921         hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
1922         return;
1923     }
1924 
1925     if (hfp_connection->state < HFP_W4_SCO_DISCONNECTED){
1926         hfp_connection->state = HFP_W2_DISCONNECT_SCO;
1927         hfp_connection->release_audio_connection = 1;
1928         return;
1929     }
1930 }
1931 
1932 uint8_t hfp_trigger_release_audio_connection(hfp_connection_t * hfp_connection){
1933     // called internally, NULL check already performed
1934     btstack_assert(hfp_connection != NULL);
1935     if (hfp_connection->state <= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){
1936         return ERROR_CODE_COMMAND_DISALLOWED;
1937     }
1938     switch (hfp_connection->state) {
1939         case HFP_W2_CONNECT_SCO:
1940             hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
1941             break;
1942         case HFP_W4_SCO_CONNECTED:
1943         case HFP_AUDIO_CONNECTION_ESTABLISHED:
1944             hfp_connection->release_audio_connection = 1;
1945             break;
1946         default:
1947             return ERROR_CODE_COMMAND_DISALLOWED;
1948     }
1949     return ERROR_CODE_SUCCESS;
1950 }
1951 
1952 bool hfp_sco_setup_active(void){
1953     return hfp_sco_establishment_active != NULL;
1954 }
1955 
1956 void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){
1957 
1958     hfp_sco_establishment_active = hfp_connection;
1959 
1960     // all packet types, fixed bandwidth
1961     int setting = hfp_connection->link_setting;
1962     log_info("hfp_setup_synchronous_connection using setting nr %u", setting);
1963     uint16_t sco_voice_setting = hci_get_sco_voice_setting();
1964     if (hfp_connection->negotiated_codec != HFP_CODEC_CVSD){
1965 #ifdef ENABLE_BCM_PCM_WBS
1966         sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers
1967 #else
1968         sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise
1969 #endif
1970     }
1971     uint16_t packet_types = hfp_link_settings[setting].packet_types;
1972     hfp_connection->packet_types = packet_types;
1973 
1974     // get packet types - bits 6-9 are 'don't allow'
1975     uint16_t packet_types_flipped = packet_types ^ 0x03c0;
1976 #if defined(ENABLE_SCO_OVER_PCM) && defined(ENABLE_NXP_PCM_WBS)
1977     uint8_t  radio_coding_format = 3;
1978     uint32_t host_bandwidth      = 0;
1979     uint8_t  coded_data_size     = 0;
1980     switch (hfp_connection->negotiated_codec){
1981         case HFP_CODEC_CVSD:
1982             radio_coding_format = 0x02;
1983             host_bandwidth = 16000;
1984             coded_data_size = 0x10;
1985             break;
1986         case HFP_CODEC_MSBC:
1987             radio_coding_format = 0x05;
1988             host_bandwidth = 32000;
1989             coded_data_size = 0x08;
1990             break;
1991         default:
1992             log_error("Coding format %u not supported by Controller", hfp_connection->negotiated_codec);
1993             btstack_assert(false);
1994             break;
1995     }
1996     hci_send_cmd(&hci_enhanced_setup_synchronous_connection,
1997         // ACL Handle
1998         hfp_connection->acl_handle,
1999         // Transmit_Bandwidth
2000         8000,
2001         // Receive_Bandwidth
2002         8000,
2003         // Transmit_Coding_Format: radio_config_format, company, codec
2004         radio_coding_format, 0x00, 0x00,
2005         // Receive_Coding_Format: radio_config_format, company, codec
2006         radio_coding_format, 0x00, 0x00,
2007         // Transmit_Codec_Frame_Size
2008         0x3c,
2009         // Receive_Codec_Frame_Size
2010         0x3c,
2011         // Input_Bandwidth
2012         host_bandwidth,
2013         // Output_Bandwidth
2014         host_bandwidth,
2015         // Input_Coding_Format, 0x04 = Linear PCM, company, codec
2016         0x04, 0x00, 0x00,
2017         // Output_Coding_Format, 0x04 = Linear PCM, company, codec
2018         0x04, 0x00, 0x00,
2019         // Input_Coded_Data_Size
2020         coded_data_size,
2021         // Output_Coded_Data_Size
2022         coded_data_size,
2023         // Input_PCM_Data_Format, 0x02 = 2’s complement
2024         0x02,
2025         // Output_PCM_Data_Format, 0x02 = 2’s complement
2026         0x02,
2027         // Input_PCM_Sample_Payload_MSB_Position
2028         0x00,
2029         // Output_PCM_Sample_Payload_MSB_Position
2030         0x00,
2031         // Input_Data_Path - vendor specific: NXP - I2S/PCM
2032         0x01,
2033         // Output_Data_Path - vendor specific: NXP - I2S/PCM
2034         0x01,
2035         // Input_Transport_Unit_Size
2036         0x10,
2037         // Output_Transport_Unit_Size
2038         0x10,
2039         //
2040         hfp_link_settings[setting].max_latency,
2041         packet_types_flipped,
2042         hfp_link_settings[setting].retransmission_effort);
2043 #else
2044     hci_send_cmd(&hci_setup_synchronous_connection, hfp_connection->acl_handle, 8000, 8000, hfp_link_settings[setting].max_latency,
2045         sco_voice_setting, hfp_link_settings[setting].retransmission_effort, packet_types_flipped);
2046 #endif
2047 }
2048 
2049 #ifdef ENABLE_HFP_HF_SAFE_SETTINGS
2050 hfp_link_settings_t hfp_safe_settings_for_context(bool use_eSCO, uint8_t negotiated_codec, bool secure_connection_in_use){
2051     uint8_t i;
2052     hfp_link_settings_t link_setting = HFP_LINK_SETTINGS_NONE;
2053     for (i=0 ; i < (sizeof(hfp_mandatory_safe_settings) / sizeof(struct hfp_mandatory_safe_setting)) ; i++){
2054         uint16_t packet_types = hfp_link_settings[(uint8_t)(hfp_mandatory_safe_settings[i].link_setting)].packet_types;
2055         bool is_eSCO_setting = (packet_types & SCO_PACKET_TYPES_ESCO) != 0;
2056         if (is_eSCO_setting != use_eSCO) continue;
2057         if ((hfp_mandatory_safe_settings[i].codec_mask & (1 << negotiated_codec)) == 0) continue;
2058         if (hfp_mandatory_safe_settings[i].secure_connection_in_use != secure_connection_in_use) continue;
2059         link_setting = hfp_mandatory_safe_settings[i].link_setting;
2060         break;
2061     }
2062     return link_setting;
2063 }
2064 #endif
2065 
2066 void hfp_accept_synchronous_connection(hfp_connection_t * hfp_connection, bool use_eSCO){
2067 
2068     hfp_sco_establishment_active = hfp_connection;
2069 
2070     // lookup safe settings based on SCO type, SC use and Codec type
2071     uint16_t max_latency;
2072     uint16_t packet_types;
2073     uint16_t retransmission_effort;
2074 
2075 #ifdef ENABLE_HFP_HF_SAFE_SETTINGS
2076     hfp_link_settings_t link_setting = HFP_LINK_SETTINGS_NONE;
2077     // fallback for non-CVSD codec and SCO connection
2078     if ((hfp_connection->negotiated_codec != HFP_CODEC_CVSD) && (use_eSCO == false)){
2079         max_latency           = 0xffff;
2080         retransmission_effort = 0xff;
2081         packet_types          = SCO_PACKET_TYPES_HV3 | SCO_PACKET_TYPES_HV1;
2082     } else {
2083         // use safe settings from HFP v1.9, table 6.10
2084     bool secure_connection_in_use = gap_secure_connection(hfp_connection->acl_handle);
2085         link_setting = hfp_safe_settings_for_context(use_eSCO, hfp_connection->negotiated_codec, secure_connection_in_use);
2086         max_latency             = hfp_link_settings[(uint8_t) link_setting].max_latency;
2087         retransmission_effort   = hfp_link_settings[(uint8_t) link_setting].retransmission_effort;
2088         packet_types            = hfp_link_settings[(uint8_t) link_setting].packet_types;
2089     }
2090 #else
2091     max_latency           = 0xffff;
2092     retransmission_effort = 0xff;
2093     if (use_eSCO) {
2094         packet_types      = SCO_PACKET_TYPES_EV3 | SCO_PACKET_TYPES_2EV3;
2095     } else {
2096         packet_types      = SCO_PACKET_TYPES_HV3 | SCO_PACKET_TYPES_HV1;
2097     }
2098 #endif
2099 
2100     // transparent data for non-CVSD connections or if codec provided by Controller
2101     uint16_t sco_voice_setting = hci_get_sco_voice_setting();
2102     if (hfp_connection->negotiated_codec != HFP_CODEC_CVSD){
2103 #ifdef ENABLE_BCM_PCM_WBS
2104         sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers
2105 #else
2106         sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise
2107 #endif
2108     }
2109 
2110     // filter packet types
2111     packet_types &= hfp_get_sco_packet_types();
2112 
2113     hfp_connection->packet_types = packet_types;
2114 
2115     // bits 6-9 are 'don't allow'
2116     uint16_t packet_types_flipped = packet_types ^ 0x3c0;
2117 
2118     log_info("Sending hci_accept_connection_request: packet types 0x%04x, sco_voice_setting 0x%02x",
2119             packet_types, sco_voice_setting);
2120 
2121 #if defined(ENABLE_SCO_OVER_PCM) && defined(ENABLE_NXP_PCM_WBS)
2122     uint8_t radio_coding_format = 3;
2123     uint32_t host_bandwidth = 0;
2124     uint8_t  coded_data_size = 0;
2125     switch (hfp_connection->negotiated_codec){
2126         case HFP_CODEC_CVSD:
2127             radio_coding_format = 0x02;
2128             host_bandwidth = 16000;
2129             coded_data_size = 0x10;
2130             break;
2131         case HFP_CODEC_MSBC:
2132             radio_coding_format = 0x05;
2133             host_bandwidth = 32000;
2134             coded_data_size = 0x08;
2135             break;
2136         default:
2137             log_error("Coding format %u not supported by Controller", hfp_connection->negotiated_codec);
2138             btstack_assert(false);
2139             break;
2140     }
2141     hci_send_cmd(&hci_enhanced_accept_synchronous_connection,
2142         // BD_ADDR
2143         hfp_connection->remote_addr,
2144         // Transmit_Bandwidth
2145         8000,
2146         // Receive_Bandwidth
2147         8000,
2148         // Transmit_Coding_Format: radio_config_format, company, codec
2149         radio_coding_format, 0x00, 0x00,
2150         // Receive_Coding_Format: radio_config_format, company, codec
2151         radio_coding_format, 0x00, 0x00,
2152         // Transmit_Codec_Frame_Size
2153         0x3c,
2154         // Receive_Codec_Frame_Size
2155         0x3c,
2156         // Input_Bandwidth
2157         host_bandwidth,
2158         // Output_Bandwidth
2159         host_bandwidth,
2160         // Input_Coding_Format, 0x04 = Linear PCM, company, codec
2161         0x04, 0x00, 0x00,
2162         // Output_Coding_Format, 0x04 = Linear PCM, company, codec
2163         0x04, 0x00, 0x00,
2164         // Input_Coded_Data_Size
2165         coded_data_size,
2166         // Output_Coded_Data_Size
2167         coded_data_size,
2168         // Input_PCM_Data_Format, 0x02 = 2’s complement
2169         0x02,
2170         // Output_PCM_Data_Format, 0x02 = 2’s complement
2171         0x02,
2172         // Input_PCM_Sample_Payload_MSB_Position
2173         0x00,
2174         // Output_PCM_Sample_Payload_MSB_Position
2175         0x00,
2176         // Input_Data_Path - vendor specific: NXP - I2S/PCM
2177         0x01,
2178         // Output_Data_Path - vendor specific: NXP - I2S/PCM
2179         0x01,
2180         // Input_Transport_Unit_Size
2181         0x10,
2182         // Output_Transport_Unit_Size
2183         0x10,
2184         //
2185         max_latency,
2186         packet_types_flipped,
2187         retransmission_effort);
2188 #else
2189     hci_send_cmd(&hci_accept_synchronous_connection, hfp_connection->remote_addr, 8000, 8000, max_latency,
2190                  sco_voice_setting, retransmission_effort, packet_types_flipped);
2191 #endif
2192 }
2193 
2194 #ifdef ENABLE_CC256X_ASSISTED_HFP
2195 void hfp_cc256x_write_codec_config(hfp_connection_t * hfp_connection){
2196     uint32_t sample_rate_hz;
2197     uint16_t clock_rate_khz;
2198     if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
2199         clock_rate_khz = 512;
2200         sample_rate_hz = 16000;
2201     } else {
2202         clock_rate_khz = 256;
2203         sample_rate_hz = 8000;
2204     }
2205     uint8_t clock_direction = 0;        // master
2206     uint16_t frame_sync_duty_cycle = 0; // i2s with 50%
2207     uint8_t  frame_sync_edge = 1;       // rising edge
2208     uint8_t  frame_sync_polarity = 0;   // active high
2209     uint8_t  reserved = 0;
2210     uint16_t size = 16;
2211     uint16_t chan_1_offset = 1;
2212     uint16_t chan_2_offset = chan_1_offset + size;
2213     uint8_t  out_edge = 1;              // rising
2214     uint8_t  in_edge = 0;               // falling
2215     hci_send_cmd(&hci_ti_write_codec_config, clock_rate_khz, clock_direction, sample_rate_hz, frame_sync_duty_cycle,
2216                  frame_sync_edge, frame_sync_polarity, reserved,
2217                  size, chan_1_offset, out_edge, size, chan_1_offset, in_edge, reserved,
2218                  size, chan_2_offset, out_edge, size, chan_2_offset, in_edge, reserved);
2219 }
2220 #endif
2221 
2222 #ifdef ENABLE_BCM_PCM_WBS
2223 void hfp_bcm_write_i2spcm_interface_param(hfp_connection_t * hfp_connection){
2224     uint8_t sample_rate = (hfp_connection->negotiated_codec == HFP_CODEC_MSBC) ? 1 : 0;
2225     // i2s enable, master, 8/16 kHz, 512 kHz
2226     hci_send_cmd(&hci_bcm_write_i2spcm_interface_param, 1, 1, sample_rate, 2);
2227 }
2228 #endif
2229 
2230 void hfp_prepare_for_sco(hfp_connection_t * hfp_connection){
2231     UNUSED(hfp_connection);
2232 #ifdef ENABLE_CC256X_ASSISTED_HFP
2233     hfp_connection->cc256x_send_write_codec_config = true;
2234     if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
2235         hfp_connection->cc256x_send_wbs_associate = true;
2236     }
2237 #endif
2238 
2239 #ifdef ENABLE_BCM_PCM_WBS
2240 #ifndef HAVE_BCM_PCM_NBS_16KHZ
2241     hfp_connection->bcm_send_write_i2spcm_interface_param = true;
2242 #endif
2243     if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
2244         hfp_connection->bcm_send_enable_wbs = true;
2245     }
2246 #endif
2247 
2248 #ifdef ENABLE_RTK_PCM_WBS
2249     hfp_connection->rtk_send_sco_config = true;
2250 #endif
2251 }
2252 
2253 void hfp_set_hf_callback(btstack_packet_handler_t callback){
2254     hfp_hf_callback = callback;
2255 }
2256 
2257 void hfp_set_ag_callback(btstack_packet_handler_t callback){
2258     hfp_ag_callback = callback;
2259 }
2260 
2261 void hfp_set_ag_rfcomm_packet_handler(btstack_packet_handler_t handler){
2262     hfp_ag_rfcomm_packet_handler = handler;
2263 }
2264 
2265 void hfp_set_hf_rfcomm_packet_handler(btstack_packet_handler_t handler){
2266     hfp_hf_rfcomm_packet_handler = handler;
2267 }
2268 
2269 void hfp_set_hf_indicators(uint8_t indicators_nr, const uint8_t * indicators) {
2270     hfp_hf_indicators_nr = indicators_nr;
2271     hfp_hf_indicators = indicators;
2272 }
2273 
2274 void hfp_init(void){
2275     hfp_allowed_sco_packet_types = SCO_PACKET_TYPES_ALL;
2276 }
2277 
2278 void hfp_deinit(void){
2279     hfp_allowed_sco_packet_types = 0;
2280     hfp_connections = NULL;
2281     hfp_hf_callback = NULL;
2282     hfp_ag_callback = NULL;
2283     hfp_hf_rfcomm_packet_handler = NULL;
2284     hfp_ag_rfcomm_packet_handler = NULL;
2285     hfp_sco_establishment_active = NULL;
2286     hfp_custom_commands_ag = NULL;
2287     hfp_custom_commands_hf = NULL;
2288     (void) memset(&hfp_sdp_query_context, 0, sizeof(hfp_sdp_query_context_t));
2289     (void) memset(&hfp_sdp_query_request, 0, sizeof(btstack_context_callback_registration_t));
2290 }
2291 
2292 void hfp_set_sco_packet_types(uint16_t packet_types){
2293     hfp_allowed_sco_packet_types = packet_types;
2294 }
2295 
2296 uint16_t hfp_get_sco_packet_types(void){
2297     return hfp_allowed_sco_packet_types;
2298 }
2299 
2300 hfp_link_settings_t hfp_next_link_setting(hfp_link_settings_t current_setting, uint16_t local_sco_packet_types,
2301                                           uint16_t remote_sco_packet_types, bool eSCO_S4_supported,
2302                                           uint8_t negotiated_codec) {
2303     int8_t setting = (int8_t) current_setting;
2304     while (setting > 0){
2305         setting--;
2306         // skip S4 if not supported
2307         if ((setting == (int8_t) HFP_LINK_SETTINGS_S4) && !eSCO_S4_supported) continue;
2308         // skip wrong codec
2309         if ((hfp_link_settings[setting].codec_mask & (1 << negotiated_codec)) == 0) continue;
2310         // skip disabled or not supported packet types
2311         uint16_t required_packet_types = hfp_link_settings[setting].packet_types;
2312         uint16_t allowed_packet_types  = hfp_allowed_sco_packet_types & local_sco_packet_types & remote_sco_packet_types;
2313         if ((required_packet_types & allowed_packet_types) == 0) continue;
2314 
2315         // found matching setting
2316         return (hfp_link_settings_t) setting;
2317     }
2318     return HFP_LINK_SETTINGS_NONE;
2319 }
2320 
2321 static hfp_link_settings_t hfp_next_link_setting_for_connection(hfp_link_settings_t current_setting, hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported){
2322     uint8_t negotiated_codec   = hfp_connection->negotiated_codec;
2323     uint16_t local_sco_packet_types = hci_usable_sco_packet_types();
2324     uint16_t remote_sco_packet_types = hci_remote_sco_packet_types(hfp_connection->acl_handle);
2325     return hfp_next_link_setting(current_setting, local_sco_packet_types, remote_sco_packet_types, eSCO_S4_supported,
2326                                  negotiated_codec);
2327 }
2328 
2329 void hfp_init_link_settings(hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported){
2330     // get highest possible link setting
2331     hfp_connection->link_setting = hfp_next_link_setting_for_connection(HFP_LINK_SETTINGS_NONE, hfp_connection, eSCO_S4_supported);
2332     log_info("hfp_init_link_settings: %u", hfp_connection->link_setting);
2333 }
2334 
2335 #define HFP_HF_RX_DEBUG_PRINT_LINE 80
2336 
2337 void hfp_log_rfcomm_message(const char * tag, uint8_t * packet, uint16_t size){
2338 #ifdef ENABLE_LOG_INFO
2339     // encode \n\r
2340     char printable[HFP_HF_RX_DEBUG_PRINT_LINE+2];
2341     int i = 0;
2342     int pos;
2343     for (pos=0 ; (pos < size) && (i < (HFP_HF_RX_DEBUG_PRINT_LINE - 3)) ; pos++){
2344         switch (packet[pos]){
2345             case '\n':
2346                 printable[i++] = '\\';
2347                 printable[i++] = 'n';
2348                 break;
2349             case '\r':
2350                 printable[i++] = '\\';
2351                 printable[i++] = 'r';
2352                 break;
2353             default:
2354                 printable[i++] = packet[pos];
2355                 break;
2356         }
2357     }
2358     printable[i] = 0;
2359     log_info("%s: '%s'", tag, printable);
2360 #endif
2361 }
2362 
2363 void hfp_register_custom_ag_command(hfp_custom_at_command_t * custom_at_command){
2364     btstack_linked_list_add(&hfp_custom_commands_ag, (btstack_linked_item_t *) custom_at_command);
2365 }
2366 
2367 void hfp_register_custom_hf_command(hfp_custom_at_command_t * custom_at_command){
2368     btstack_linked_list_add(&hfp_custom_commands_hf, (btstack_linked_item_t *) custom_at_command);
2369 }
2370 
2371 // HFP H2 Synchronization - might get moved into a hfp_h2.c
2372 
2373 // find position of h2 sync header, returns -1 if not found, or h2 sync position
2374 static int16_t hfp_h2_sync_find(const uint8_t * frame_data, uint16_t frame_len){
2375     uint16_t i;
2376     for (i=0;i<(frame_len - 1);i++){
2377         // check: first byte == 1
2378         uint8_t h2_first_byte = frame_data[i];
2379         if (h2_first_byte == 0x01) {
2380             uint8_t h2_second_byte = frame_data[i + 1];
2381             // check lower nibble of second byte == 0x08
2382             if ((h2_second_byte & 0x0F) == 8) {
2383                 // check if bits 0+2 == bits 1+3
2384                 uint8_t hn = h2_second_byte >> 4;
2385                 if (((hn >> 1) & 0x05) == (hn & 0x05)) {
2386                     return (int16_t) i;
2387                 }
2388             }
2389         }
2390     }
2391     return -1;
2392 }
2393 
2394 static void hfp_h2_sync_reset(hfp_h2_sync_t * hfp_h2_sync){
2395     hfp_h2_sync->frame_len = 0;
2396 }
2397 
2398 void hfp_h2_sync_init(hfp_h2_sync_t * hfp_h2_sync,
2399                       bool (*callback)(bool bad_frame, const uint8_t * frame_data, uint16_t frame_len)){
2400     hfp_h2_sync->callback = callback;
2401     hfp_h2_sync->dropped_bytes = 0;
2402     hfp_h2_sync_reset(hfp_h2_sync);
2403 }
2404 
2405 static void hfp_h2_report_bad_frames(hfp_h2_sync_t *hfp_h2_sync){
2406     // report bad frames
2407     while (hfp_h2_sync->dropped_bytes >= HFP_H2_SYNC_FRAME_SIZE){
2408         hfp_h2_sync->dropped_bytes -= HFP_H2_SYNC_FRAME_SIZE;
2409         (void)(*hfp_h2_sync->callback)(true,NULL, HFP_H2_SYNC_FRAME_SIZE);
2410     }
2411 }
2412 
2413 static void hfp_h2_sync_drop_bytes(hfp_h2_sync_t * hfp_h2_sync, uint16_t bytes_to_drop){
2414     btstack_assert(bytes_to_drop <= hfp_h2_sync->frame_len);
2415     memmove(hfp_h2_sync->frame_data, &hfp_h2_sync->frame_data[bytes_to_drop], hfp_h2_sync->frame_len - bytes_to_drop);
2416     hfp_h2_sync->dropped_bytes += bytes_to_drop;
2417     hfp_h2_sync->frame_len     -= bytes_to_drop;
2418     hfp_h2_report_bad_frames(hfp_h2_sync);
2419 }
2420 
2421 void hfp_h2_sync_process(hfp_h2_sync_t *hfp_h2_sync, bool bad_frame, const uint8_t *frame_data, uint16_t frame_len) {
2422 
2423     if (bad_frame){
2424         // drop all data
2425         hfp_h2_sync->dropped_bytes += hfp_h2_sync->frame_len;
2426         hfp_h2_sync->frame_len = 0;
2427         // all new data is bad, too
2428         hfp_h2_sync->dropped_bytes += frame_len;
2429         // report frames
2430         hfp_h2_report_bad_frames(hfp_h2_sync);
2431         return;
2432     }
2433 
2434     while (frame_len > 0){
2435         // Fill hfp_h2_sync->frame_buffer
2436         uint16_t bytes_free_in_frame_buffer = HFP_H2_SYNC_FRAME_SIZE - hfp_h2_sync->frame_len;
2437         uint16_t bytes_to_append = btstack_min(frame_len, bytes_free_in_frame_buffer);
2438         memcpy(&hfp_h2_sync->frame_data[hfp_h2_sync->frame_len], frame_data, bytes_to_append);
2439         frame_data             += bytes_to_append;
2440         frame_len              -= bytes_to_append;
2441         hfp_h2_sync->frame_len += bytes_to_append;
2442         // check complete frame for h2 sync
2443         if (hfp_h2_sync->frame_len == HFP_H2_SYNC_FRAME_SIZE){
2444             bool valid_frame = true;
2445             int16_t h2_pos = hfp_h2_sync_find(hfp_h2_sync->frame_data, hfp_h2_sync->frame_len);
2446             if (h2_pos < 0){
2447                 // no h2 sync, no valid frame, keep last byte if it is 0x01
2448                 if (hfp_h2_sync->frame_data[HFP_H2_SYNC_FRAME_SIZE-1] == 0x01){
2449                     hfp_h2_sync_drop_bytes(hfp_h2_sync, HFP_H2_SYNC_FRAME_SIZE - 1);
2450                 } else {
2451                     hfp_h2_sync_drop_bytes(hfp_h2_sync, HFP_H2_SYNC_FRAME_SIZE);
2452                 }
2453                 valid_frame = false;
2454             }
2455             else if (h2_pos > 0){
2456                 // drop data before h2 sync
2457                 hfp_h2_sync_drop_bytes(hfp_h2_sync, h2_pos);
2458                 valid_frame = false;
2459             }
2460             if (valid_frame) {
2461                 // h2 sync at pos 0 and complete frame
2462                 bool codec_ok = (*hfp_h2_sync->callback)(false, hfp_h2_sync->frame_data, hfp_h2_sync->frame_len);
2463                 if (codec_ok){
2464                     hfp_h2_sync_reset(hfp_h2_sync);
2465                 } else {
2466                     // drop first two bytes
2467                     hfp_h2_sync_drop_bytes(hfp_h2_sync, 2);
2468                 }
2469             }
2470         }
2471     }
2472 }
2473