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