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