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