xref: /btstack/src/classic/hfp_hf.c (revision 8caefee39d444df6d8908a96a844825f10fbdaa4)
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 Hands-Free (HF) 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 
51 #include "hci_cmds.h"
52 #include "run_loop.h"
53 
54 #include "hci.h"
55 #include "btstack_memory.h"
56 #include "hci_dump.h"
57 #include "l2cap.h"
58 #include "sdp_query_rfcomm.h"
59 #include "sdp.h"
60 #include "debug.h"
61 #include "hfp.h"
62 #include "hfp_hf.h"
63 
64 
65 static const char default_hfp_hf_service_name[] = "Hands-Free unit";
66 static uint16_t hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
67 static uint8_t hfp_codecs_nr = 0;
68 static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS];
69 
70 static uint8_t hfp_indicators_nr = 0;
71 static uint8_t hfp_indicators[HFP_MAX_NUM_HF_INDICATORS];
72 static uint8_t hfp_indicators_status;
73 
74 static hfp_callback_t hfp_callback;
75 
76 void hfp_hf_register_packet_handler(hfp_callback_t callback){
77     hfp_callback = callback;
78     if (callback == NULL){
79         log_error("hfp_hf_register_packet_handler called with NULL callback");
80         return;
81     }
82     hfp_callback = callback;
83 }
84 
85 static int hfp_hf_supports_codec(uint8_t codec){
86     int i;
87     for (i = 0; i < hfp_codecs_nr; i++){
88         if (hfp_codecs[i] == codec) return 1;
89     }
90     return 0;
91 }
92 static int has_codec_negotiation_feature(hfp_connection_t * connection){
93     int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION);
94     int ag = get_bit(connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION);
95     return hf && ag;
96 }
97 
98 static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * connection){
99     int hf = get_bit(hfp_supported_features, HFP_HFSF_THREE_WAY_CALLING);
100     int ag = get_bit(connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING);
101     return hf && ag;
102 }
103 
104 
105 static int has_hf_indicators_feature(hfp_connection_t * connection){
106     int hf = get_bit(hfp_supported_features, HFP_HFSF_HF_INDICATORS);
107     int ag = get_bit(connection->remote_supported_features, HFP_AGSF_HF_INDICATORS);
108     return hf && ag;
109 }
110 
111 static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
112 
113 void hfp_hf_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint16_t supported_features){
114     if (!name){
115         name = default_hfp_hf_service_name;
116     }
117     hfp_create_sdp_record(service, SDP_Handsfree, rfcomm_channel_nr, name, supported_features);
118 }
119 
120 
121 static int hfp_hf_cmd_exchange_supported_features(uint16_t cid){
122     char buffer[20];
123     sprintf(buffer, "AT%s=%d\r\n", HFP_SUPPORTED_FEATURES, hfp_supported_features);
124     // printf("exchange_supported_features %s\n", buffer);
125     return send_str_over_rfcomm(cid, buffer);
126 }
127 
128 static int hfp_hf_cmd_notify_on_codecs(uint16_t cid){
129     char buffer[30];
130     int offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_AVAILABLE_CODECS);
131     offset += join(buffer+offset, sizeof(buffer)-offset, hfp_codecs, hfp_codecs_nr);
132     offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n");
133     buffer[offset] = 0;
134     return send_str_over_rfcomm(cid, buffer);
135 }
136 
137 static int hfp_hf_cmd_retrieve_indicators(uint16_t cid){
138     char buffer[20];
139     sprintf(buffer, "AT%s=?\r\n", HFP_INDICATOR);
140     // printf("retrieve_indicators %s\n", buffer);
141     return send_str_over_rfcomm(cid, buffer);
142 }
143 
144 static int hfp_hf_cmd_retrieve_indicators_status(uint16_t cid){
145     char buffer[20];
146     sprintf(buffer, "AT%s?\r\n", HFP_INDICATOR);
147     // printf("retrieve_indicators_status %s\n", buffer);
148     return send_str_over_rfcomm(cid, buffer);
149 }
150 
151 static int hfp_hf_cmd_activate_status_update_for_all_ag_indicators(uint16_t cid, uint8_t activate){
152     char buffer[20];
153     sprintf(buffer, "AT%s=3,0,0,%d\r\n", HFP_ENABLE_STATUS_UPDATE_FOR_AG_INDICATORS, activate);
154     // printf("toggle_indicator_status_update %s\n", buffer);
155     return send_str_over_rfcomm(cid, buffer);
156 }
157 
158 static int hfp_hf_cmd_activate_status_update_for_ag_indicator(uint16_t cid, uint32_t indicators_status, int indicators_nr){
159     char buffer[50];
160     int offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_UPDATE_ENABLE_STATUS_FOR_INDIVIDUAL_AG_INDICATORS);
161     offset += join_bitmap(buffer+offset, sizeof(buffer)-offset, indicators_status, indicators_nr);
162     offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n");
163     buffer[offset] = 0;
164     return send_str_over_rfcomm(cid, buffer);
165 }
166 
167 static int hfp_hf_cmd_retrieve_can_hold_call(uint16_t cid){
168     char buffer[20];
169     sprintf(buffer, "AT%s=?\r\n", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES);
170     // printf("retrieve_can_hold_call %s\n", buffer);
171     return send_str_over_rfcomm(cid, buffer);
172 }
173 
174 static int hfp_hf_cmd_list_supported_generic_status_indicators(uint16_t cid){
175     char buffer[30];
176     int offset = snprintf(buffer, sizeof(buffer), "AT%s=", HFP_GENERIC_STATUS_INDICATOR);
177     offset += join(buffer+offset, sizeof(buffer)-offset, hfp_indicators, hfp_indicators_nr);
178     offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n");
179     buffer[offset] = 0;
180     return send_str_over_rfcomm(cid, buffer);
181 }
182 
183 static int hfp_hf_cmd_retrieve_supported_generic_status_indicators(uint16_t cid){
184     char buffer[20];
185     sprintf(buffer, "AT%s=?\r\n", HFP_GENERIC_STATUS_INDICATOR);
186     // printf("retrieve_supported_generic_status_indicators %s\n", buffer);
187     return send_str_over_rfcomm(cid, buffer);
188 }
189 
190 static int hfp_hf_cmd_list_initital_supported_generic_status_indicators(uint16_t cid){
191     char buffer[20];
192     sprintf(buffer, "AT%s?\r\n", HFP_GENERIC_STATUS_INDICATOR);
193     // printf("list_initital_supported_generic_status_indicators %s\n", buffer);
194     return send_str_over_rfcomm(cid, buffer);
195 }
196 
197 static int hfp_hf_cmd_query_operator_name_format(uint16_t cid){
198     char buffer[20];
199     sprintf(buffer, "AT%s=3,0\r\n", HFP_QUERY_OPERATOR_SELECTION);
200     return send_str_over_rfcomm(cid, buffer);
201 }
202 
203 static int hfp_hf_cmd_query_operator_name(uint16_t cid){
204     char buffer[20];
205     sprintf(buffer, "AT%s?\r\n", HFP_QUERY_OPERATOR_SELECTION);
206     return send_str_over_rfcomm(cid, buffer);
207 }
208 
209 static int hfp_hf_cmd_enable_extended_audio_gateway_error_report(uint16_t cid, uint8_t enable){
210     char buffer[20];
211     sprintf(buffer, "AT%s=%d\r\n", HFP_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR, enable);
212     return send_str_over_rfcomm(cid, buffer);
213 }
214 
215 static int hfp_hf_cmd_trigger_codec_connection_setup(uint16_t cid){
216     char buffer[20];
217     sprintf(buffer, "AT%s\r\n", HFP_TRIGGER_CODEC_CONNECTION_SETUP);
218     return send_str_over_rfcomm(cid, buffer);
219 }
220 
221 static int hfp_hf_cmd_confirm_codec(uint16_t cid, uint8_t codec){
222     char buffer[20];
223     sprintf(buffer, "AT%s=%d\r\n", HFP_CONFIRM_COMMON_CODEC, codec);
224     return send_str_over_rfcomm(cid, buffer);
225 }
226 
227 static void hfp_emit_ag_indicator_event(hfp_callback_t callback, int status, hfp_ag_indicator_t indicator){
228     if (!callback) return;
229     uint8_t event[6];
230     event[0] = HCI_EVENT_HFP_META;
231     event[1] = sizeof(event) - 2;
232     event[2] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED;
233     event[3] = status;
234     event[4] = indicator.index;
235     event[5] = indicator.status;
236     (*callback)(event, sizeof(event));
237 }
238 
239 static void hfp_emit_network_operator_event(hfp_callback_t callback, int status, hfp_network_opearator_t network_operator){
240     if (!callback) return;
241     uint8_t event[24];
242     event[0] = HCI_EVENT_HFP_META;
243     event[1] = sizeof(event) - 2;
244     event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED;
245     event[3] = status;
246     event[4] = network_operator.mode;
247     event[5] = network_operator.format;
248     strcpy((char*)&event[6], network_operator.name);
249     (*callback)(event, sizeof(event));
250 }
251 
252 static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * context){
253     if (context->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0;
254     int done = 0;
255     if (context->wait_ok) return done;
256 
257     switch (context->state){
258         case HFP_EXCHANGE_SUPPORTED_FEATURES:
259             hfp_hf_cmd_exchange_supported_features(context->rfcomm_cid);
260             context->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES;
261             break;
262         case HFP_NOTIFY_ON_CODECS:
263             hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid);
264             context->state = HFP_W4_NOTIFY_ON_CODECS;
265             break;
266         case HFP_RETRIEVE_INDICATORS:
267             hfp_hf_cmd_retrieve_indicators(context->rfcomm_cid);
268             context->state = HFP_W4_RETRIEVE_INDICATORS;
269             context->retrieve_ag_indicators = 1;
270             context->retrieve_ag_indicators_status = 0;
271             break;
272         case HFP_RETRIEVE_INDICATORS_STATUS:
273             hfp_hf_cmd_retrieve_indicators_status(context->rfcomm_cid);
274             context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS;
275             context->retrieve_ag_indicators_status = 1;
276             context->retrieve_ag_indicators = 0;
277             break;
278         case HFP_ENABLE_INDICATORS_STATUS_UPDATE:
279             hfp_hf_cmd_activate_status_update_for_all_ag_indicators(context->rfcomm_cid, 1);
280             context->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE;
281             break;
282         case HFP_RETRIEVE_CAN_HOLD_CALL:
283             hfp_hf_cmd_retrieve_can_hold_call(context->rfcomm_cid);
284             context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL;
285             break;
286         case HFP_LIST_GENERIC_STATUS_INDICATORS:
287             hfp_hf_cmd_list_supported_generic_status_indicators(context->rfcomm_cid);
288             context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
289             context->list_generic_status_indicators = 1;
290             context->retrieve_generic_status_indicators = 0;
291             context->retrieve_generic_status_indicators_state = 0;
292             break;
293         case HFP_RETRIEVE_GENERIC_STATUS_INDICATORS:
294             hfp_hf_cmd_retrieve_supported_generic_status_indicators(context->rfcomm_cid);
295             context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS;
296             context->list_generic_status_indicators = 0;
297             context->retrieve_generic_status_indicators = 1;
298             context->retrieve_generic_status_indicators_state = 0;
299             break;
300         case HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
301             hfp_hf_cmd_list_initital_supported_generic_status_indicators(context->rfcomm_cid);
302             context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
303             context->list_generic_status_indicators = 0;
304             context->retrieve_generic_status_indicators = 0;
305             context->retrieve_generic_status_indicators_state = 1;
306             break;
307         default:
308             break;
309     }
310     return done;
311 }
312 
313 static void hfp_hf_handle_ok_service_level_connection_establishment(hfp_connection_t *context){
314     if (context->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return;
315     switch (context->state){
316         case HFP_W4_EXCHANGE_SUPPORTED_FEATURES:
317             if (has_codec_negotiation_feature(context)){
318                 context->state = HFP_NOTIFY_ON_CODECS;
319                 break;
320             }
321             context->state = HFP_RETRIEVE_INDICATORS;
322             break;
323 
324         case HFP_W4_NOTIFY_ON_CODECS:
325             context->state = HFP_RETRIEVE_INDICATORS;
326             break;
327 
328         case HFP_W4_RETRIEVE_INDICATORS:
329             context->state = HFP_RETRIEVE_INDICATORS_STATUS;
330             context->retrieve_ag_indicators = 0;
331             break;
332 
333         case HFP_W4_RETRIEVE_INDICATORS_STATUS:
334             context->state = HFP_ENABLE_INDICATORS_STATUS_UPDATE;
335             context->retrieve_ag_indicators_status = 0;
336             break;
337 
338         case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE:
339             if (has_call_waiting_and_3way_calling_feature(context)){
340                 context->state = HFP_RETRIEVE_CAN_HOLD_CALL;
341                 break;
342             }
343             if (has_hf_indicators_feature(context)){
344                 context->state = HFP_LIST_GENERIC_STATUS_INDICATORS;
345                 break;
346             }
347             context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
348             hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
349             break;
350 
351         case HFP_W4_RETRIEVE_CAN_HOLD_CALL:
352             if (has_hf_indicators_feature(context)){
353                 context->state = HFP_LIST_GENERIC_STATUS_INDICATORS;
354                 break;
355             }
356             context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
357             hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
358            break;
359 
360         case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
361             context->state = HFP_RETRIEVE_GENERIC_STATUS_INDICATORS;
362             context->retrieve_generic_status_indicators = 0;
363             break;
364 
365         case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
366             context->state = HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
367             context->retrieve_generic_status_indicators = 0;
368             break;
369 
370         case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
371             context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
372             context->retrieve_generic_status_indicators_state = 0;
373             hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
374             break;
375         default:
376             break;
377     }
378 }
379 
380 static void hfp_hf_run_for_context_service_level_connection_queries(hfp_connection_t * context){
381     if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return;
382     if (context->wait_ok) return;
383 
384     if (context->enable_status_update_for_ag_indicators != 0xFF){
385         hfp_hf_cmd_activate_status_update_for_all_ag_indicators(context->rfcomm_cid, context->enable_status_update_for_ag_indicators);
386         context->wait_ok = 1;
387         return;
388     };
389     if (context->change_status_update_for_individual_ag_indicators){
390         hfp_hf_cmd_activate_status_update_for_ag_indicator(context->rfcomm_cid,
391                 context->ag_indicators_status_update_bitmap,
392                 context->ag_indicators_nr);
393         context->wait_ok = 1;
394         return;
395     }
396 
397     if (context->operator_name_format){
398         hfp_hf_cmd_query_operator_name_format(context->rfcomm_cid);
399         context->wait_ok = 1;
400         return;
401     }
402     if (context->operator_name){
403         hfp_hf_cmd_query_operator_name(context->rfcomm_cid);
404         context->wait_ok = 1;
405         return;
406     }
407 
408     if (context->enable_extended_audio_gateway_error_report){
409         hfp_hf_cmd_enable_extended_audio_gateway_error_report(context->rfcomm_cid, context->enable_extended_audio_gateway_error_report);
410         context->wait_ok = 1;
411         return;
412     }
413 }
414 
415 static void hfp_hf_handle_ok_service_level_connection_queries(hfp_connection_t * context){
416     if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return;
417 
418     if (context->enable_status_update_for_ag_indicators != 0xFF){
419         context->enable_status_update_for_ag_indicators = 0xFF;
420         hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
421         return;
422     };
423 
424     if (context->change_status_update_for_individual_ag_indicators == 1){
425         context->change_status_update_for_individual_ag_indicators = 0;
426         hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
427         return;
428     }
429 
430     if (context->operator_name_format){
431         context->operator_name_format = 0;
432         context->operator_name = 1;
433         return;
434     }
435 
436     if (context->operator_name){
437         context->operator_name = 0;
438         hfp_emit_network_operator_event(hfp_callback, 0, context->network_operator);
439         return;
440     }
441     if (context->enable_extended_audio_gateway_error_report){
442         context->enable_extended_audio_gateway_error_report = 0;
443         return;
444     }
445 }
446 
447 
448 static void hfp_hf_run_for_context_codecs_connection(hfp_connection_t * context){
449     // if (context->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED && context->state <= HFP_AUDIO_CONNECTION_ESTABLISHED){
450 
451     // handle audio connection setup
452     // printf("hfp_run_for_context state %d \n", context->state);
453     if (context->wait_ok) return;
454 
455     switch (context->state){
456         case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
457             if (context->notify_ag_on_new_codecs){
458                 context->wait_ok = 1;
459                 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid);
460                 break;
461             }
462 
463             if (context->hf_trigger_codec_connection_setup){
464                 context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC;
465                 context->wait_ok = 1;
466                 hfp_hf_cmd_trigger_codec_connection_setup(context->rfcomm_cid);
467                 break;
468             }
469 
470             if (context->suggested_codec){
471                 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC;
472                 context->codec_confirmed = 1;
473                 context->wait_ok = 1;
474                 hfp_hf_cmd_confirm_codec(context->rfcomm_cid, context->suggested_codec);
475                 break;
476             }
477             break;
478 
479         case HFP_SLE_W4_EXCHANGE_COMMON_CODEC:
480             if (context->notify_ag_on_new_codecs){
481                 context->wait_ok = 1;
482                 context->codec_confirmed = 0;
483                 context->suggested_codec = 0;
484                 context->negotiated_codec = 0;
485                 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid);
486                 break;
487             }
488             if (context->suggested_codec){
489                 if (hfp_hf_supports_codec(context->suggested_codec)){
490                     context->codec_confirmed = context->suggested_codec;
491                     context->wait_ok = 1;
492                     hfp_hf_cmd_confirm_codec(context->rfcomm_cid, context->suggested_codec);
493                 } else {
494                     context->notify_ag_on_new_codecs = 1;
495                     context->wait_ok = 1;
496                     context->codec_confirmed = 0;
497                     context->suggested_codec = 0;
498                     context->negotiated_codec = 0;
499                     hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid);
500                 }
501 
502                 break;
503             }
504 
505             break;
506 
507         case HFP_CODECS_CONNECTION_ESTABLISHED:
508             if (context->notify_ag_on_new_codecs){
509                 context->negotiated_codec = 0;
510                 context->wait_ok = 1;
511                 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC;
512                 hfp_hf_cmd_notify_on_codecs(context->rfcomm_cid);
513                 break;
514             }
515 
516             if (context->hf_trigger_codec_connection_setup){
517                 context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC;
518                 context->wait_ok = 1;
519                 hfp_hf_cmd_trigger_codec_connection_setup(context->rfcomm_cid);
520                 break;
521             }
522 
523             if (context->establish_audio_connection){
524                 // TODO AUDIO CONNECTION
525             }
526             break;
527        default:
528             break;
529     }
530 }
531 
532 static void hfp_hf_handle_ok_codecs_connection(hfp_connection_t * context){
533         // handle audio connection setup
534     switch (context->state){
535         case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
536             if (context->notify_ag_on_new_codecs){
537                 context->notify_ag_on_new_codecs = 0;
538                 break;
539             }
540         case HFP_SLE_W2_EXCHANGE_COMMON_CODEC:
541             if (context->hf_trigger_codec_connection_setup){
542                 context->hf_trigger_codec_connection_setup = 0;
543                 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC;
544                 break;
545             }
546             break;
547         case HFP_SLE_W4_EXCHANGE_COMMON_CODEC:
548             if (context->notify_ag_on_new_codecs){
549                 context->codec_confirmed = 0;
550                 context->suggested_codec = 0;
551                 context->notify_ag_on_new_codecs = 0;
552                 break;
553             }
554             if (context->codec_confirmed && context->suggested_codec){
555                 context->negotiated_codec = context->suggested_codec;
556                 context->codec_confirmed = 0;
557                 context->suggested_codec = 0;
558                 context->state = HFP_CODECS_CONNECTION_ESTABLISHED;
559                 hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0);
560                 break;
561             }
562             break;
563 
564         case HFP_AUDIO_CONNECTION_ESTABLISHED:
565             printf("HFP_AUDIO_CONNECTION_ESTABLISHED \n");
566             break;
567 
568         default:
569             break;
570     }
571 }
572 
573 static void hfp_run_for_context(hfp_connection_t * context){
574 
575     if (!context) return;
576     if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return;
577 
578     hfp_hf_run_for_context_service_level_connection(context);
579     hfp_hf_run_for_context_service_level_connection_queries(context);
580     hfp_hf_run_for_context_codecs_connection(context);
581 
582     // deal with disconnect
583     switch (context->state){
584         case HFP_W2_DISCONNECT_RFCOMM:
585             context->state = HFP_W4_RFCOMM_DISCONNECTED;
586             rfcomm_disconnect_internal(context->rfcomm_cid);
587             break;
588 
589         default:
590             break;
591     }
592 }
593 
594 static void hfp_hf_switch_on_ok(hfp_connection_t *context){
595     // printf("switch on ok\n");
596     context->wait_ok = 0;
597 
598     hfp_hf_handle_ok_service_level_connection_establishment(context);
599     hfp_hf_handle_ok_service_level_connection_queries(context);
600     hfp_hf_handle_ok_codecs_connection(context);
601 
602     // done
603     context->command = HFP_CMD_NONE;
604 }
605 
606 
607 static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
608     hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel);
609     if (!context) return;
610 
611     packet[size] = 0;
612     int pos, i;
613     //printf("\nHF received: %s", packet+2);
614     for (pos = 0; pos < size ; pos++){
615         hfp_parse(context, packet[pos]);
616 
617         // emit indicators status changed
618         for (i = 0; i < context->ag_indicators_nr; i++){
619             if (context->ag_indicators[i].status_changed) {
620                 hfp_emit_ag_indicator_event(hfp_callback, 0, context->ag_indicators[i]);
621                 context->ag_indicators[i].status_changed = 0;
622                 break;
623             }
624         }
625 
626         if (context->command == HFP_CMD_ERROR){
627             context->wait_ok = 0;
628             hfp_reset_context_flags(context);
629             hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1);
630             return;
631         }
632         if (context->command == HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR){
633             context->wait_ok = 0;
634             hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, context->extended_audio_gateway_error);
635             context->extended_audio_gateway_error = 0;
636             return;
637         }
638 
639         if (context->command != HFP_CMD_OK) continue;
640         hfp_hf_switch_on_ok(context);
641     }
642 }
643 
644 static void hfp_run(){
645     linked_list_iterator_t it;
646     linked_list_iterator_init(&it, hfp_get_connections());
647     while (linked_list_iterator_has_next(&it)){
648         hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
649         hfp_run_for_context(connection);
650     }
651 }
652 
653 static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
654     switch (packet_type){
655         case RFCOMM_DATA_PACKET:
656             hfp_handle_rfcomm_event(packet_type, channel, packet, size);
657             break;
658         case HCI_EVENT_PACKET:
659             hfp_handle_hci_event(hfp_callback, packet_type, packet, size);
660         default:
661             break;
662     }
663     hfp_run();
664 }
665 
666 void hfp_hf_set_codecs(uint8_t * codecs, int codecs_nr){
667     if (codecs_nr > HFP_MAX_NUM_CODECS){
668         log_error("hfp_hf_set_codecs: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS);
669         return;
670     }
671 
672     hfp_codecs_nr = codecs_nr;
673     int i;
674     for (i=0; i<codecs_nr; i++){
675         hfp_codecs[i] = codecs[i];
676     }
677 
678     char buffer[30];
679     int offset = join(buffer, sizeof(buffer), hfp_codecs, hfp_codecs_nr);
680     buffer[offset] = 0;
681     printf("set codecs %s\n", buffer);
682 
683     linked_list_iterator_t it;
684     linked_list_iterator_init(&it, hfp_get_connections());
685     while (linked_list_iterator_has_next(&it)){
686         hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
687         if (!connection) continue;
688         connection->notify_ag_on_new_codecs = 1;
689         hfp_run_for_context(connection);
690     }
691 }
692 
693 void hfp_hf_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint16_t * indicators, int indicators_nr, uint32_t indicators_status){
694     rfcomm_register_packet_handler(packet_handler);
695     hfp_init(rfcomm_channel_nr);
696 
697     hfp_supported_features = supported_features;
698 
699     hfp_indicators_nr = indicators_nr;
700     hfp_indicators_status = indicators_status;
701     int i;
702     for (i=0; i<indicators_nr; i++){
703         hfp_indicators[i] = indicators[i];
704     }
705 }
706 
707 void hfp_hf_establish_service_level_connection(bd_addr_t bd_addr){
708     hfp_establish_service_level_connection(bd_addr, SDP_HandsfreeAudioGateway);
709 }
710 
711 void hfp_hf_release_service_level_connection(bd_addr_t bd_addr){
712     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
713     hfp_release_service_level_connection(connection);
714     hfp_run_for_context(connection);
715 }
716 
717 void hfp_hf_enable_status_update_for_all_ag_indicators(bd_addr_t bd_addr, uint8_t enable){
718     hfp_hf_establish_service_level_connection(bd_addr);
719     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
720     if (!connection){
721         log_error("HFP HF: connection doesn't exist.");
722         return;
723     }
724     connection->enable_status_update_for_ag_indicators = enable;
725     hfp_run_for_context(connection);
726 }
727 
728 // TODO: returned ERROR - wrong format
729 void hfp_hf_enable_status_update_for_individual_ag_indicators(bd_addr_t bd_addr, uint32_t indicators_status_bitmap){
730     hfp_hf_establish_service_level_connection(bd_addr);
731     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
732     if (!connection){
733         log_error("HFP HF: connection doesn't exist.");
734         return;
735     }
736     connection->change_status_update_for_individual_ag_indicators = 1;
737     connection->ag_indicators_status_update_bitmap = indicators_status_bitmap;
738     hfp_run_for_context(connection);
739 }
740 
741 void hfp_hf_query_operator_selection(bd_addr_t bd_addr){
742     hfp_hf_establish_service_level_connection(bd_addr);
743     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
744     if (!connection){
745         log_error("HFP HF: connection doesn't exist.");
746         return;
747     }
748     connection->operator_name_format = 1;
749     hfp_run_for_context(connection);
750 }
751 
752 void hfp_hf_enable_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, uint8_t enable){
753     hfp_hf_establish_service_level_connection(bd_addr);
754     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
755     if (!connection){
756         log_error("HFP HF: connection doesn't exist.");
757         return;
758     }
759     connection->enable_extended_audio_gateway_error_report = enable;
760     hfp_run_for_context(connection);
761 }
762 
763 void hfp_hf_negotiate_codecs(bd_addr_t bd_addr){
764     hfp_hf_establish_service_level_connection(bd_addr);
765     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
766     if (!has_codec_negotiation_feature(connection)) return;
767     if (connection->remote_codecs_nr == 0) return;
768 
769     if (connection->state >= HFP_W2_DISCONNECT_SCO) return;
770 
771     if (connection->state != HFP_SLE_W2_EXCHANGE_COMMON_CODEC &&
772         connection->state != HFP_SLE_W4_EXCHANGE_COMMON_CODEC){
773         connection->hf_trigger_codec_connection_setup = 1;
774     }
775     hfp_run_for_context(connection);
776 }
777 
778 
779 void hfp_hf_establish_audio_connection(bd_addr_t bd_addr){
780     hfp_hf_establish_service_level_connection(bd_addr);
781     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
782     if (!has_codec_negotiation_feature(connection)) return;
783         connection->establish_audio_connection = 0;
784     if (connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return;
785     if (connection->state >= HFP_W2_DISCONNECT_SCO) return;
786 
787     connection->establish_audio_connection = 1;
788     if (connection->state < HFP_SLE_W4_EXCHANGE_COMMON_CODEC){
789         connection->hf_trigger_codec_connection_setup = 1;
790     }
791     hfp_run_for_context(connection);
792 }
793 
794 void hfp_hf_release_audio_connection(bd_addr_t bd_addr){
795     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
796     hfp_release_audio_connection(connection);
797     hfp_run_for_context(connection);
798 }
799 
800 
801