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