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