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