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