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