xref: /btstack/src/classic/hfp.c (revision 457b5cb16b95dcfdb3b5786e4195d8b5b211dd71)
1 /*
2  * Copyright (C) 2014 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 // *****************************************************************************
39 //
40 // Minimal setup for HFP Audio Gateway (AG) unit (!! UNDER DEVELOPMENT !!)
41 //
42 // *****************************************************************************
43 
44 #include "btstack-config.h"
45 
46 #include <stdint.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <inttypes.h>
51 
52 #include "hci_cmds.h"
53 #include "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 "debug.h"
62 
63 #define HFP_HF_FEATURES_SIZE 10
64 #define HFP_AG_FEATURES_SIZE 12
65 
66 
67 static const char * hfp_hf_features[] = {
68     "EC and/or NR function",
69     "Three-way calling",
70     "CLI presentation capability",
71     "Voice recognition activation",
72     "Remote volume control",
73 
74     "Enhanced call status",
75     "Enhanced call control",
76 
77     "Codec negotiation",
78 
79     "HF Indicators",
80     "eSCO S4 (and T2) Settings Supported",
81     "Reserved for future definition"
82 };
83 
84 static const char * hfp_ag_features[] = {
85     "Three-way calling",
86     "EC and/or NR function",
87     "Voice recognition function",
88     "In-band ring tone capability",
89     "Attach a number to a voice tag",
90     "Ability to reject a call",
91     "Enhanced call status",
92     "Enhanced call control",
93     "Extended Error Result Codes",
94     "Codec negotiation",
95     "HF Indicators",
96     "eSCO S4 (and T2) Settings Supported",
97     "Reserved for future definition"
98 };
99 
100 static int hfp_generic_status_indicators_nr = 0;
101 static hfp_generic_status_indicator_t hfp_generic_status_indicators[HFP_MAX_NUM_HF_INDICATORS];
102 
103 static linked_list_t hfp_connections = NULL;
104 
105 hfp_generic_status_indicator_t * get_hfp_generic_status_indicators(void){
106     return (hfp_generic_status_indicator_t *) &hfp_generic_status_indicators;
107 }
108 int get_hfp_generic_status_indicators_nr(void){
109     return hfp_generic_status_indicators_nr;
110 }
111 void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr){
112     if (indicator_nr > HFP_MAX_NUM_HF_INDICATORS) return;
113     hfp_generic_status_indicators_nr = indicator_nr;
114     memcpy(hfp_generic_status_indicators, indicators, indicator_nr * sizeof(hfp_generic_status_indicator_t));
115 }
116 
117 const char * hfp_hf_feature(int index){
118     if (index > HFP_HF_FEATURES_SIZE){
119         return hfp_hf_features[HFP_HF_FEATURES_SIZE];
120     }
121     return hfp_hf_features[index];
122 }
123 
124 const char * hfp_ag_feature(int index){
125     if (index > HFP_AG_FEATURES_SIZE){
126         return hfp_ag_features[HFP_AG_FEATURES_SIZE];
127     }
128     return hfp_ag_features[index];
129 }
130 
131 int send_str_over_rfcomm(uint16_t cid, char * command){
132     if (!rfcomm_can_send_packet_now(cid)) return 1;
133     int err = rfcomm_send_internal(cid, (uint8_t*) command, strlen(command));
134     if (err){
135         log_error("rfcomm_send_internal -> error 0x%02x \n", err);
136     }
137     return 1;
138 }
139 
140 #if 0
141 void hfp_set_codec(hfp_connection_t * context, uint8_t *packet, uint16_t size){
142     // parse available codecs
143     int pos = 0;
144     int i;
145     for (i=0; i<size; i++){
146         pos+=8;
147         if (packet[pos] > context->negotiated_codec){
148             context->negotiated_codec = packet[pos];
149         }
150     }
151     printf("Negotiated Codec 0x%02x\n", context->negotiated_codec);
152 }
153 #endif
154 
155 // UTILS
156 int get_bit(uint16_t bitmap, int position){
157     return (bitmap >> position) & 1;
158 }
159 
160 int store_bit(uint32_t bitmap, int position, uint8_t value){
161     if (value){
162         bitmap |= 1 << position;
163     } else {
164         bitmap &= ~ (1 << position);
165     }
166     return bitmap;
167 }
168 
169 int join(char * buffer, int buffer_size, uint8_t * values, int values_nr){
170     if (buffer_size < values_nr * 3) return 0;
171     int i;
172     int offset = 0;
173     for (i = 0; i < values_nr-1; i++) {
174       offset += snprintf(buffer+offset, buffer_size-offset, "%d,", values[i]); // puts string into buffer
175     }
176     if (i<values_nr){
177         offset += snprintf(buffer+offset, buffer_size-offset, "%d", values[i]);
178     }
179     return offset;
180 }
181 
182 int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){
183     if (buffer_size < values_nr * 3) return 0;
184 
185     int i;
186     int offset = 0;
187     for (i = 0; i < values_nr-1; i++) {
188       offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_bit(values,i)); // puts string into buffer
189     }
190 
191     if (i<values_nr){
192         offset += snprintf(buffer+offset, buffer_size-offset, "%d", get_bit(values,i));
193     }
194     return offset;
195 }
196 
197 void hfp_emit_event(hfp_callback_t callback, uint8_t event_subtype, uint8_t value){
198     if (!callback) return;
199     uint8_t event[4];
200     event[0] = HCI_EVENT_HFP_META;
201     event[1] = sizeof(event) - 2;
202     event[2] = event_subtype;
203     event[3] = value; // status 0 == OK
204     (*callback)(event, sizeof(event));
205 }
206 
207 
208 linked_list_t * hfp_get_connections(){
209     return (linked_list_t *) &hfp_connections;
210 }
211 
212 hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){
213     linked_list_iterator_t it;
214     linked_list_iterator_init(&it, hfp_get_connections());
215     while (linked_list_iterator_has_next(&it)){
216         hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
217         if (connection->rfcomm_cid == cid){
218             return connection;
219         }
220     }
221     return NULL;
222 }
223 
224 hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){
225     linked_list_iterator_t it;
226     linked_list_iterator_init(&it, hfp_get_connections());
227     while (linked_list_iterator_has_next(&it)){
228         hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
229         if (memcmp(connection->remote_addr, bd_addr, 6) == 0) {
230             return connection;
231         }
232     }
233     return NULL;
234 }
235 
236 static hfp_connection_t * get_hfp_connection_context_for_handle(uint16_t handle){
237     linked_list_iterator_t it;
238     linked_list_iterator_init(&it, hfp_get_connections());
239     while (linked_list_iterator_has_next(&it)){
240         hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
241         if (connection->con_handle == handle){
242             return connection;
243         }
244     }
245     return NULL;
246 }
247 
248 void hfp_reset_context_flags(hfp_connection_t * context){
249     if (!context) return;
250     context->wait_ok = 0;
251     context->send_ok = 0;
252     context->send_error = 0;
253 
254     context->keep_separator = 0;
255 
256     context->retrieve_ag_indicators = 0;        // HFP_CMD_INDICATOR, check if needed
257     context->retrieve_ag_indicators_status = 0;
258 
259     context->list_generic_status_indicators = 0;           // HFP_CMD_LIST_GENERIC_STATUS_INDICATOR
260     context->retrieve_generic_status_indicators = 0;       // HFP_CMD_GENERIC_STATUS_INDICATOR
261     context->retrieve_generic_status_indicators_state = 0; // HFP_CMD_GENERIC_STATUS_INDICATOR_STATE
262 
263     context->change_status_update_for_individual_ag_indicators = 0;
264 
265     context->operator_name_format = 0;
266     context->operator_name = 0;
267     context->operator_name_changed = 0;
268 
269     context->enable_extended_audio_gateway_error_report = 0;
270     context->extended_audio_gateway_error = 0;
271 
272     // can come any time (here taken into account only after SLE),
273     // if codec negotiation feature is set
274     context->notify_ag_on_new_codecs = 0;
275 
276     // establish codecs connection
277     context->ag_trigger_codec_connection_setup = 0;
278     context->hf_trigger_codec_connection_setup = 0;
279     context->suggested_codec = 0;
280     context->negotiated_codec = 0;
281     context->codec_confirmed = 0;
282 
283     context->establish_audio_connection = 0;
284 }
285 
286 static hfp_connection_t * create_hfp_connection_context(){
287     hfp_connection_t * context = btstack_memory_hfp_connection_get();
288     if (!context) return NULL;
289     // init state
290     memset(context,0, sizeof(hfp_connection_t));
291 
292     context->state = HFP_IDLE;
293     context->parser_state = HFP_PARSER_CMD_HEADER;
294     context->command = HFP_CMD_NONE;
295     context->negotiated_codec = 0;
296 
297     context->enable_status_update_for_ag_indicators = 0xFF;
298 
299     context->generic_status_indicators_nr = hfp_generic_status_indicators_nr;
300     memcpy(context->generic_status_indicators, hfp_generic_status_indicators, hfp_generic_status_indicators_nr * sizeof(hfp_generic_status_indicator_t));
301 
302     linked_list_add(&hfp_connections, (linked_item_t*)context);
303     return context;
304 }
305 
306 static void remove_hfp_connection_context(hfp_connection_t * context){
307     linked_list_remove(&hfp_connections, (linked_item_t*)context);
308 }
309 
310 static hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){
311     hfp_connection_t * context = get_hfp_connection_context_for_bd_addr(bd_addr);
312     if (context) return  context;
313     context = create_hfp_connection_context();
314     memcpy(context->remote_addr, bd_addr, 6);
315     return context;
316 }
317 
318 
319 /* @param suported_features
320  * HF bit 0: EC and/or NR function (yes/no, 1 = yes, 0 = no)
321  * HF bit 1: Call waiting or three-way calling(yes/no, 1 = yes, 0 = no)
322  * HF bit 2: CLI presentation capability (yes/no, 1 = yes, 0 = no)
323  * HF bit 3: Voice recognition activation (yes/no, 1= yes, 0 = no)
324  * HF bit 4: Remote volume control (yes/no, 1 = yes, 0 = no)
325  * HF bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
326  */
327  /* Bit position:
328  * AG bit 0: Three-way calling (yes/no, 1 = yes, 0 = no)
329  * AG bit 1: EC and/or NR function (yes/no, 1 = yes, 0 = no)
330  * AG bit 2: Voice recognition function (yes/no, 1 = yes, 0 = no)
331  * AG bit 3: In-band ring tone capability (yes/no, 1 = yes, 0 = no)
332  * AG bit 4: Attach a phone number to a voice tag (yes/no, 1 = yes, 0 = no)
333  * AG bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
334  */
335 
336 
337 void hfp_create_sdp_record(uint8_t * service, uint16_t service_uuid, int rfcomm_channel_nr, const char * name, uint16_t supported_features){
338     uint8_t* attribute;
339     de_create_sequence(service);
340 
341     // 0x0000 "Service Record Handle"
342     de_add_number(service, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle);
343     de_add_number(service, DE_UINT, DE_SIZE_32, 0x10001);
344 
345     // 0x0001 "Service Class ID List"
346     de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList);
347     attribute = de_push_sequence(service);
348     {
349         //  "UUID for Service"
350         de_add_number(attribute, DE_UUID, DE_SIZE_16, service_uuid);
351         de_add_number(attribute, DE_UUID, DE_SIZE_16, SDP_GenericAudio);
352     }
353     de_pop_sequence(service, attribute);
354 
355     // 0x0004 "Protocol Descriptor List"
356     de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_ProtocolDescriptorList);
357     attribute = de_push_sequence(service);
358     {
359         uint8_t* l2cpProtocol = de_push_sequence(attribute);
360         {
361             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, SDP_L2CAPProtocol);
362         }
363         de_pop_sequence(attribute, l2cpProtocol);
364 
365         uint8_t* rfcomm = de_push_sequence(attribute);
366         {
367             de_add_number(rfcomm,  DE_UUID, DE_SIZE_16, SDP_RFCOMMProtocol);  // rfcomm_service
368             de_add_number(rfcomm,  DE_UINT, DE_SIZE_8,  rfcomm_channel_nr);  // rfcomm channel
369         }
370         de_pop_sequence(attribute, rfcomm);
371     }
372     de_pop_sequence(service, attribute);
373 
374 
375     // 0x0005 "Public Browse Group"
376     de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_BrowseGroupList); // public browse group
377     attribute = de_push_sequence(service);
378     {
379         de_add_number(attribute,  DE_UUID, DE_SIZE_16, SDP_PublicBrowseGroup);
380     }
381     de_pop_sequence(service, attribute);
382 
383     // 0x0009 "Bluetooth Profile Descriptor List"
384     de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_BluetoothProfileDescriptorList);
385     attribute = de_push_sequence(service);
386     {
387         uint8_t *sppProfile = de_push_sequence(attribute);
388         {
389             de_add_number(sppProfile,  DE_UUID, DE_SIZE_16, SDP_Handsfree);
390             de_add_number(sppProfile,  DE_UINT, DE_SIZE_16, 0x0107); // Verision 1.7
391         }
392         de_pop_sequence(attribute, sppProfile);
393     }
394     de_pop_sequence(service, attribute);
395 
396     // 0x0100 "Service Name"
397     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
398     de_add_data(service,  DE_STRING, strlen(name), (uint8_t *) name);
399 
400     de_add_number(service, DE_UINT, DE_SIZE_16, supported_features);
401 }
402 
403 static hfp_connection_t * connection_doing_sdp_query = NULL;
404 static void handle_query_rfcomm_event(sdp_query_event_t * event, void * context){
405     sdp_query_rfcomm_service_event_t * ve;
406     sdp_query_complete_event_t * ce;
407     hfp_connection_t * connection = connection_doing_sdp_query;
408 
409     if ( connection->state != HFP_W4_SDP_QUERY_COMPLETE) return;
410 
411     switch (event->type){
412         case SDP_QUERY_RFCOMM_SERVICE:
413             ve = (sdp_query_rfcomm_service_event_t*) event;
414             if (!connection) {
415                 log_error("handle_query_rfcomm_event alloc connection for RFCOMM port %u failed", ve->channel_nr);
416                 return;
417             }
418             connection->rfcomm_channel_nr = ve->channel_nr;
419             break;
420         case SDP_QUERY_COMPLETE:
421             connection_doing_sdp_query = NULL;
422             ce = (sdp_query_complete_event_t*) event;
423 
424             if (connection->rfcomm_channel_nr > 0){
425                 connection->state = HFP_W4_RFCOMM_CONNECTED;
426                 log_info("HFP: SDP_QUERY_COMPLETE context %p, addr %s, state %d", connection, bd_addr_to_str( connection->remote_addr),  connection->state);
427                 rfcomm_create_channel(connection->remote_addr, connection->rfcomm_channel_nr, NULL);
428                 break;
429             }
430             log_info("rfcomm service not found, status %u.", ce->status);
431             break;
432         default:
433             break;
434     }
435 }
436 
437 void hfp_handle_hci_event(hfp_callback_t callback, uint8_t packet_type, uint8_t *packet, uint16_t size){
438     bd_addr_t event_addr;
439     uint16_t rfcomm_cid, handle;
440     hfp_connection_t * context = NULL;
441 
442     switch (packet[0]) {
443         case BTSTACK_EVENT_STATE:
444             // bt stack activated, get started
445             if (packet[2] == HCI_STATE_WORKING){
446                 printf("BTstack activated, get started .\n");
447             }
448             break;
449 
450         case HCI_EVENT_PIN_CODE_REQUEST:
451             // inform about pin code request
452             printf("Pin code request - using '0000'\n\r");
453             bt_flip_addr(event_addr, &packet[2]);
454             hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
455             break;
456 
457         case RFCOMM_EVENT_INCOMING_CONNECTION:
458             // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
459             bt_flip_addr(event_addr, &packet[2]);
460             context = get_hfp_connection_context_for_bd_addr(event_addr);
461 
462             if (!context || context->state != HFP_IDLE) return;
463 
464             context->rfcomm_cid = READ_BT_16(packet, 9);
465             context->state = HFP_W4_RFCOMM_CONNECTED;
466             printf("RFCOMM channel %u requested for %s\n", context->rfcomm_cid, bd_addr_to_str(context->remote_addr));
467             rfcomm_accept_connection_internal(context->rfcomm_cid);
468             break;
469 
470         case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
471             // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
472             printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);
473             bt_flip_addr(event_addr, &packet[3]);
474             context = get_hfp_connection_context_for_bd_addr(event_addr);
475             if (!context || context->state != HFP_W4_RFCOMM_CONNECTED) return;
476 
477             if (packet[2]) {
478                 hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, packet[2]);
479                 remove_hfp_connection_context(context);
480             } else {
481                 context->con_handle = READ_BT_16(packet, 9);
482                 context->rfcomm_cid = READ_BT_16(packet, 12);
483                 uint16_t mtu = READ_BT_16(packet, 14);
484                 printf("RFCOMM channel open succeeded. Context %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", context, context->rfcomm_cid, mtu);
485 
486                 switch (context->state){
487                     case HFP_W4_RFCOMM_CONNECTED:
488                         context->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
489                         break;
490                     case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
491                         context->state = HFP_W2_DISCONNECT_RFCOMM;
492                         printf("Shutting down RFCOMM.\n");
493                         break;
494                     default:
495                         break;
496                 }
497             }
498             break;
499 
500         case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
501             int index = 2;
502             uint8_t status = packet[index++];
503             uint16_t sco_handle = READ_BT_16(packet, index);
504             index+=2;
505             bd_addr_t address;
506             memcpy(address, &packet[index], 6);
507             index+=6;
508             uint8_t link_type = packet[index++];
509             uint8_t transmission_interval = packet[index++];  // measured in slots
510             uint8_t retransmission_interval = packet[index++];// measured in slots
511             uint16_t rx_packet_length = READ_BT_16(packet, index); // measured in bytes
512             index+=2;
513             uint16_t tx_packet_length = READ_BT_16(packet, index); // measured in bytes
514             index+=2;
515             uint8_t air_mode = packet[index];
516 
517             if (status != 0){
518                 log_error("(e)SCO Connection is not established, status %u", status);
519                 break;
520             }
521             switch (link_type){
522                 case 0x00:
523                     printf("SCO Connection established. \n");
524                     if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
525                     if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);
526                     if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length);
527                     if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length);
528                     break;
529                 case 0x02:
530                     printf("eSCO Connection established. \n");
531                     break;
532                 default:
533                     log_error("(e)SCO reserved link_type 0x%2x", link_type);
534                     break;
535             }
536             log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, "
537                  " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)", sco_handle,
538                  bd_addr_to_str(address), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);
539 
540             context = get_hfp_connection_context_for_bd_addr(address);
541 
542             if (context->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
543                 context->state = HFP_W2_DISCONNECT_SCO;
544                 break;
545             }
546 
547             context->sco_handle = sco_handle;
548             context->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
549             hfp_emit_event(callback, HFP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, packet[2]);
550             break;
551         }
552 
553         case RFCOMM_EVENT_CHANNEL_CLOSED:
554             rfcomm_cid = READ_BT_16(packet,2);
555             context = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
556             if (!context) break;
557             if (context->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
558                 context->state = HFP_IDLE;
559                 hfp_establish_service_level_connection(context->remote_addr, context->service_uuid);
560                 break;
561             }
562 
563             hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
564             remove_hfp_connection_context(context);
565             break;
566 
567         case HCI_EVENT_DISCONNECTION_COMPLETE:
568             handle = READ_BT_16(packet,3);
569             context = get_hfp_connection_context_for_handle(handle);
570             if (!context) break;
571             if (context->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
572                 context->state = HFP_IDLE;
573                 hfp_establish_service_level_connection(context->remote_addr, context->service_uuid);
574                 break;
575             }
576             hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, packet[2]);
577             remove_hfp_connection_context(context);
578             break;
579 
580         default:
581             break;
582     }
583 }
584 
585 // translates command string into hfp_command_t CMD and flags to distinguish between CMD=, CMD?, CMD=?
586 static void process_command(hfp_connection_t * context){
587     if (context->line_size < 2) return;
588     // printf("process_command %s\n", context->line_buffer);
589     context->command = HFP_CMD_NONE;
590     int offset = 0;
591     int isHandsFree = 1;
592 
593     if (strncmp((char *)context->line_buffer, "AT", 2) == 0){
594         offset = 2;
595         isHandsFree = 0;
596     }
597 
598     if (strncmp((char *)context->line_buffer+offset, HFP_ERROR, strlen(HFP_ERROR)) == 0){
599         context->command = HFP_CMD_ERROR;
600         return;
601     }
602 
603     if (isHandsFree && strncmp((char *)context->line_buffer+offset, HFP_OK, strlen(HFP_OK)) == 0){
604         //printf("parsed HFP_CMD_OK \n");
605         context->command = HFP_CMD_OK;
606         return;
607     }
608 
609     if (strncmp((char *)context->line_buffer+offset, HFP_SUPPORTED_FEATURES, strlen(HFP_SUPPORTED_FEATURES)) == 0){
610         context->command = HFP_CMD_SUPPORTED_FEATURES;
611         return;
612     }
613 
614     if (strncmp((char *)context->line_buffer+offset, HFP_INDICATOR, strlen(HFP_INDICATOR)) == 0){
615         //printf("parsed HFP_INDICATOR \n");
616         context->command = HFP_CMD_INDICATOR;
617         if (isHandsFree) return;
618 
619         if (strncmp((char *)context->line_buffer+strlen(HFP_INDICATOR)+offset, "?", 1) == 0){
620             context->retrieve_ag_indicators_status = 1;
621             context->retrieve_ag_indicators = 0;
622         } else {
623             context->retrieve_ag_indicators = 1;
624             context->retrieve_ag_indicators_status = 0;
625         }
626         return;
627     }
628 
629     if (strncmp((char *)context->line_buffer+offset, HFP_AVAILABLE_CODECS, strlen(HFP_AVAILABLE_CODECS)) == 0){
630         context->command = HFP_CMD_AVAILABLE_CODECS;
631         context->notify_ag_on_new_codecs = 1;
632         return;
633     }
634 
635     if (strncmp((char *)context->line_buffer+offset, HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, strlen(HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS)) == 0){
636         context->command = HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE;
637         return;
638     }
639 
640     if (strncmp((char *)context->line_buffer+offset, HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES, strlen(HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES)) == 0){
641         context->command = HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES;
642         return;
643     }
644 
645     if (strncmp((char *)context->line_buffer+offset, HFP_GENERIC_STATUS_INDICATOR, strlen(HFP_GENERIC_STATUS_INDICATOR)) == 0){
646         context->command = HFP_CMD_GENERIC_STATUS_INDICATOR;
647         if (isHandsFree) return;
648 
649         if (strncmp((char *)context->line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=?", 2) == 0){
650             context->list_generic_status_indicators = 0;
651             context->retrieve_generic_status_indicators = 1;
652             context->retrieve_generic_status_indicators_state = 0;
653         } else if (strncmp((char *)context->line_buffer+strlen(HFP_GENERIC_STATUS_INDICATOR)+offset, "=", 1) == 0){
654             context->list_generic_status_indicators = 1;
655             context->retrieve_generic_status_indicators = 0;
656             context->retrieve_generic_status_indicators_state = 0;
657         } else {
658             context->list_generic_status_indicators = 0;
659             context->retrieve_generic_status_indicators = 0;
660             context->retrieve_generic_status_indicators_state = 1;
661         }
662         return;
663     }
664 
665     if (strncmp((char *)context->line_buffer+offset, HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS, strlen(HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS)) == 0){
666         context->command = HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE;
667         return;
668     }
669 
670 
671     if (strncmp((char *)context->line_buffer+offset, HFP_QUERY_OPERATOR_SELECTION, strlen(HFP_QUERY_OPERATOR_SELECTION)) == 0){
672         context->command = HFP_CMD_QUERY_OPERATOR_SELECTION;
673         context->operator_name = 1;
674         context->operator_name_format = 0;
675         if (isHandsFree) return;
676 
677         context->operator_name = 0;
678         if (strncmp((char *)context->line_buffer+strlen(HFP_QUERY_OPERATOR_SELECTION)+offset, "=", 1) == 0){
679             context->operator_name_format = 1;
680         }
681         return;
682     }
683 
684     if (strncmp((char *)context->line_buffer+offset, HFP_TRANSFER_AG_INDICATOR_STATUS, strlen(HFP_TRANSFER_AG_INDICATOR_STATUS)) == 0){
685         context->command = HFP_CMD_TRANSFER_AG_INDICATOR_STATUS;
686         return;
687     }
688 
689     if (isHandsFree && strncmp((char *)context->line_buffer+offset, HFP_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){
690         context->command = HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR;
691         return;
692     }
693 
694     if (!isHandsFree && strncmp((char *)context->line_buffer+offset, HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, strlen(HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR)) == 0){
695         context->command = HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR;
696         return;
697     }
698 
699     if (strncmp((char *)context->line_buffer+offset, HFP_TRIGGER_CODEC_CONNECTION_SETUP, strlen(HFP_TRIGGER_CODEC_CONNECTION_SETUP)) == 0){
700         context->command = HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP;
701         // printf("HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP update command\n");
702         if (isHandsFree){
703             context->hf_trigger_codec_connection_setup = 1;
704             printf("update command: hf_trigger_codec_connection_setup = 1\n");
705         } else {
706             context->hf_trigger_codec_connection_setup = 1;
707             printf("update command: hf_trigger_codec_connection_setup = 1\n");
708         }
709         return;
710     }
711 
712     if (strncmp((char *)context->line_buffer+offset, HFP_CONFIRM_COMMON_CODEC, strlen(HFP_CONFIRM_COMMON_CODEC)) == 0){
713         if (!isHandsFree){
714             context->command = HFP_CMD_HF_CONFIRMED_CODEC;
715         } else {
716             context->command = HFP_CMD_AG_SUGGESTED_CODEC;
717         }
718         return;
719     }
720 
721     if (strncmp((char *)context->line_buffer+offset, "NOP", 3) == 0) return;
722 
723     printf(" process unknown command 3 %s \n", context->line_buffer);
724 }
725 
726 #if 0
727 uint32_t fromBinary(char *s) {
728     return (uint32_t) strtol(s, NULL, 2);
729 }
730 #endif
731 
732 static void hfp_parser_store_byte(hfp_connection_t * context, uint8_t byte){
733     // TODO: add limit
734     context->line_buffer[context->line_size++] = byte;
735     context->line_buffer[context->line_size] = 0;
736 }
737 static int hfp_parser_is_buffer_empty(hfp_connection_t * context){
738     return context->line_size == 0;
739 }
740 
741 static int hfp_parser_is_end_of_line(uint8_t byte){
742     return byte == '\n' || byte == '\r';
743 }
744 
745 static int hfp_parser_is_end_of_header(uint8_t byte){
746     return hfp_parser_is_end_of_line(byte) || byte == ':' || byte == '?';
747 }
748 
749 static int hfp_parser_found_separator(hfp_connection_t * context, uint8_t byte){
750     if (context->keep_separator == 1) return 1;
751 
752     int found_separator =   byte == ',' || byte == '\n'|| byte == '\r'||
753                             byte == ')' || byte == '(' || byte == ':' ||
754                             byte == '-' || byte == '"' ||  byte == '?'|| byte == '=';
755     return found_separator;
756 }
757 
758 static void hfp_parser_next_state(hfp_connection_t * context, uint8_t byte){
759     context->line_size = 0;
760     if (hfp_parser_is_end_of_line(byte)){
761         context->parser_item_index = 0;
762         context->parser_state = HFP_PARSER_CMD_HEADER;
763         return;
764     }
765     switch (context->parser_state){
766         case HFP_PARSER_CMD_HEADER:
767             context->parser_state = HFP_PARSER_CMD_SEQUENCE;
768             if (context->keep_separator == 1){
769                 hfp_parser_store_byte(context, byte);
770                 context->keep_separator = 0;
771             }
772             break;
773         case HFP_PARSER_CMD_SEQUENCE:
774             switch (context->command){
775                 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
776                 case HFP_CMD_QUERY_OPERATOR_SELECTION:
777                     context->parser_state = HFP_PARSER_SECOND_ITEM;
778                     break;
779                 case HFP_CMD_INDICATOR:
780                     if (context->retrieve_ag_indicators == 1){
781                         context->parser_state = HFP_PARSER_SECOND_ITEM;
782                         break;
783                     }
784                     break;
785                 case HFP_CMD_GENERIC_STATUS_INDICATOR:
786                     if (context->retrieve_generic_status_indicators_state == 1){
787                         context->parser_state = HFP_PARSER_SECOND_ITEM;
788                         break;
789                     }
790                     break;
791                 default:
792                     break;
793             }
794             break;
795         case HFP_PARSER_SECOND_ITEM:
796             context->parser_state = HFP_PARSER_THIRD_ITEM;
797             break;
798         case HFP_PARSER_THIRD_ITEM:
799             if (context->command == HFP_CMD_INDICATOR && context->retrieve_ag_indicators){
800                 context->parser_state = HFP_PARSER_CMD_SEQUENCE;
801                 break;
802             }
803             context->parser_state = HFP_PARSER_CMD_HEADER;
804             break;
805     }
806 }
807 
808 void hfp_parse(hfp_connection_t * context, uint8_t byte){
809     int value;
810 
811     // TODO: handle space inside word
812     if (byte == ' ' && context->parser_state > HFP_PARSER_CMD_HEADER) return;
813 
814     if (!hfp_parser_found_separator(context, byte)){
815         hfp_parser_store_byte(context, byte);
816         return;
817     }
818     if (hfp_parser_is_end_of_line(byte)) {
819         if (hfp_parser_is_buffer_empty(context)){
820             context->parser_state = HFP_PARSER_CMD_HEADER;
821         }
822     }
823     if (hfp_parser_is_buffer_empty(context)) return;
824 
825 
826     switch (context->parser_state){
827         case HFP_PARSER_CMD_HEADER: // header
828             if (byte == '='){
829                 context->keep_separator = 1;
830                 hfp_parser_store_byte(context, byte);
831                 return;
832             }
833 
834             if (byte == '?'){
835                 context->keep_separator = 0;
836                 hfp_parser_store_byte(context, byte);
837                 return;
838             }
839             // printf(" parse header 2 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator);
840             if (hfp_parser_is_end_of_header(byte) || context->keep_separator == 1){
841                 // printf(" parse header 3 %s, keep separator $ %d\n", context->line_buffer, context->keep_separator);
842                 process_command(context);
843             }
844             break;
845 
846         case HFP_PARSER_CMD_SEQUENCE: // parse comma separated sequence, ignore breacktes
847             switch (context->command){
848                 case HFP_CMD_HF_CONFIRMED_CODEC:
849                     context->codec_confirmed = atoi((char*)context->line_buffer);
850                     log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", context->codec_confirmed);
851                     break;
852                 case HFP_CMD_AG_SUGGESTED_CODEC:
853                     context->suggested_codec = atoi((char*)context->line_buffer);
854                     log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", context->suggested_codec);
855                     break;
856                 case HFP_CMD_SUPPORTED_FEATURES:
857                     context->remote_supported_features = atoi((char*)context->line_buffer);
858                     log_info("Parsed supported feature %d\n", context->remote_supported_features);
859                     break;
860                 case HFP_CMD_AVAILABLE_CODECS:
861                     log_info("Parsed codec %s\n", context->line_buffer);
862                     context->remote_codecs[context->parser_item_index] = (uint16_t)atoi((char*)context->line_buffer);
863                     context->parser_item_index++;
864                     context->remote_codecs_nr = context->parser_item_index;
865                     break;
866                 case HFP_CMD_INDICATOR:
867                     if (context->retrieve_ag_indicators == 1){
868                         strcpy((char *)context->ag_indicators[context->parser_item_index].name,  (char *)context->line_buffer);
869                         context->ag_indicators[context->parser_item_index].index = context->parser_item_index+1;
870                         log_info("Indicator %d: %s (", context->ag_indicators_nr+1, context->line_buffer);
871                     }
872 
873                     if (context->retrieve_ag_indicators_status == 1){
874                         log_info("Parsed Indicator %d with status: %s\n", context->parser_item_index+1, context->line_buffer);
875                         context->ag_indicators[context->parser_item_index].status = atoi((char *) context->line_buffer);
876                         context->parser_item_index++;
877                         break;
878                     }
879                     break;
880                 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
881                     context->parser_item_index++;
882                     if (context->parser_item_index != 4) break;
883                     log_info("Parsed Enable indicators: %s\n", context->line_buffer);
884                     value = atoi((char *)&context->line_buffer[0]);
885                     context->enable_status_update_for_ag_indicators = (uint8_t) value;
886                     break;
887                 case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
888                     log_info("Parsed Support call hold: %s\n", context->line_buffer);
889                     if (context->line_size > 2 ) break;
890                     strcpy((char *)context->remote_call_services[context->remote_call_services_nr].name,  (char *)context->line_buffer);
891                     context->remote_call_services_nr++;
892                     break;
893                 case HFP_CMD_GENERIC_STATUS_INDICATOR:
894                     log_info("parser HFP_CMD_GENERIC_STATUS_INDICATOR 1 (%d, %d, %d)\n",
895                             context->list_generic_status_indicators,
896                             context->retrieve_generic_status_indicators,
897                             context->retrieve_generic_status_indicators_state);
898                     if (context->retrieve_generic_status_indicators == 1 || context->list_generic_status_indicators == 1){
899                         log_info("Parsed Generic status indicator: %s\n", context->line_buffer);
900                         context->generic_status_indicators[context->parser_item_index].uuid = (uint16_t)atoi((char*)context->line_buffer);
901                         context->parser_item_index++;
902                         context->generic_status_indicators_nr = context->parser_item_index;
903                         break;
904                     }
905                     log_info("parser HFP_CMD_GENERIC_STATUS_INDICATOR 2\n");
906                     if (context->retrieve_generic_status_indicators_state == 1){
907                         // HF parses inital AG gen. ind. state
908                         log_info("Parsed List generic status indicator %s state: ", context->line_buffer);
909                         context->parser_item_index = (uint8_t)atoi((char*)context->line_buffer);
910                         break;
911                     }
912                     break;
913 
914                 case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:
915                     // AG parses new gen. ind. state
916                     log_info("Parsed Enable ag indicator state: %s\n", context->line_buffer);
917                     value = atoi((char *)&context->line_buffer[0]);
918                     if (!context->ag_indicators[context->parser_item_index].mandatory){
919                         context->ag_indicators[context->parser_item_index].enabled = value;
920                     }
921                     context->parser_item_index++;
922                     break;
923                 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
924                     // indicators are indexed starting with 1
925                     context->parser_item_index = atoi((char *)&context->line_buffer[0]) - 1;
926                     log_info("Parsed status of the AG indicator %d, status ", context->parser_item_index);
927                     break;
928                 case HFP_CMD_QUERY_OPERATOR_SELECTION:
929                     if (context->operator_name_format == 1){
930                         if (context->line_buffer[0] == '3'){
931                             log_info("Parsed Set network operator format : %s, ", context->line_buffer);
932                             break;
933                         }
934                         // TODO emit ERROR, wrong format
935                         log_info("ERROR Set network operator format: index %s not supported\n", context->line_buffer);
936                         break;
937                     }
938 
939                     if (context->operator_name == 1) {
940                         context->network_operator.mode = atoi((char *)&context->line_buffer[0]);
941                         log_info("Parsed network operator mode: %d, ", context->network_operator.mode);
942                         break;
943                     }
944                     break;
945                 case HFP_CMD_ERROR:
946                     break;
947                 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
948                     context->extended_audio_gateway_error = (uint8_t)atoi((char*)context->line_buffer);
949                     break;
950                 case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR:
951                     context->enable_extended_audio_gateway_error_report = (uint8_t)atoi((char*)context->line_buffer);
952                     context->send_ok = 1;
953                     context->extended_audio_gateway_error = 0;
954                     break;
955                 default:
956                     break;
957             }
958             break;
959 
960         case HFP_PARSER_SECOND_ITEM:
961             switch (context->command){
962                 case HFP_CMD_QUERY_OPERATOR_SELECTION:
963                     if (context->operator_name_format == 1) {
964                         log_info("format %s \n", context->line_buffer);
965                         context->network_operator.format =  atoi((char *)&context->line_buffer[0]);
966                         break;
967                     }
968                     if (context->operator_name == 1){
969                         log_info("format %s, ", context->line_buffer);
970                         context->network_operator.format =  atoi((char *)&context->line_buffer[0]);
971                     }
972                     break;
973                 case HFP_CMD_GENERIC_STATUS_INDICATOR:
974                     context->generic_status_indicators[context->parser_item_index].state = (uint8_t)atoi((char*)context->line_buffer);
975                     break;
976                 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
977                     context->ag_indicators[context->parser_item_index].status = (uint8_t)atoi((char*)context->line_buffer);
978                     context->ag_indicators[context->parser_item_index].status_changed = 1;
979                     break;
980                 case HFP_CMD_INDICATOR:
981                     if (context->retrieve_ag_indicators == 1){
982                         context->ag_indicators[context->parser_item_index].min_range = atoi((char *)context->line_buffer);
983                         log_info("%s, ", context->line_buffer);
984                     }
985                     break;
986                 default:
987                     break;
988             }
989             break;
990 
991         case HFP_PARSER_THIRD_ITEM:
992              switch (context->command){
993                 case HFP_CMD_QUERY_OPERATOR_SELECTION:
994                     if (context->operator_name == 1){
995                         strcpy(context->network_operator.name, (char *)context->line_buffer);
996                         log_info("name %s\n", context->line_buffer);
997                     }
998                     break;
999                 case HFP_CMD_INDICATOR:
1000                     if (context->retrieve_ag_indicators == 1){
1001                         context->ag_indicators[context->parser_item_index].max_range = atoi((char *)context->line_buffer);
1002                         context->parser_item_index++;
1003                         context->ag_indicators_nr = context->parser_item_index;
1004                         log_info("%s)\n", context->line_buffer);
1005                     }
1006                     break;
1007                 default:
1008                     break;
1009             }
1010             break;
1011     }
1012     hfp_parser_next_state(context, byte);
1013 }
1014 
1015 void hfp_init(uint16_t rfcomm_channel_nr){
1016     rfcomm_register_service(rfcomm_channel_nr, 0xffff);
1017     sdp_query_rfcomm_register_callback(handle_query_rfcomm_event, NULL);
1018 }
1019 
1020 void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){
1021     hfp_connection_t * context = provide_hfp_connection_context_for_bd_addr(bd_addr);
1022     log_info("hfp_connect %s, context %p", bd_addr_to_str(bd_addr), context);
1023 
1024     if (!context) {
1025         log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr));
1026         return;
1027     }
1028     switch (context->state){
1029         case HFP_W2_DISCONNECT_RFCOMM:
1030             context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
1031             return;
1032         case HFP_W4_RFCOMM_DISCONNECTED:
1033             context->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART;
1034             return;
1035         case HFP_IDLE:
1036             memcpy(context->remote_addr, bd_addr, 6);
1037             context->state = HFP_W4_SDP_QUERY_COMPLETE;
1038             connection_doing_sdp_query = context;
1039             context->service_uuid = service_uuid;
1040             sdp_query_rfcomm_channel_and_name_for_uuid(context->remote_addr, service_uuid);
1041             break;
1042         default:
1043             break;
1044     }
1045 }
1046 
1047 void hfp_release_service_level_connection(hfp_connection_t * context){
1048     if (!context) return;
1049 
1050     if (context->state < HFP_W4_RFCOMM_CONNECTED){
1051         context->state = HFP_IDLE;
1052         return;
1053     }
1054 
1055     if (context->state == HFP_W4_RFCOMM_CONNECTED){
1056         context->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
1057         return;
1058     }
1059 
1060     if (context->state < HFP_CCE_W4_SCO_CONNECTION_ESTABLISHED){
1061         context->state = HFP_W2_DISCONNECT_RFCOMM;
1062         return;
1063     }
1064 
1065     if (context->state < HFP_W4_SCO_DISCONNECTED){
1066         context->state = HFP_W2_DISCONNECT_SCO;
1067         return;
1068     }
1069 
1070     return;
1071 }
1072 
1073 void hfp_release_audio_connection(hfp_connection_t * connection){
1074     if (!connection) return;
1075     if (connection->state >= HFP_W2_DISCONNECT_SCO) return;
1076     connection->release_audio_connection = 1;
1077 }
1078 
1079 
1080