xref: /btstack/src/classic/hfp_ag.c (revision 3edc84c5b6b1e23a3d103fe8ce1f6b5ad1df3498)
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 
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 "classic/sdp_query_rfcomm.h"
59 #include "classic/sdp.h"
60 #include "debug.h"
61 #include "classic/hfp.h"
62 #include "classic/hfp_ag.h"
63 
64 static const char default_hfp_ag_service_name[] = "Voice gateway";
65 static uint16_t hfp_supported_features = HFP_DEFAULT_AG_SUPPORTED_FEATURES;
66 static uint8_t hfp_codecs_nr = 0;
67 static uint8_t hfp_codecs[HFP_MAX_NUM_CODECS];
68 
69 static int  hfp_ag_indicators_nr = 0;
70 static hfp_ag_indicator_t hfp_ag_indicators[HFP_MAX_NUM_AG_INDICATORS];
71 
72 static int  hfp_ag_call_hold_services_nr = 0;
73 static char *hfp_ag_call_hold_services[6];
74 static hfp_callback_t hfp_callback;
75 
76 static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
77 
78 hfp_generic_status_indicator_t * get_hfp_generic_status_indicators();
79 int get_hfp_generic_status_indicators_nr();
80 void set_hfp_generic_status_indicators(hfp_generic_status_indicator_t * indicators, int indicator_nr);
81 void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr);
82 int get_hfp_ag_indicators_nr(hfp_connection_t * context);
83 hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context);
84 
85 
86 hfp_ag_indicator_t * get_hfp_ag_indicators(hfp_connection_t * context){
87     // TODO: save only value, and value changed in the context?
88     if (context->ag_indicators_nr != hfp_ag_indicators_nr){
89         context->ag_indicators_nr = hfp_ag_indicators_nr;
90         memcpy(context->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t));
91     }
92     return (hfp_ag_indicator_t *)&(context->ag_indicators);
93 }
94 
95 void set_hfp_ag_indicators(hfp_ag_indicator_t * indicators, int indicator_nr){
96     memcpy(hfp_ag_indicators, indicators, indicator_nr * sizeof(hfp_ag_indicator_t));
97     hfp_ag_indicators_nr = indicator_nr;
98 }
99 
100 int get_hfp_ag_indicators_nr(hfp_connection_t * context){
101     if (context->ag_indicators_nr != hfp_ag_indicators_nr){
102         context->ag_indicators_nr = hfp_ag_indicators_nr;
103         memcpy(context->ag_indicators, hfp_ag_indicators, hfp_ag_indicators_nr * sizeof(hfp_ag_indicator_t));
104     }
105     return context->ag_indicators_nr;
106 }
107 
108 
109 void hfp_ag_register_packet_handler(hfp_callback_t callback){
110     if (callback == NULL){
111         log_error("hfp_ag_register_packet_handler called with NULL callback");
112         return;
113     }
114     hfp_callback = callback;
115 }
116 
117 static uint8_t hfp_get_indicator_index_by_name(hfp_connection_t * context, const char * name){
118     int i;
119     for (i=0; i<context->ag_indicators_nr; i++){
120         if (strcmp(context->ag_indicators[i].name, name) == 0){
121             return i;
122         }
123     }
124     return 0xFF;
125 }
126 
127 static void hfp_ag_update_indicator_status(hfp_connection_t * context, const char * indicator_name, uint8_t status){
128     int index = hfp_get_indicator_index_by_name(context, indicator_name);
129     if (index == 0xFF) return;
130     if (context->ag_indicators[index].status == status) return;
131     context->ag_indicators[index].status = status;
132     context->ag_indicators[index].status_changed = 1;
133 }
134 
135 static int has_codec_negotiation_feature(hfp_connection_t * connection){
136     int hf = get_bit(connection->remote_supported_features, HFP_HFSF_CODEC_NEGOTIATION);
137     int ag = get_bit(hfp_supported_features, HFP_AGSF_CODEC_NEGOTIATION);
138     return hf && ag;
139 }
140 
141 static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * connection){
142     int hf = get_bit(connection->remote_supported_features, HFP_HFSF_THREE_WAY_CALLING);
143     int ag = get_bit(hfp_supported_features, HFP_AGSF_THREE_WAY_CALLING);
144     return hf && ag;
145 }
146 
147 static int has_hf_indicators_feature(hfp_connection_t * connection){
148     int hf = get_bit(connection->remote_supported_features, HFP_HFSF_HF_INDICATORS);
149     int ag = get_bit(hfp_supported_features, HFP_AGSF_HF_INDICATORS);
150     return hf && ag;
151 }
152 
153 void hfp_ag_create_sdp_record(uint8_t * service, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features){
154     if (!name){
155         name = default_hfp_ag_service_name;
156     }
157     hfp_create_sdp_record(service, SDP_HandsfreeAudioGateway, rfcomm_channel_nr, name, supported_features);
158 
159     // Network
160     de_add_number(service, DE_UINT, DE_SIZE_8, ability_to_reject_call);
161     /*
162      * 0x01 – Ability to reject a call
163      * 0x00 – No ability to reject a call
164      */
165 }
166 
167 static int hfp_ag_exchange_supported_features_cmd(uint16_t cid){
168     char buffer[40];
169     sprintf(buffer, "\r\n%s:%d\r\n\r\nOK\r\n", HFP_SUPPORTED_FEATURES, hfp_supported_features);
170     return send_str_over_rfcomm(cid, buffer);
171 }
172 
173 static int hfp_ag_ok(uint16_t cid){
174     char buffer[10];
175     sprintf(buffer, "\r\nOK\r\n");
176     return send_str_over_rfcomm(cid, buffer);
177 }
178 
179 static int hfp_ag_error(uint16_t cid){
180     char buffer[10];
181     sprintf(buffer, "\r\nERROR\r\n");
182     return send_str_over_rfcomm(cid, buffer);
183 }
184 
185 static int hfp_ag_report_extended_audio_gateway_error(uint16_t cid, uint8_t error){
186     char buffer[20];
187     sprintf(buffer, "\r\n%s=%d\r\n", HFP_EXTENDED_AUDIO_GATEWAY_ERROR, error);
188     return send_str_over_rfcomm(cid, buffer);
189 }
190 
191 static int hfp_ag_retrieve_codec_cmd(uint16_t cid){
192     return hfp_ag_ok(cid);
193 }
194 
195 static int hfp_ag_indicators_join(char * buffer, int buffer_size, hfp_connection_t * context){
196     if (buffer_size < get_hfp_ag_indicators_nr(context) * (1 + sizeof(hfp_ag_indicator_t))) return 0;
197     int i;
198     int offset = 0;
199     for (i = 0; i < get_hfp_ag_indicators_nr(context)-1; i++) {
200         offset += snprintf(buffer+offset, buffer_size-offset, "(\"%s\",(%d,%d)),",
201             get_hfp_ag_indicators(context)[i].name,
202             get_hfp_ag_indicators(context)[i].min_range,
203             get_hfp_ag_indicators(context)[i].max_range);
204     }
205     if ( i < get_hfp_ag_indicators_nr(context)){
206         offset += snprintf(buffer+offset, buffer_size-offset, "(\"%s\",(%d,%d))",
207             get_hfp_ag_indicators(context)[i].name,
208             get_hfp_ag_indicators(context)[i].min_range,
209             get_hfp_ag_indicators(context)[i].max_range);
210     }
211     return offset;
212 }
213 
214 static int hfp_hf_indicators_join(char * buffer, int buffer_size){
215     if (buffer_size < hfp_ag_indicators_nr * 3) return 0;
216     int i;
217     int offset = 0;
218     for (i = 0; i < get_hfp_generic_status_indicators_nr()-1; i++) {
219         offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_hfp_generic_status_indicators()[i].uuid);
220     }
221     if (i < get_hfp_generic_status_indicators_nr()){
222         offset += snprintf(buffer+offset, buffer_size-offset, "%d,", get_hfp_generic_status_indicators()[i].uuid);
223     }
224     return offset;
225 }
226 
227 static int hfp_hf_indicators_initial_status_join(char * buffer, int buffer_size){
228     if (buffer_size < get_hfp_generic_status_indicators_nr() * 3) return 0;
229     int i;
230     int offset = 0;
231     for (i = 0; i < get_hfp_generic_status_indicators_nr(); i++) {
232         offset += snprintf(buffer+offset, buffer_size-offset, "\r\n%s:%d,%d\r\n", HFP_GENERIC_STATUS_INDICATOR, get_hfp_generic_status_indicators()[i].uuid, get_hfp_generic_status_indicators()[i].state);
233     }
234     return offset;
235 }
236 
237 static int hfp_ag_indicators_status_join(char * buffer, int buffer_size){
238     if (buffer_size < hfp_ag_indicators_nr * 3) return 0;
239     int i;
240     int offset = 0;
241     for (i = 0; i < hfp_ag_indicators_nr-1; i++) {
242         offset += snprintf(buffer+offset, buffer_size-offset, "%d,", hfp_ag_indicators[i].status);
243     }
244     if (i<hfp_ag_indicators_nr){
245         offset += snprintf(buffer+offset, buffer_size-offset, "%d", hfp_ag_indicators[i].status);
246     }
247     return offset;
248 }
249 
250 static int hfp_ag_call_services_join(char * buffer, int buffer_size){
251     if (buffer_size < hfp_ag_call_hold_services_nr * 3) return 0;
252     int i;
253     int offset = snprintf(buffer, buffer_size, "(");
254     for (i = 0; i < hfp_ag_call_hold_services_nr-1; i++) {
255         offset += snprintf(buffer+offset, buffer_size-offset, "%s,", hfp_ag_call_hold_services[i]);
256     }
257     if (i<hfp_ag_call_hold_services_nr){
258         offset += snprintf(buffer+offset, buffer_size-offset, "%s)", hfp_ag_call_hold_services[i]);
259     }
260     return offset;
261 }
262 
263 static int hfp_ag_retrieve_indicators_cmd(uint16_t cid, hfp_connection_t * context){
264     char buffer[250];
265     int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_INDICATOR);
266     offset += hfp_ag_indicators_join(buffer+offset, sizeof(buffer)-offset, context);
267 
268     buffer[offset] = 0;
269 
270     offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n");
271     buffer[offset] = 0;
272     return send_str_over_rfcomm(cid, buffer);
273 }
274 
275 static int hfp_ag_retrieve_indicators_status_cmd(uint16_t cid){
276     char buffer[40];
277     int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_INDICATOR);
278     offset += hfp_ag_indicators_status_join(buffer+offset, sizeof(buffer)-offset);
279 
280     buffer[offset] = 0;
281 
282     offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n");
283     buffer[offset] = 0;
284     return send_str_over_rfcomm(cid, buffer);
285 }
286 
287 static int hfp_ag_set_indicator_status_update_cmd(uint16_t cid, uint8_t activate){
288     // AT\r\n%s:3,0,0,%d\r\n
289     return hfp_ag_ok(cid);
290 }
291 
292 
293 static int hfp_ag_retrieve_can_hold_call_cmd(uint16_t cid){
294     char buffer[100];
295     int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES);
296     offset += hfp_ag_call_services_join(buffer+offset, sizeof(buffer)-offset);
297 
298     buffer[offset] = 0;
299 
300     offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n");
301     buffer[offset] = 0;
302     return send_str_over_rfcomm(cid, buffer);
303 }
304 
305 
306 static int hfp_ag_list_supported_generic_status_indicators_cmd(uint16_t cid){
307     return hfp_ag_ok(cid);
308 }
309 
310 static int hfp_ag_retrieve_supported_generic_status_indicators_cmd(uint16_t cid){
311     char buffer[40];
312     int offset = snprintf(buffer, sizeof(buffer), "\r\n%s:", HFP_GENERIC_STATUS_INDICATOR);
313     offset += hfp_hf_indicators_join(buffer+offset, sizeof(buffer)-offset);
314 
315     buffer[offset] = 0;
316 
317     offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\n\r\nOK\r\n");
318     buffer[offset] = 0;
319     return send_str_over_rfcomm(cid, buffer);
320 }
321 
322 static int hfp_ag_retrieve_initital_supported_generic_status_indicators_cmd(uint16_t cid){
323     char buffer[40];
324     int offset = hfp_hf_indicators_initial_status_join(buffer, sizeof(buffer));
325 
326     buffer[offset] = 0;
327     offset += snprintf(buffer+offset, sizeof(buffer)-offset, "\r\nOK\r\n");
328     buffer[offset] = 0;
329     return send_str_over_rfcomm(cid, buffer);
330 }
331 
332 static int hfp_ag_transfer_ag_indicators_status_cmd(uint16_t cid, hfp_ag_indicator_t indicator){
333     char buffer[20];
334     sprintf(buffer, "\r\n%s:%d,%d\r\n\r\nOK\r\n", HFP_TRANSFER_AG_INDICATOR_STATUS, indicator.index, indicator.status);
335     return send_str_over_rfcomm(cid, buffer);
336 }
337 
338 static int hfp_ag_report_network_operator_name_cmd(uint16_t cid, hfp_network_opearator_t op){
339     char buffer[40];
340     if (strlen(op.name) == 0){
341         sprintf(buffer, "\r\n%s:%d,,\r\n\r\nOK\r\n", HFP_QUERY_OPERATOR_SELECTION, op.mode);
342     } else {
343         sprintf(buffer, "\r\n%s:%d,%d,%s\r\n\r\nOK\r\n", HFP_QUERY_OPERATOR_SELECTION, op.mode, op.format, op.name);
344     }
345     return send_str_over_rfcomm(cid, buffer);
346 }
347 
348 
349 static int hfp_ag_cmd_suggest_codec(uint16_t cid, uint8_t codec){
350     char buffer[30];
351     sprintf(buffer, "\r\n%s:%d\r\n", HFP_CONFIRM_COMMON_CODEC, codec);
352     return send_str_over_rfcomm(cid, buffer);
353 }
354 
355 static uint8_t hfp_ag_suggest_codec(hfp_connection_t *context){
356     int i,j;
357     uint8_t codec = 0;
358     for (i = 0; i < hfp_codecs_nr; i++){
359         for (j = 0; j < context->remote_codecs_nr; j++){
360             if (context->remote_codecs[j] == hfp_codecs[i]){
361                 codec = context->remote_codecs[j];
362                 continue;
363             }
364         }
365     }
366     return codec;
367 }
368 
369 
370 static int hfp_ag_run_for_context_service_level_connection(hfp_connection_t * context){
371     if (context->state >= HFP_CODECS_CONNECTION_ESTABLISHED) return 0;
372     //printf(" AG run for context_service_level_connection \n");
373     int done = 0;
374 
375     switch(context->command){
376         case HFP_CMD_SUPPORTED_FEATURES:
377             switch(context->state){
378                 case HFP_W4_EXCHANGE_SUPPORTED_FEATURES:
379                     hfp_ag_exchange_supported_features_cmd(context->rfcomm_cid);
380                     done = 1;
381                     if (has_codec_negotiation_feature(context)){
382                         context->state = HFP_W4_NOTIFY_ON_CODECS;
383                         break;
384                     }
385                     context->state = HFP_W4_RETRIEVE_INDICATORS;
386                     break;
387                 default:
388                     break;
389             }
390             break;
391         case HFP_CMD_AVAILABLE_CODECS:
392             switch(context->state){
393                 case HFP_W4_NOTIFY_ON_CODECS:
394                     hfp_ag_retrieve_codec_cmd(context->rfcomm_cid);
395                     done = 1;
396                     context->state = HFP_W4_RETRIEVE_INDICATORS;
397                     break;
398                 case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
399                     context->suggested_codec = hfp_ag_suggest_codec(context);
400                     //printf("received BAC == new HF codecs, suggested codec %d\n", context->suggested_codec);
401                     hfp_ag_ok(context->rfcomm_cid);
402                     done = 1;
403                     break;
404 
405                 default:
406                     break;
407             }
408             break;
409         case HFP_CMD_INDICATOR:
410             switch(context->state){
411                 case HFP_W4_RETRIEVE_INDICATORS:
412                     if (context->retrieve_ag_indicators == 0) break;
413                     hfp_ag_retrieve_indicators_cmd(context->rfcomm_cid, context);
414                     done = 1;
415                     context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS;
416                     break;
417                 case HFP_W4_RETRIEVE_INDICATORS_STATUS:
418                     if (context->retrieve_ag_indicators_status == 0) break;
419                     hfp_ag_retrieve_indicators_status_cmd(context->rfcomm_cid);
420                     done = 1;
421                     context->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE;
422                     break;
423                 default:
424                     break;
425             }
426             break;
427         case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
428             switch(context->state){
429                 case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE:
430                     hfp_ag_set_indicator_status_update_cmd(context->rfcomm_cid, 1);
431                     done = 1;
432                     if (has_call_waiting_and_3way_calling_feature(context)){
433                         context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL;
434                         break;
435                     }
436                     if (has_hf_indicators_feature(context)){
437                         context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
438                         break;
439                     }
440                     context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
441                     hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
442                     break;
443                 default:
444                     break;
445             }
446             break;
447         case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
448             switch(context->state){
449                 case HFP_W4_RETRIEVE_CAN_HOLD_CALL:
450                     hfp_ag_retrieve_can_hold_call_cmd(context->rfcomm_cid);
451                     done = 1;
452                     if (has_hf_indicators_feature(context)){
453                         context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
454                         break;
455                     }
456                     context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
457                     hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
458                     break;
459                 default:
460                     break;
461             }
462             break;
463         case HFP_CMD_GENERIC_STATUS_INDICATOR:
464             switch(context->state){
465                 case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
466                     if (context->list_generic_status_indicators == 0) break;
467                     hfp_ag_list_supported_generic_status_indicators_cmd(context->rfcomm_cid);
468                     done = 1;
469                     context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS;
470                     context->list_generic_status_indicators = 0;
471                     break;
472                 case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
473                     if (context->retrieve_generic_status_indicators == 0) break;
474                     hfp_ag_retrieve_supported_generic_status_indicators_cmd(context->rfcomm_cid);
475                     done = 1;
476                     context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
477                     context->retrieve_generic_status_indicators = 0;
478                     break;
479                 case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
480                     if (context->retrieve_generic_status_indicators_state == 0) break;
481                     hfp_ag_retrieve_initital_supported_generic_status_indicators_cmd(context->rfcomm_cid);
482                     done = 1;
483                     context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
484                     context->retrieve_generic_status_indicators_state = 0;
485                     hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
486                     break;
487                 default:
488                     break;
489             }
490             break;
491 
492         default:
493             break;
494     }
495     return done;
496 }
497 
498 static int hfp_ag_run_for_context_service_level_connection_queries(hfp_connection_t * context){
499     if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0;
500     int done = 0;
501     //printf("    SLC queries: ");
502 
503     switch(context->command){
504         case HFP_CMD_AVAILABLE_CODECS:
505             context->suggested_codec = hfp_ag_suggest_codec(context);
506             //printf("received BAC == new HF codecs, suggested codec %d\n", context->suggested_codec);
507             hfp_ag_ok(context->rfcomm_cid);
508             done = 1;
509             break;
510 
511         case HFP_CMD_QUERY_OPERATOR_SELECTION:
512             if (context->operator_name_format == 1){
513                 if (context->network_operator.format != 0){
514                     hfp_ag_error(context->rfcomm_cid);
515                     done = 1;
516                     break;
517                 }
518                 hfp_ag_ok(context->rfcomm_cid);
519                 done = 1;
520                 context->operator_name_format = 0;
521                 break;
522             }
523             if (context->operator_name == 1){
524                 hfp_ag_report_network_operator_name_cmd(context->rfcomm_cid, context->network_operator);
525                 context->operator_name = 0;
526                 done = 1;
527                 break;
528             }
529             break;
530         case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:{
531                 int i;
532                 for (i = 0; i < context->ag_indicators_nr; i++){
533                     if (context->ag_indicators[i].enabled == 0) continue;
534                     if (context->ag_indicators[i].status_changed == 0) continue;
535                     hfp_ag_transfer_ag_indicators_status_cmd(context->rfcomm_cid, context->ag_indicators[i]);
536                     done = 1;
537                     context->ag_indicators[i].status_changed = 0;
538                     return done;
539                 }
540                 break;
541             }
542         case HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP:
543             if (context->hf_trigger_codec_connection_setup){ // received BCC
544                 //printf(" received BCC \n");
545                 context->hf_trigger_codec_connection_setup = 0;
546                 context->ag_trigger_codec_connection_setup = 1;
547                 context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC;
548                 hfp_ag_ok(context->rfcomm_cid);
549                 done = 1;
550                 return done;
551             }
552 
553             if (context->ag_trigger_codec_connection_setup){ // received BCS
554                 //printf(" send BCS \n");
555                 context->ag_trigger_codec_connection_setup = 0;
556                 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC;
557                 context->suggested_codec = hfp_ag_suggest_codec(context);
558                 hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->suggested_codec);
559                 done = 1;
560                 return done;
561             }
562             break;
563         case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR:
564             if (context->extended_audio_gateway_error){
565                 hfp_ag_report_extended_audio_gateway_error(context->rfcomm_cid, context->extended_audio_gateway_error);
566                 context->extended_audio_gateway_error = 0;
567                 done = 1;
568                 break;
569             }
570         case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
571             printf("TODO\n");
572             break;
573         default:
574             break;
575     }
576     return done;
577 }
578 
579 
580 static int hfp_ag_run_for_context_codecs_connection(hfp_connection_t * context){
581     if (context->state <= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED ||
582         context->state > HFP_CODECS_CONNECTION_ESTABLISHED) return 0;
583 
584     int done = 0;
585     //printf(" AG run for context_codecs_connection: ");
586     switch (context->state){
587         case HFP_SLE_W2_EXCHANGE_COMMON_CODEC:
588             if (context->ag_trigger_codec_connection_setup){ // received BCS
589                 //printf(" send BCS \n");
590                 context->ag_trigger_codec_connection_setup = 0;
591                 context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC;
592                 context->suggested_codec = hfp_ag_suggest_codec(context);
593                 hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->suggested_codec);
594                 done = 1;
595                 break;
596             }
597             break;
598         case HFP_SLE_W4_EXCHANGE_COMMON_CODEC:
599             switch(context->command){
600                 case HFP_CMD_AVAILABLE_CODECS:
601                     if (context->notify_ag_on_new_codecs){ // received BAC
602                         //printf(" received BAC\n");
603                         context->notify_ag_on_new_codecs = 0;
604                         if (context->suggested_codec != hfp_ag_suggest_codec(context)){
605                             context->suggested_codec = hfp_ag_suggest_codec(context);
606                             context->state = HFP_SLE_W2_EXCHANGE_COMMON_CODEC;
607                             context->ag_trigger_codec_connection_setup = 1;
608                         }
609                         hfp_ag_ok(context->rfcomm_cid);
610                         done = 1;
611                         break;
612                     }
613                     break;
614                 case HFP_CMD_HF_CONFIRMED_CODEC:
615                     //printf(" received AT+BCS\n");
616                     if (context->codec_confirmed != context->suggested_codec){
617                         context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
618                         hfp_ag_error(context->rfcomm_cid);
619                         done = 1;
620                         break;
621                     }
622                     context->negotiated_codec = context->codec_confirmed;
623                     context->state = HFP_CODECS_CONNECTION_ESTABLISHED;
624                     hfp_emit_event(hfp_callback, HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE, 0);
625                     hfp_ag_ok(context->rfcomm_cid);
626                     done = 1;
627                     break;
628                 default:
629                     break;
630             }
631             break;
632 
633         case HFP_CODECS_CONNECTION_ESTABLISHED:
634             switch(context->command){
635                 case HFP_CMD_AVAILABLE_CODECS:
636 
637                     if (context->notify_ag_on_new_codecs){ // received BAC
638                         context->notify_ag_on_new_codecs = 0;
639                         if (context->suggested_codec != hfp_ag_suggest_codec(context)){
640                             context->suggested_codec = hfp_ag_suggest_codec(context);
641                             context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC;
642                         }
643                         hfp_ag_ok(context->rfcomm_cid);
644                         done = 1;
645                         break;
646                     }
647                     break;
648                 case HFP_CMD_AG_SUGGESTED_CODEC:
649                     if (context->ag_trigger_codec_connection_setup){
650                         context->ag_trigger_codec_connection_setup = 0;
651                         if (context->negotiated_codec != hfp_ag_suggest_codec(context)){
652                             context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC;
653                             context->suggested_codec = hfp_ag_suggest_codec(context);
654                             hfp_ag_cmd_suggest_codec(context->rfcomm_cid, context->suggested_codec);
655                             done = 1;
656                             break;
657                         }
658                     }
659                     break;
660                 default:
661                     break;
662             }
663 
664         default:
665             break;
666     }
667     return done;
668 }
669 
670 static void hfp_run_for_context(hfp_connection_t *context){
671     if (!context) return;
672 
673     if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return;
674 
675     // printf("AG hfp_run_for_context 1 state %d, command %d\n", context->state, context->command);
676     if (context->send_ok){
677         hfp_ag_ok(context->rfcomm_cid);
678         context->send_ok = 0;
679         context->command = HFP_CMD_NONE;
680         return;
681     }
682 
683     if (context->send_error){
684         hfp_ag_error(context->rfcomm_cid);
685         context->send_error = 0;
686         context->command = HFP_CMD_NONE;
687         return;
688     }
689 
690     int done = hfp_ag_run_for_context_service_level_connection(context);
691 
692     if (rfcomm_can_send_packet_now(context->rfcomm_cid) && !done){
693         done = hfp_ag_run_for_context_service_level_connection_queries(context);
694         if (rfcomm_can_send_packet_now(context->rfcomm_cid) && !done){
695             done = hfp_ag_run_for_context_codecs_connection(context);
696         }
697     }
698 
699 
700     if (context->command == HFP_CMD_NONE && !done){
701         switch(context->state){
702             case HFP_W2_DISCONNECT_RFCOMM:
703                 context->state = HFP_W4_RFCOMM_DISCONNECTED;
704                 rfcomm_disconnect_internal(context->rfcomm_cid);
705                 break;
706             default:
707                 break;
708         }
709     }
710     if (done){
711         context->command = HFP_CMD_NONE;
712     }
713 }
714 
715 static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
716     hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel);
717     if (!context) return;
718 
719     if (context->state == HFP_EXCHANGE_SUPPORTED_FEATURES){
720         context->state = HFP_W4_EXCHANGE_SUPPORTED_FEATURES;
721     }
722 
723     packet[size] = 0;
724     int pos;
725     for (pos = 0; pos < size ; pos++){
726         hfp_parse(context, packet[pos]);
727 
728         // trigger next action after CMD received
729         if (context->command == HFP_CMD_NONE) continue;
730         //hfp_run_for_context(context);
731     }
732 }
733 
734 static void hfp_run(){
735     linked_list_iterator_t it;
736     linked_list_iterator_init(&it, hfp_get_connections());
737     while (linked_list_iterator_has_next(&it)){
738         hfp_connection_t * connection = (hfp_connection_t *)linked_list_iterator_next(&it);
739         hfp_run_for_context(connection);
740     }
741 }
742 
743 static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
744     switch (packet_type){
745         case RFCOMM_DATA_PACKET:
746             hfp_handle_rfcomm_event(packet_type, channel, packet, size);
747             break;
748         case HCI_EVENT_PACKET:
749             hfp_handle_hci_event(hfp_callback, packet_type, packet, size);
750             return;
751         default:
752             break;
753     }
754 
755     hfp_run();
756 }
757 
758 void hfp_ag_init(uint16_t rfcomm_channel_nr, uint32_t supported_features,
759     uint8_t * codecs, int codecs_nr,
760     hfp_ag_indicator_t * ag_indicators, int ag_indicators_nr,
761     hfp_generic_status_indicator_t * hf_indicators, int hf_indicators_nr,
762     const char *call_hold_services[], int call_hold_services_nr){
763     if (codecs_nr > HFP_MAX_NUM_CODECS){
764         log_error("hfp_init: codecs_nr (%d) > HFP_MAX_NUM_CODECS (%d)", codecs_nr, HFP_MAX_NUM_CODECS);
765         return;
766     }
767     rfcomm_register_packet_handler(packet_handler);
768     hfp_init(rfcomm_channel_nr);
769 
770     hfp_supported_features = supported_features;
771     hfp_codecs_nr = codecs_nr;
772 
773     int i;
774     for (i=0; i<codecs_nr; i++){
775         hfp_codecs[i] = codecs[i];
776     }
777 
778     hfp_ag_indicators_nr = ag_indicators_nr;
779     memcpy(hfp_ag_indicators, ag_indicators, ag_indicators_nr * sizeof(hfp_ag_indicator_t));
780     for (i=0; i<hfp_ag_indicators_nr; i++){
781         printf("ag ind %s\n", hfp_ag_indicators[i].name);
782     }
783 
784     set_hfp_generic_status_indicators(hf_indicators, hf_indicators_nr);
785 
786     hfp_ag_call_hold_services_nr = call_hold_services_nr;
787     memcpy(hfp_ag_call_hold_services, call_hold_services, call_hold_services_nr * sizeof(char *));
788 }
789 
790 void hfp_ag_establish_service_level_connection(bd_addr_t bd_addr){
791     hfp_establish_service_level_connection(bd_addr, SDP_Handsfree);
792 }
793 
794 void hfp_ag_release_service_level_connection(bd_addr_t bd_addr){
795     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
796     hfp_release_service_level_connection(connection);
797     hfp_run_for_context(connection);
798 }
799 
800 void hfp_ag_report_extended_audio_gateway_error_result_code(bd_addr_t bd_addr, hfp_cme_error_t error){
801     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
802     if (!connection){
803         log_error("HFP HF: connection doesn't exist.");
804         return;
805     }
806     connection->extended_audio_gateway_error = 0;
807     if (!connection->enable_extended_audio_gateway_error_report){
808         return;
809     }
810     connection->extended_audio_gateway_error = error;
811     hfp_run_for_context(connection);
812 }
813 
814 void hfp_ag_transfer_call_status(bd_addr_t bd_addr, hfp_call_status_t status){
815     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
816     if (!connection){
817         log_error("HFP HF: connection doesn't exist.");
818         return;
819     }
820     if (!connection->enable_status_update_for_ag_indicators) return;
821     hfp_ag_update_indicator_status(connection, (char *)"call", status);
822 }
823 
824 void hfp_ag_transfer_callsetup_status(bd_addr_t bd_addr, hfp_callsetup_status_t status){
825     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
826     if (!connection){
827         log_error("HFP HF: connection doesn't exist.");
828         return;
829     }
830     if (!connection->enable_status_update_for_ag_indicators) return;
831     hfp_ag_update_indicator_status(connection, (char *)"callsetup", status);
832 }
833 
834 void hfp_ag_transfer_callheld_status(bd_addr_t bd_addr, hfp_callheld_status_t status){
835     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
836     if (!connection){
837         log_error("HFP AG: connection doesn't exist.");
838         return;
839     }
840     if (!connection->enable_status_update_for_ag_indicators) return;
841     hfp_ag_update_indicator_status(connection, (char *)"callheld", status);
842     hfp_run_for_context(connection);
843 }
844 
845 #if 0
846 static void hfp_ag_codec_connection_setup(hfp_connection_t * connection){
847     if (!connection){
848         log_error("HFP AG: connection doesn't exist.");
849         return;
850     }
851     // TODO:
852     hfp_run_for_context(connection);
853 }
854 #endif
855 
856 /**
857  * @param handle
858  * @param transmit_bandwidth 8000(64kbps)
859  * @param receive_bandwidth  8000(64kbps)
860  * @param max_latency        >= 7ms for eSCO, 0xFFFF do not care
861  * @param voice_settings     e.g. CVSD, Input Coding: Linear, Input Data Format: 2’s complement, data 16bit: 00011000000 == 0x60
862  * @param retransmission_effort  e.g. 0xFF do not care
863  * @param packet_type        at least EV3 for eSCO
864 
865  hci_send_cmd(&hci_setup_synchronous_connection, rfcomm_handle, 8000, 8000, 0xFFFF, 0x0060, 0xFF, 0x003F);
866 
867  */
868 
869 #if 0
870 static void hfp_ag_negotiate_codecs(bd_addr_t bd_addr){
871     hfp_ag_establish_service_level_connection(bd_addr);
872     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
873     if (!has_codec_negotiation_feature(connection)) return;
874     if (connection->remote_codecs_nr == 0) return;
875 
876     if (connection->state >= HFP_W2_DISCONNECT_SCO) return;
877 
878     if (connection->state != HFP_SLE_W2_EXCHANGE_COMMON_CODEC &&
879         connection->state != HFP_SLE_W4_EXCHANGE_COMMON_CODEC){
880         connection->ag_trigger_codec_connection_setup = 1;
881     }
882 
883     hfp_run_for_context(connection);
884 }
885 #endif
886 
887 void hfp_ag_establish_audio_connection(bd_addr_t bd_addr){
888     hfp_ag_establish_service_level_connection(bd_addr);
889     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
890     if (!has_codec_negotiation_feature(connection)) return;
891     connection->establish_audio_connection = 0;
892     if (connection->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return;
893     if (connection->state >= HFP_W2_DISCONNECT_SCO) return;
894 
895     connection->establish_audio_connection = 1;
896     if (connection->state < HFP_SLE_W4_EXCHANGE_COMMON_CODEC){
897         connection->ag_trigger_codec_connection_setup = 1;
898     }
899     hfp_run_for_context(connection);
900 }
901 
902 void hfp_ag_release_audio_connection(bd_addr_t bd_addr){
903     hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr);
904     hfp_release_audio_connection(connection);
905     hfp_run_for_context(connection);
906 }
907