OSDN Git Service

[automerger skipped] [automerger] Decrease length after reading from array in process...
[android-x86/system-bt.git] / bta / ag / bta_ag_cmd.cc
1 /******************************************************************************
2  *
3  *  Copyright (C) 2004-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18
19 #define LOG_TAG "bta_ag_cmd"
20
21 #include <ctype.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "bt_common.h"
26 #include "bt_target.h"
27 #include "bt_types.h"
28 #include "bta_ag_api.h"
29 #include "bta_ag_at.h"
30 #include "bta_ag_int.h"
31 #include "bta_api.h"
32 #include "bta_sys.h"
33 #include "osi/include/log.h"
34 #include "osi/include/osi.h"
35 #include "port_api.h"
36 #include "utl.h"
37
38 /*****************************************************************************
39  *  Constants
40  ****************************************************************************/
41
42 /* Ring timeout */
43 #define BTA_AG_RING_TIMEOUT_MS (5 * 1000) /* 5 seconds */
44
45 #define BTA_AG_CMD_MAX_VAL 32767 /* Maximum value is signed 16-bit value */
46
47 /* Invalid Chld command */
48 #define BTA_AG_INVALID_CHLD 255
49
50 /* clip type constants */
51 #define BTA_AG_CLIP_TYPE_MIN 128
52 #define BTA_AG_CLIP_TYPE_MAX 175
53 #define BTA_AG_CLIP_TYPE_DEFAULT 129
54 #define BTA_AG_CLIP_TYPE_VOIP 255
55
56 #define COLON_IDX_4_VGSVGM 4
57
58 /* Local events which will not trigger a higher layer callback */
59 enum {
60   BTA_AG_LOCAL_EVT_FIRST = 0x100,
61   BTA_AG_LOCAL_EVT_CCWA,
62   BTA_AG_LOCAL_EVT_CLIP,
63   BTA_AG_LOCAL_EVT_CMER,
64   BTA_AG_LOCAL_EVT_BRSF,
65   BTA_AG_LOCAL_EVT_CMEE,
66   BTA_AG_LOCAL_EVT_BIA,
67   BTA_AG_LOCAL_EVT_BCC,
68 };
69
70 /* AT command interpreter table for HSP */
71 const tBTA_AG_AT_CMD bta_ag_hsp_cmd[] = {
72     {"+CKPD", BTA_AG_AT_CKPD_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 200, 200},
73     {"+VGS", BTA_AG_SPK_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 15},
74     {"+VGM", BTA_AG_MIC_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 15},
75     /* End-of-table marker used to stop lookup iteration */
76     {"", 0, 0, 0, 0, 0}};
77
78 /* AT command interpreter table for HFP */
79 const tBTA_AG_AT_CMD bta_ag_hfp_cmd[] = {
80     {"A", BTA_AG_AT_A_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
81     {"D", BTA_AG_AT_D_EVT, BTA_AG_AT_NONE | BTA_AG_AT_FREE, BTA_AG_AT_STR, 0,
82      0},
83     {"+VGS", BTA_AG_SPK_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 15},
84     {"+VGM", BTA_AG_MIC_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 15},
85     {"+CCWA", BTA_AG_LOCAL_EVT_CCWA, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 1},
86     /* Consider CHLD as str to take care of indexes for ECC */
87     {"+CHLD", BTA_AG_AT_CHLD_EVT, BTA_AG_AT_SET | BTA_AG_AT_TEST, BTA_AG_AT_STR,
88      0, 4},
89     {"+CHUP", BTA_AG_AT_CHUP_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
90     {"+CIND", BTA_AG_AT_CIND_EVT, BTA_AG_AT_READ | BTA_AG_AT_TEST,
91      BTA_AG_AT_STR, 0, 0},
92     {"+CLIP", BTA_AG_LOCAL_EVT_CLIP, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 1},
93     {"+CMER", BTA_AG_LOCAL_EVT_CMER, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
94     {"+VTS", BTA_AG_AT_VTS_EVT, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
95     {"+BINP", BTA_AG_AT_BINP_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 1, 1},
96     {"+BLDN", BTA_AG_AT_BLDN_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
97     {"+BVRA", BTA_AG_AT_BVRA_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 1},
98     {"+BRSF", BTA_AG_LOCAL_EVT_BRSF, BTA_AG_AT_SET, BTA_AG_AT_INT, 0,
99      BTA_AG_CMD_MAX_VAL},
100     {"+NREC", BTA_AG_AT_NREC_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 0},
101     {"+CNUM", BTA_AG_AT_CNUM_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
102     {"+BTRH", BTA_AG_AT_BTRH_EVT, BTA_AG_AT_READ | BTA_AG_AT_SET, BTA_AG_AT_INT,
103      0, 2},
104     {"+CLCC", BTA_AG_AT_CLCC_EVT, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
105     {"+COPS", BTA_AG_AT_COPS_EVT, BTA_AG_AT_READ | BTA_AG_AT_SET, BTA_AG_AT_STR,
106      0, 0},
107     {"+CMEE", BTA_AG_LOCAL_EVT_CMEE, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 1},
108     {"+BIA", BTA_AG_LOCAL_EVT_BIA, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 20},
109     {"+CBC", BTA_AG_AT_CBC_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 100},
110     {"+BCC", BTA_AG_LOCAL_EVT_BCC, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
111     {"+BCS", BTA_AG_AT_BCS_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0,
112      BTA_AG_CMD_MAX_VAL},
113     {"+BIND", BTA_AG_AT_BIND_EVT,
114      BTA_AG_AT_SET | BTA_AG_AT_READ | BTA_AG_AT_TEST, BTA_AG_AT_STR, 0, 0},
115     {"+BIEV", BTA_AG_AT_BIEV_EVT, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
116     {"+BAC", BTA_AG_AT_BAC_EVT, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 0},
117     /* End-of-table marker used to stop lookup iteration */
118     {"", 0, 0, 0, 0, 0}};
119
120 /* AT result code table element */
121 typedef struct {
122   const char* result_string; /* AT result string */
123   size_t result_id;          /* Local or BTA result id */
124   uint8_t arg_type;          /* whether argument is int or string */
125 } tBTA_AG_RESULT;
126
127 /* AT result code argument types */
128 enum {
129   BTA_AG_RES_FMT_NONE, /* no argument */
130   BTA_AG_RES_FMT_INT,  /* integer argument */
131   BTA_AG_RES_FMT_STR   /* string argument */
132 };
133
134 /* Local AT command result codes not defined in bta_ag_api.h */
135 enum {
136   BTA_AG_LOCAL_RES_FIRST = 0x0100,
137   BTA_AG_LOCAL_RES_OK,
138   BTA_AG_LOCAL_RES_ERROR,
139   BTA_AG_LOCAL_RES_RING,
140   BTA_AG_LOCAL_RES_CLIP,
141   BTA_AG_LOCAL_RES_BRSF,
142   BTA_AG_LOCAL_RES_CMEE,
143   BTA_AG_LOCAL_RES_BCS
144 };
145
146 /* AT result code constant table */
147 const tBTA_AG_RESULT bta_ag_result_tbl[] = {
148     {"OK", BTA_AG_LOCAL_RES_OK, BTA_AG_RES_FMT_NONE},
149     {"ERROR", BTA_AG_LOCAL_RES_ERROR, BTA_AG_RES_FMT_NONE},
150     {"RING", BTA_AG_LOCAL_RES_RING, BTA_AG_RES_FMT_NONE},
151     {"+VGS: ", BTA_AG_SPK_RES, BTA_AG_RES_FMT_INT},
152     {"+VGM: ", BTA_AG_MIC_RES, BTA_AG_RES_FMT_INT},
153     {"+CCWA: ", BTA_AG_CALL_WAIT_RES, BTA_AG_RES_FMT_STR},
154     {"+CHLD: ", BTA_AG_IN_CALL_HELD_RES, BTA_AG_RES_FMT_STR},
155     {"+CIND: ", BTA_AG_CIND_RES, BTA_AG_RES_FMT_STR},
156     {"+CLIP: ", BTA_AG_LOCAL_RES_CLIP, BTA_AG_RES_FMT_STR},
157     {"+CIEV: ", BTA_AG_IND_RES, BTA_AG_RES_FMT_STR},
158     {"+BINP: ", BTA_AG_BINP_RES, BTA_AG_RES_FMT_STR},
159     {"+BVRA: ", BTA_AG_BVRA_RES, BTA_AG_RES_FMT_INT},
160     {"+BRSF: ", BTA_AG_LOCAL_RES_BRSF, BTA_AG_RES_FMT_INT},
161     {"+BSIR: ", BTA_AG_INBAND_RING_RES, BTA_AG_RES_FMT_INT},
162     {"+CNUM: ", BTA_AG_CNUM_RES, BTA_AG_RES_FMT_STR},
163     {"+BTRH: ", BTA_AG_BTRH_RES, BTA_AG_RES_FMT_INT},
164     {"+CLCC: ", BTA_AG_CLCC_RES, BTA_AG_RES_FMT_STR},
165     {"+COPS: ", BTA_AG_COPS_RES, BTA_AG_RES_FMT_STR},
166     {"+CME ERROR: ", BTA_AG_LOCAL_RES_CMEE, BTA_AG_RES_FMT_INT},
167     {"+BCS: ", BTA_AG_LOCAL_RES_BCS, BTA_AG_RES_FMT_INT},
168     {"+BIND: ", BTA_AG_BIND_RES, BTA_AG_RES_FMT_STR},
169     {"", BTA_AG_UNAT_RES, BTA_AG_RES_FMT_STR}};
170
171 static const tBTA_AG_RESULT* bta_ag_result_by_code(size_t code) {
172   for (size_t i = 0;
173        i != sizeof(bta_ag_result_tbl) / sizeof(bta_ag_result_tbl[0]); ++i) {
174     if (code == bta_ag_result_tbl[i].result_id) return &bta_ag_result_tbl[i];
175   }
176   return 0;
177 }
178
179 const tBTA_AG_AT_CMD* bta_ag_at_tbl[BTA_AG_NUM_IDX] = {bta_ag_hsp_cmd,
180                                                        bta_ag_hfp_cmd};
181
182 typedef struct {
183   size_t result_code;
184   size_t indicator;
185 } tBTA_AG_INDICATOR_MAP;
186
187 /* callsetup indicator value lookup table */
188 const tBTA_AG_INDICATOR_MAP callsetup_indicator_map[] = {
189     {BTA_AG_IN_CALL_RES, BTA_AG_CALLSETUP_INCOMING},
190     {BTA_AG_CALL_WAIT_RES, BTA_AG_CALLSETUP_INCOMING},
191     {BTA_AG_OUT_CALL_ORIG_RES, BTA_AG_CALLSETUP_OUTGOING},
192     {BTA_AG_OUT_CALL_ALERT_RES, BTA_AG_CALLSETUP_ALERTING}};
193
194 static size_t bta_ag_indicator_by_result_code(size_t code) {
195   for (size_t i = 0;
196        i !=
197        sizeof(callsetup_indicator_map) / sizeof(callsetup_indicator_map[0]);
198        ++i) {
199     if (code == callsetup_indicator_map[i].result_code)
200       return callsetup_indicator_map[i].indicator;
201   }
202   return BTA_AG_CALLSETUP_NONE;
203 }
204
205 /*******************************************************************************
206  *
207  * Function         bta_ag_send_result
208  *
209  * Description      Send an AT result code.
210  *
211  *
212  * Returns          void
213  *
214  ******************************************************************************/
215 static void bta_ag_send_result(tBTA_AG_SCB* p_scb, size_t code,
216                                const char* p_arg, int16_t int_arg) {
217   const tBTA_AG_RESULT* result = bta_ag_result_by_code(code);
218   if (result == 0) {
219     LOG_ERROR(LOG_TAG, "%s Unable to lookup result for code %zu", __func__,
220               code);
221     return;
222   }
223
224   char buf[BTA_AG_AT_MAX_LEN + 16];
225   char* p = buf;
226   memset(buf, 0, sizeof(buf));
227
228   /* init with \r\n */
229   *p++ = '\r';
230   *p++ = '\n';
231
232   /* copy result code string */
233   strlcpy(p, result->result_string, sizeof(buf) - 2);
234
235   if (p_scb->conn_service == BTA_AG_HSP) {
236     /* If HSP then ":"symbol should be changed as "=" for HSP compatibility */
237     switch (code) {
238       case BTA_AG_SPK_RES:
239       case BTA_AG_MIC_RES:
240         if (*(p + COLON_IDX_4_VGSVGM) == ':') {
241           *(p + COLON_IDX_4_VGSVGM) = '=';
242         }
243         break;
244     }
245   }
246
247   p += strlen(result->result_string);
248
249   /* copy argument if any */
250   if (result->arg_type == BTA_AG_RES_FMT_INT) {
251     p += utl_itoa((uint16_t)int_arg, p);
252   } else if (result->arg_type == BTA_AG_RES_FMT_STR) {
253     strcpy(p, p_arg);
254     p += strlen(p_arg);
255   }
256
257   /* finish with \r\n */
258   *p++ = '\r';
259   *p++ = '\n';
260
261   /* send to RFCOMM */
262   uint16_t len = 0;
263   PORT_WriteData(p_scb->conn_handle, buf, (uint16_t)(p - buf), &len);
264 }
265
266 /*******************************************************************************
267  *
268  * Function         bta_ag_send_ok
269  *
270  * Description      Send an OK result code.
271  *
272  *
273  * Returns          void
274  *
275  ******************************************************************************/
276 static void bta_ag_send_ok(tBTA_AG_SCB* p_scb) {
277   bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_OK, NULL, 0);
278 }
279
280 /*******************************************************************************
281  *
282  * Function         bta_ag_send_error
283  *
284  * Description      Send an ERROR result code.
285  *                      errcode - used to send verbose errocode
286  *
287  *
288  * Returns          void
289  *
290  ******************************************************************************/
291 static void bta_ag_send_error(tBTA_AG_SCB* p_scb, int16_t errcode) {
292   /* If HFP and extended audio gateway error codes are enabled */
293   if (p_scb->conn_service == BTA_AG_HFP && p_scb->cmee_enabled)
294     bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_CMEE, NULL, errcode);
295   else
296     bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_ERROR, NULL, 0);
297 }
298
299 /*******************************************************************************
300  *
301  * Function         bta_ag_send_ind
302  *
303  * Description      Send an indicator CIEV result code.
304  *
305  *
306  * Returns          void
307  *
308  ******************************************************************************/
309 static void bta_ag_send_ind(tBTA_AG_SCB* p_scb, uint16_t id, uint16_t value,
310                             bool on_demand) {
311   char str[12];
312   char* p = str;
313
314   /* If the indicator is masked out, just return */
315   /* Mandatory indicators can not be masked out. */
316   if ((p_scb->bia_masked_out & ((uint32_t)1 << id)) &&
317       ((id != BTA_AG_IND_CALL) && (id != BTA_AG_IND_CALLSETUP) &&
318        (id != BTA_AG_IND_CALLHELD)))
319     return;
320
321   /* Ensure we do not send duplicate indicators if not requested by app */
322   /* If it was requested by app, transmit CIEV even if it is duplicate. */
323   if (id == BTA_AG_IND_CALL) {
324     if ((value == p_scb->call_ind) && (on_demand == false)) return;
325
326     p_scb->call_ind = (uint8_t)value;
327   }
328
329   if ((id == BTA_AG_IND_CALLSETUP) && (on_demand == false)) {
330     if (value == p_scb->callsetup_ind) return;
331
332     p_scb->callsetup_ind = (uint8_t)value;
333   }
334
335   if ((id == BTA_AG_IND_SERVICE) && (on_demand == false)) {
336     if (value == p_scb->service_ind) return;
337
338     p_scb->service_ind = (uint8_t)value;
339   }
340   if ((id == BTA_AG_IND_SIGNAL) && (on_demand == false)) {
341     if (value == p_scb->signal_ind) return;
342
343     p_scb->signal_ind = (uint8_t)value;
344   }
345   if ((id == BTA_AG_IND_ROAM) && (on_demand == false)) {
346     if (value == p_scb->roam_ind) return;
347
348     p_scb->roam_ind = (uint8_t)value;
349   }
350   if ((id == BTA_AG_IND_BATTCHG) && (on_demand == false)) {
351     if (value == p_scb->battchg_ind) return;
352
353     p_scb->battchg_ind = (uint8_t)value;
354   }
355
356   if ((id == BTA_AG_IND_CALLHELD) && (on_demand == false)) {
357     /* call swap could result in sending callheld=1 multiple times */
358     if ((value != 1) && (value == p_scb->callheld_ind)) return;
359
360     p_scb->callheld_ind = (uint8_t)value;
361   }
362
363   if (p_scb->cmer_enabled) {
364     p += utl_itoa(id, p);
365     *p++ = ',';
366     utl_itoa(value, p);
367     bta_ag_send_result(p_scb, BTA_AG_IND_RES, str, 0);
368   }
369 }
370
371 /*******************************************************************************
372  *
373  * Function         bta_ag_parse_cmer
374  *
375  * Description      Parse AT+CMER parameter string.
376  *
377  *
378  * Returns          true if parsed ok, false otherwise.
379  *
380  ******************************************************************************/
381 static bool bta_ag_parse_cmer(char* p_s, bool* p_enabled) {
382   int16_t n[4] = {-1, -1, -1, -1};
383   int i;
384   char* p;
385
386   for (i = 0; i < 4; i++) {
387     /* skip to comma delimiter */
388     for (p = p_s; *p != ',' && *p != 0; p++)
389       ;
390
391     /* get integer value */
392     *p = 0;
393     n[i] = utl_str2int(p_s);
394     p_s = p + 1;
395     if (p_s == 0) {
396       break;
397     }
398   }
399
400   /* process values */
401   if (n[0] < 0 || n[3] < 0) {
402     return false;
403   }
404
405   if ((n[0] == 3) && ((n[3] == 1) || (n[3] == 0))) {
406     *p_enabled = (bool)n[3];
407   }
408
409   return true;
410 }
411
412 /*******************************************************************************
413  *
414  * Function         bta_ag_parse_chld
415  *
416  * Description      Parse AT+CHLD parameter string.
417  *
418  *
419  * Returns          Returns idx (1-7), 0 if ECC not enabled or
420  BTA_AG_INVALID_CHLD
421                     if idx doesn't exist/1st character of argument is not a
422  digit
423  *
424  ******************************************************************************/
425 static uint8_t bta_ag_parse_chld(UNUSED_ATTR tBTA_AG_SCB* p_scb, char* p_s) {
426   uint8_t retval = 0;
427   int16_t idx = -1;
428
429   if (!isdigit(p_s[0])) {
430     return BTA_AG_INVALID_CHLD;
431   }
432
433   if (p_s[1] != 0) {
434     /* p_idxstr++;  point to beginning of call number */
435     idx = utl_str2int(&p_s[1]);
436     if (idx != -1 && idx < 255) {
437       retval = (uint8_t)idx;
438     } else {
439       retval = BTA_AG_INVALID_CHLD;
440     }
441   }
442
443   return (retval);
444 }
445
446 /*******************************************************************************
447  *
448  * Function         bta_ag_parse_bac
449  *
450  * Description      Parse AT+BAC parameter string.
451  *
452  * Returns          Returns bitmap of supported codecs.
453  *
454  ******************************************************************************/
455 static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB* p_scb, char* p_s) {
456   tBTA_AG_PEER_CODEC retval = BTA_AG_CODEC_NONE;
457   uint16_t uuid_codec;
458   bool cont = false; /* Continue processing */
459   char* p;
460
461   while (p_s) {
462     /* skip to comma delimiter */
463     for (p = p_s; *p != ',' && *p != 0; p++)
464       ;
465
466     /* get integre value */
467     if (*p != 0) {
468       *p = 0;
469       cont = true;
470     } else
471       cont = false;
472
473     uuid_codec = utl_str2int(p_s);
474     switch (uuid_codec) {
475       case UUID_CODEC_CVSD:
476         retval |= BTA_AG_CODEC_CVSD;
477         break;
478       case UUID_CODEC_MSBC:
479         retval |= BTA_AG_CODEC_MSBC;
480         break;
481       default:
482         APPL_TRACE_ERROR("Unknown Codec UUID(%d) received", uuid_codec);
483         break;
484     }
485
486     if (cont)
487       p_s = p + 1;
488     else
489       break;
490   }
491
492   return (retval);
493 }
494
495 /*******************************************************************************
496  *
497  * Function         bta_ag_process_unat_res
498  *
499  * Description      Process the unat response data and remove extra carriage
500  *                  return and line feed
501  *
502  *
503  * Returns          void
504  *
505  ******************************************************************************/
506
507 static void bta_ag_process_unat_res(char* unat_result) {
508   uint8_t str_leng;
509   uint8_t i = 0;
510   uint8_t j = 0;
511   uint8_t pairs_of_nl_cr;
512   char trim_data[BTA_AG_AT_MAX_LEN];
513
514   str_leng = strlen(unat_result);
515
516   /* If no extra CR and LF, just return */
517   if (str_leng < 4) return;
518
519   /* Remove the carriage return and left feed */
520   while (unat_result[0] == '\r' && unat_result[1] == '\n' &&
521          unat_result[str_leng - 2] == '\r' &&
522          unat_result[str_leng - 1] == '\n') {
523     pairs_of_nl_cr = 1;
524     for (i = 0; i < (str_leng - 4 * pairs_of_nl_cr); i++) {
525       trim_data[j++] = unat_result[i + pairs_of_nl_cr * 2];
526     }
527     /* Add EOF */
528     trim_data[j] = '\0';
529     str_leng = str_leng - 4;
530     strlcpy(unat_result, trim_data, str_leng + 1);
531     i = 0;
532     j = 0;
533
534     if (str_leng < 4) return;
535   }
536   return;
537 }
538
539 /*******************************************************************************
540  *
541  * Function         bta_ag_inband_enabled
542  *
543  * Description      Determine whether in-band ring can be used.
544  *
545  *
546  * Returns          void
547  *
548  ******************************************************************************/
549 bool bta_ag_inband_enabled(tBTA_AG_SCB* p_scb) {
550   /* if feature is enabled and no other scbs connected */
551   if (p_scb->inband_enabled && !bta_ag_other_scb_open(p_scb)) {
552     return true;
553   } else {
554     return false;
555   }
556 }
557
558 /*******************************************************************************
559  *
560  * Function         bta_ag_send_call_inds
561  *
562  * Description      Send call and callsetup indicators.
563  *
564  *
565  * Returns          void
566  *
567  ******************************************************************************/
568 void bta_ag_send_call_inds(tBTA_AG_SCB* p_scb, tBTA_AG_RES result) {
569   uint8_t call = p_scb->call_ind;
570
571   /* set new call and callsetup values based on BTA_AgResult */
572   size_t callsetup = bta_ag_indicator_by_result_code(result);
573
574   if (result == BTA_AG_END_CALL_RES) {
575     call = BTA_AG_CALL_INACTIVE;
576   } else if (result == BTA_AG_IN_CALL_CONN_RES ||
577              result == BTA_AG_OUT_CALL_CONN_RES ||
578              result == BTA_AG_IN_CALL_HELD_RES) {
579     call = BTA_AG_CALL_ACTIVE;
580   } else {
581     call = p_scb->call_ind;
582   }
583
584   /* Send indicator function tracks if the values have actually changed */
585   bta_ag_send_ind(p_scb, BTA_AG_IND_CALL, call, false);
586   bta_ag_send_ind(p_scb, BTA_AG_IND_CALLSETUP, callsetup, false);
587 }
588
589 /*******************************************************************************
590  *
591  * Function         bta_ag_at_hsp_cback
592  *
593  * Description      AT command processing callback for HSP.
594  *
595  *
596  * Returns          void
597  *
598  ******************************************************************************/
599 void bta_ag_at_hsp_cback(tBTA_AG_SCB* p_scb, uint16_t command_id,
600                          uint8_t arg_type, char* p_arg, int16_t int_arg) {
601   APPL_TRACE_DEBUG("AT cmd:%d arg_type:%d arg:%d arg:%s", command_id, arg_type,
602                    int_arg, p_arg);
603
604   bta_ag_send_ok(p_scb);
605
606   tBTA_AG_VAL val;
607   val.hdr.handle = bta_ag_scb_to_idx(p_scb);
608   val.hdr.app_id = p_scb->app_id;
609   val.num = (uint16_t)int_arg;
610   strlcpy(val.str, p_arg, sizeof(val.str));
611
612   /* call callback with event */
613   (*bta_ag_cb.p_cback)(command_id, (tBTA_AG*)&val);
614 }
615
616 static void remove_spaces(char* str) {
617   char* dest_str = str;
618
619   while (*str) {
620     if (*str == ' ') {
621       str++;
622     } else {
623       *dest_str++ = *str++;
624     }
625   }
626   *dest_str = '\0';
627 }
628
629 /*******************************************************************************
630  *
631  * Function         bta_ag_find_empty_hf_ind)
632  *
633  * Description      This function returns the index of an empty HF indicator
634  *                  structure.
635  *
636  * Returns          int : index of the empty HF indicator structure or
637  *                            -1 if no empty indicator
638  *                            is available.
639  *
640  ******************************************************************************/
641 static int bta_ag_find_empty_hf_ind(tBTA_AG_SCB* p_scb) {
642   for (int index = 0; index < BTA_AG_MAX_NUM_PEER_HF_IND; index++) {
643     if (p_scb->peer_hf_indicators[index].ind_id == 0) return index;
644   }
645
646   return -1;
647 }
648
649 /*******************************************************************************
650  *
651  * Function         bta_ag_find_hf_ind_by_id
652  *
653  * Description      This function returns the index of the HF indicator
654  *                  structure by the indicator id
655  *
656  * Returns          int : index of the HF indicator structure
657  *                            -1 if the indicator
658  *                            was not found.
659  *
660  ******************************************************************************/
661 static int bta_ag_find_hf_ind_by_id(tBTA_AG_HF_IND* p_hf_ind, int size,
662                                     uint32_t ind_id) {
663   for (int index = 0; index < size; index++) {
664     if (p_hf_ind[index].ind_id == ind_id) return index;
665   }
666
667   return -1;
668 }
669
670 /*******************************************************************************
671  *
672  * Function         bta_ag_parse_bind_set
673  *
674  * Description      Parse AT+BIND set command and save the indicators
675  *
676  * Returns          true if successful
677  *
678  ******************************************************************************/
679 static bool bta_ag_parse_bind_set(tBTA_AG_SCB* p_scb, tBTA_AG_VAL val) {
680   char* p_token = strtok(val.str, ",");
681   if (p_token == NULL) return false;
682
683   while (p_token != NULL) {
684     uint16_t rcv_ind_id = atoi(p_token);
685     int index = bta_ag_find_empty_hf_ind(p_scb);
686     if (index == -1) {
687       APPL_TRACE_WARNING("%s Can't save more indicators", __func__);
688       return false;
689     }
690
691     p_scb->peer_hf_indicators[index].ind_id = rcv_ind_id;
692     APPL_TRACE_DEBUG("%s peer_hf_ind[%d] = %d", __func__, index, rcv_ind_id);
693
694     p_token = strtok(NULL, ",");
695   }
696
697   return true;
698 }
699
700 /*******************************************************************************
701  *
702  * Function         bta_ag_bind_response
703  *
704  * Description      Send response for the AT+BIND command (HFP 1.7) received
705  *                  from the headset based on the argument types.
706  *
707  * Returns          Void
708  *
709  ******************************************************************************/
710 static void bta_ag_bind_response(tBTA_AG_SCB* p_scb, uint8_t arg_type) {
711   char buffer[BTA_AG_AT_MAX_LEN];
712   memset(buffer, 0, BTA_AG_AT_MAX_LEN);
713
714   if (arg_type == BTA_AG_AT_TEST) {
715     int index = 0;
716     buffer[index++] = '(';
717
718     for (uint32_t i = 0; i < bta_ag_local_hf_ind_cfg[0].ind_id; i++) {
719       if (bta_ag_local_hf_ind_cfg[i + 1].is_supported) {
720         /* Add ',' from second indicator */
721         if (index > 1) buffer[index++] = ',';
722         snprintf(&buffer[index++], 2, "%d",
723                  bta_ag_local_hf_ind_cfg[i + 1].ind_id);
724       }
725     }
726
727     buffer[index++] = ')';
728
729     bta_ag_send_result(p_scb, BTA_AG_BIND_RES, buffer, 0);
730     bta_ag_send_ok(p_scb);
731   } else if (arg_type == BTA_AG_AT_READ) {
732     char* p = buffer;
733
734     /* bta_ag_local_hf_ind_cfg[0].ind_id is used as BTA_AG_NUM_LOCAL_HF_IND */
735     for (uint32_t i = 0; i < bta_ag_local_hf_ind_cfg[0].ind_id; i++) {
736       if (i == BTA_AG_MAX_NUM_LOCAL_HF_IND) {
737         APPL_TRACE_WARNING("%s No space for more HF indicators", __func__);
738         break;
739       }
740
741       p_scb->local_hf_indicators[i].ind_id =
742           bta_ag_local_hf_ind_cfg[i + 1].ind_id;
743       p_scb->local_hf_indicators[i].is_supported =
744           bta_ag_local_hf_ind_cfg[i + 1].is_supported;
745       p_scb->local_hf_indicators[i].is_enable =
746           bta_ag_local_hf_ind_cfg[i + 1].is_enable;
747
748       int peer_index = bta_ag_find_hf_ind_by_id(
749           p_scb->peer_hf_indicators, BTA_AG_MAX_NUM_PEER_HF_IND,
750           p_scb->local_hf_indicators[i].ind_id);
751
752       /* Check whether local and peer sides support this indicator */
753       if (p_scb->local_hf_indicators[i].is_supported == true &&
754           peer_index != -1) {
755         /* In the format of ind, state */
756         p += utl_itoa((uint16_t)p_scb->local_hf_indicators[i].ind_id, p);
757         *p++ = ',';
758         p += utl_itoa((uint16_t)p_scb->local_hf_indicators[i].is_enable, p);
759
760         bta_ag_send_result(p_scb, BTA_AG_BIND_RES, buffer, 0);
761
762         memset(buffer, 0, sizeof(buffer));
763         p = buffer;
764       } else {
765         /* If indicator is not supported, also set it to disable */
766         p_scb->local_hf_indicators[i].is_enable = false;
767       }
768     }
769
770     bta_ag_send_ok(p_scb);
771
772     /* If the service level connection wan't already open, now it's open */
773     if (!p_scb->svc_conn) bta_ag_svc_conn_open(p_scb, NULL);
774   }
775 }
776
777 /*******************************************************************************
778  *
779  * Function         bta_ag_parse_biev_response
780  *
781  * Description      Send response for AT+BIEV command (HFP 1.7) received from
782  *                  the headset based on the argument types.
783  *
784  * Returns          true if the response was parsed successfully
785  *
786  ******************************************************************************/
787 static bool bta_ag_parse_biev_response(tBTA_AG_SCB* p_scb, tBTA_AG_VAL* val) {
788   char* p_token = strtok(val->str, ",");
789   uint16_t rcv_ind_id = atoi(p_token);
790
791   p_token = strtok(NULL, ",");
792   uint16_t rcv_ind_val = atoi(p_token);
793
794   APPL_TRACE_DEBUG("%s BIEV indicator id %d, value %d", __func__, rcv_ind_id,
795                    rcv_ind_val);
796
797   /* Check whether indicator ID is valid or not */
798   if (rcv_ind_id > BTA_AG_NUM_LOCAL_HF_IND) {
799     APPL_TRACE_WARNING("%s received invalid indicator id %d", __func__,
800                        rcv_ind_id);
801     return false;
802   }
803
804   /* Check this indicator is support or not and enabled or not */
805   int local_index = bta_ag_find_hf_ind_by_id(
806       p_scb->local_hf_indicators, BTA_AG_MAX_NUM_LOCAL_HF_IND, rcv_ind_id);
807   if (local_index == -1 ||
808       p_scb->local_hf_indicators[local_index].is_supported != true ||
809       p_scb->local_hf_indicators[local_index].is_enable != true) {
810     APPL_TRACE_WARNING("%s indicator id %d not supported or disabled", __func__,
811                        rcv_ind_id);
812     return false;
813   }
814
815   /* For each indicator ID, check whether the indicator value is in range */
816   if (rcv_ind_val < bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_min_val ||
817       rcv_ind_val > bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_max_val) {
818     APPL_TRACE_WARNING("%s invalid ind_val %d", __func__, rcv_ind_val);
819     return false;
820   }
821
822   val->lidx = rcv_ind_id;
823   val->num = rcv_ind_val;
824
825   return true;
826 }
827
828 /*******************************************************************************
829  *
830  * Function         bta_ag_at_hfp_cback
831  *
832  * Description      AT command processing callback for HFP.
833  *
834  *
835  * Returns          void
836  *
837  ******************************************************************************/
838 void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
839                          char* p_arg, int16_t int_arg) {
840   tBTA_AG_VAL val;
841   tBTA_AG_SCB* ag_scb;
842   uint32_t i, ind_id;
843   uint32_t bia_masked_out;
844   if (p_arg == NULL) {
845     APPL_TRACE_ERROR("%s: p_arg is null, send error and return", __func__);
846     bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
847     return;
848   }
849
850   APPL_TRACE_DEBUG("%s: AT command %d, arg_type %d, int_arg %d, arg %s",
851                    __func__, cmd, arg_type, int_arg, p_arg);
852
853   memset(&val, 0, sizeof(tBTA_AG_VAL));
854   val.hdr.handle = bta_ag_scb_to_idx(p_scb);
855   val.hdr.app_id = p_scb->app_id;
856   val.hdr.status = BTA_AG_SUCCESS;
857   val.num = int_arg;
858   val.bd_addr = p_scb->peer_addr;
859   strlcpy(val.str, p_arg, sizeof(val.str));
860
861   /**
862    * Unless this this is a local event, by default we'll forward
863    * the event code to the application.
864    * If |event| is 0 at the end of this function, the application
865    * callback is NOT invoked.
866    */
867   tBTA_AG_EVT event = 0;
868   if (cmd < BTA_AG_LOCAL_EVT_FIRST) event = cmd;
869
870   switch (cmd) {
871     case BTA_AG_AT_A_EVT:
872     case BTA_AG_SPK_EVT:
873     case BTA_AG_MIC_EVT:
874     case BTA_AG_AT_CHUP_EVT:
875     case BTA_AG_AT_CBC_EVT:
876       /* send OK */
877       bta_ag_send_ok(p_scb);
878       break;
879
880     case BTA_AG_AT_BLDN_EVT:
881       /* Do not send OK, App will send error or OK depending on
882       ** last dial number enabled or not */
883       break;
884
885     case BTA_AG_AT_D_EVT:
886       /* Do not send OK for Dial cmds
887       ** Let application decide whether to send OK or ERROR*/
888
889       /* if mem dial cmd, make sure string contains only digits */
890       if (val.str[0] == '>') {
891         /* Some car kits may add some unwanted space characters in the
892         ** input string. This workaround will trim the unwanted chars. */
893         remove_spaces(val.str + 1);
894
895         if (!utl_isintstr(val.str + 1)) {
896           event = 0;
897           bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR);
898         }
899       } else if (val.str[0] == 'V') /* ATDV : Dial VoIP Call */
900       {
901         /* We do not check string. Code will be added later if needed. */
902         if (!((p_scb->peer_features & BTA_AG_PEER_FEAT_VOIP) &&
903               (p_scb->features & BTA_AG_FEAT_VOIP))) {
904           event = 0;
905           bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
906         }
907       }
908       /* If dial cmd, make sure string contains only dial digits
909       ** Dial digits are 0-9, A-C, *, #, + */
910       else {
911         /* Some car kits may add some unwanted space characters in the
912         ** input string. This workaround will trim the unwanted chars. */
913         remove_spaces(val.str);
914
915         if (!utl_isdialstr(val.str)) {
916           event = 0;
917           bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR);
918         }
919       }
920       break;
921
922     case BTA_AG_LOCAL_EVT_CCWA:
923       /* store setting */
924       p_scb->ccwa_enabled = (bool)int_arg;
925
926       /* send OK */
927       bta_ag_send_ok(p_scb);
928       break;
929
930     case BTA_AG_AT_CHLD_EVT:
931       if (arg_type == BTA_AG_AT_TEST) {
932         /* don't call callback */
933         event = 0;
934
935         /* send CHLD string */
936         /* Form string based on supported 1.5 feature */
937         if ((p_scb->peer_version >= HFP_VERSION_1_5) &&
938             (p_scb->features & BTA_AG_FEAT_ECC) &&
939             (p_scb->peer_features & BTA_AG_PEER_FEAT_ECC))
940           bta_ag_send_result(p_scb, BTA_AG_IN_CALL_HELD_RES,
941                              p_bta_ag_cfg->chld_val_ecc, 0);
942         else
943           bta_ag_send_result(p_scb, BTA_AG_IN_CALL_HELD_RES,
944                              p_bta_ag_cfg->chld_val, 0);
945
946         /* send OK */
947         bta_ag_send_ok(p_scb);
948
949         /* if service level conn. not already open, now it's open */
950         bta_ag_svc_conn_open(p_scb, NULL);
951       } else {
952         val.idx = bta_ag_parse_chld(p_scb, val.str);
953
954         if (val.idx == BTA_AG_INVALID_CHLD) {
955           event = 0;
956           bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
957           break;
958         }
959         if (val.idx &&
960             !((p_scb->features & BTA_AG_FEAT_ECC) &&
961               (p_scb->peer_features & BTA_AG_PEER_FEAT_ECC))) {
962           /* we do not support ECC, but HF is sending us a CHLD with call
963            * index*/
964           event = 0;
965           bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
966
967         } else {
968           /* If it is swap between calls, set call held indicator to 3(out of
969           *valid 0-2)
970           ** Application will set it back to 1
971           ** callheld indicator will be sent across to the peer. */
972           if (val.str[0] == '2') {
973             for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB;
974                  i++, ag_scb++) {
975               if (ag_scb->in_use) {
976                 if ((ag_scb->call_ind == BTA_AG_CALL_ACTIVE) &&
977                     (ag_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE))
978                   ag_scb->callheld_ind = BTA_AG_CALLHELD_NOACTIVE + 1;
979               }
980             }
981           }
982         }
983
984         /* Do not send OK. Let app decide after parsing the val str */
985         /* bta_ag_send_ok(p_scb); */
986       }
987       break;
988
989     case BTA_AG_AT_BIND_EVT:
990       APPL_TRACE_DEBUG("%s BTA_AG_AT_BIND_EVT arg_type: %d", __func__,
991                        arg_type);
992       if (arg_type == BTA_AG_AT_SET) {
993         if (bta_ag_parse_bind_set(p_scb, val)) {
994           bta_ag_send_ok(p_scb);
995         } else {
996           event = 0; /* don't call callback */
997           bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
998         }
999       } else {
1000         bta_ag_bind_response(p_scb, arg_type);
1001
1002         /* Need not pass this command beyond BTIF.*/
1003         /* Stack handles it internally */
1004         event = 0; /* don't call callback */
1005       }
1006       break;
1007
1008     case BTA_AG_AT_BIEV_EVT:
1009       if (bta_ag_parse_biev_response(p_scb, &val)) {
1010         bta_ag_send_ok(p_scb);
1011       } else {
1012         bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
1013         /* don't call callback receiving invalid indicator */
1014         event = 0;
1015       }
1016       break;
1017
1018     case BTA_AG_AT_CIND_EVT:
1019       if (arg_type == BTA_AG_AT_TEST) {
1020         /* don't call callback */
1021         event = 0;
1022
1023         /* send CIND string, send OK */
1024         bta_ag_send_result(p_scb, BTA_AG_CIND_RES, p_bta_ag_cfg->cind_info, 0);
1025         bta_ag_send_ok(p_scb);
1026       }
1027       break;
1028
1029     case BTA_AG_LOCAL_EVT_CLIP:
1030       /* store setting, send OK */
1031       p_scb->clip_enabled = (bool)int_arg;
1032       bta_ag_send_ok(p_scb);
1033       break;
1034
1035     case BTA_AG_LOCAL_EVT_CMER:
1036       /* if parsed ok store setting, send OK */
1037       if (bta_ag_parse_cmer(p_arg, &p_scb->cmer_enabled)) {
1038         bta_ag_send_ok(p_scb);
1039
1040         /* if service level conn. not already open and our features and
1041         ** peer features do not have 3-way, service level conn. now open
1042         */
1043         if (!p_scb->svc_conn &&
1044             !((p_scb->features & BTA_AG_FEAT_3WAY) &&
1045               (p_scb->peer_features & BTA_AG_PEER_FEAT_3WAY))) {
1046           bta_ag_svc_conn_open(p_scb, NULL);
1047         }
1048       } else {
1049         bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
1050       }
1051       break;
1052
1053     case BTA_AG_AT_VTS_EVT:
1054       /* check argument */
1055       if (strlen(p_arg) == 1) {
1056         bta_ag_send_ok(p_scb);
1057       } else {
1058         event = 0;
1059         bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
1060       }
1061       break;
1062
1063     case BTA_AG_AT_BINP_EVT:
1064       /* if feature not set don't call callback, send ERROR */
1065       if (!(p_scb->features & BTA_AG_FEAT_VTAG)) {
1066         event = 0;
1067         bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1068       }
1069       break;
1070
1071     case BTA_AG_AT_BVRA_EVT:
1072       /* if feature not supported don't call callback, send ERROR. App will send
1073        * OK */
1074       if (!(p_scb->features & BTA_AG_FEAT_VREC)) {
1075         event = 0;
1076         bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1077       }
1078       break;
1079
1080     case BTA_AG_LOCAL_EVT_BRSF: {
1081       /* store peer features */
1082       p_scb->peer_features = (uint16_t)int_arg;
1083
1084       tBTA_AG_FEAT features = p_scb->features;
1085       if (p_scb->peer_version < HFP_VERSION_1_7) {
1086         features &= HFP_1_6_FEAT_MASK;
1087       }
1088
1089       APPL_TRACE_DEBUG("%s BRSF HF: 0x%x, phone: 0x%x", __func__,
1090                        p_scb->peer_features, features);
1091
1092       /* send BRSF, send OK */
1093       bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_BRSF, NULL, (int16_t)features);
1094       bta_ag_send_ok(p_scb);
1095       break;
1096     }
1097
1098     case BTA_AG_AT_NREC_EVT:
1099       /* if feature send OK, else don't call callback, send ERROR */
1100       if (p_scb->features & BTA_AG_FEAT_ECNR) {
1101         bta_ag_send_ok(p_scb);
1102       } else {
1103         event = 0;
1104         bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1105       }
1106       break;
1107
1108     case BTA_AG_AT_BTRH_EVT:
1109       /* if feature send BTRH, send OK:, else don't call callback, send ERROR */
1110       if (p_scb->features & BTA_AG_FEAT_BTRH) {
1111         /* If set command; send response and notify app */
1112         if (arg_type == BTA_AG_AT_SET) {
1113           for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB;
1114                i++, ag_scb++) {
1115             if (ag_scb->in_use) {
1116               bta_ag_send_result(ag_scb, BTA_AG_BTRH_RES, NULL, int_arg);
1117             }
1118           }
1119           bta_ag_send_ok(p_scb);
1120         } else /* Read Command */
1121         {
1122           val.num = BTA_AG_BTRH_READ;
1123         }
1124       } else {
1125         event = 0;
1126         bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1127       }
1128       break;
1129
1130     case BTA_AG_AT_COPS_EVT:
1131       if (arg_type == BTA_AG_AT_SET) {
1132         /* don't call callback */
1133         event = 0;
1134
1135         /* send OK */
1136         bta_ag_send_ok(p_scb);
1137       }
1138       break;
1139
1140     case BTA_AG_LOCAL_EVT_CMEE:
1141       if (p_scb->features & BTA_AG_FEAT_EXTERR) {
1142         /* store setting */
1143         p_scb->cmee_enabled = (bool)int_arg;
1144
1145         /* send OK */
1146         bta_ag_send_ok(p_scb);
1147       } else {
1148         bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1149       }
1150       /* don't call callback */
1151       event = 0;
1152       break;
1153
1154     case BTA_AG_LOCAL_EVT_BIA:
1155       /* don't call callback */
1156       event = 0;
1157
1158       bia_masked_out = p_scb->bia_masked_out;
1159
1160       /* Parse the indicator mask */
1161       for (i = 0, ind_id = 1; (val.str[i] != 0) && (ind_id <= 20);
1162            i++, ind_id++) {
1163         if (val.str[i] == ',') continue;
1164
1165         if (val.str[i] == '0')
1166           bia_masked_out |= ((uint32_t)1 << ind_id);
1167         else if (val.str[i] == '1')
1168           bia_masked_out &= ~((uint32_t)1 << ind_id);
1169         else
1170           break;
1171
1172         i++;
1173         if ((val.str[i] == 0) || (val.str[i] != ',')) break;
1174       }
1175       if (val.str[i] == 0) {
1176         p_scb->bia_masked_out = bia_masked_out;
1177         bta_ag_send_ok(p_scb);
1178       } else
1179         bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
1180       break;
1181
1182     case BTA_AG_AT_CNUM_EVT:
1183       break;
1184
1185     case BTA_AG_AT_CLCC_EVT:
1186       if (!(p_scb->features & BTA_AG_FEAT_ECS)) {
1187         event = 0;
1188         bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1189       }
1190       break;
1191
1192     case BTA_AG_AT_BAC_EVT:
1193       bta_ag_send_ok(p_scb);
1194
1195       /* store available codecs from the peer */
1196       if ((p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC) &&
1197           (p_scb->features & BTA_AG_FEAT_CODEC)) {
1198         p_scb->peer_codecs = bta_ag_parse_bac(p_scb, p_arg);
1199         p_scb->codec_updated = true;
1200
1201         if (p_scb->peer_codecs & BTA_AG_CODEC_MSBC) {
1202           p_scb->sco_codec = UUID_CODEC_MSBC;
1203           APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to MSBC");
1204         } else {
1205           p_scb->sco_codec = UUID_CODEC_CVSD;
1206           APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to CVSD");
1207         }
1208         /* The above logic sets the stack preferred codec based on local and
1209         peer codec
1210         capabilities. This can be overridden by the application depending on its
1211         preference
1212         using the bta_ag_setcodec API. We send the peer_codecs to the
1213         application. */
1214         val.num = p_scb->peer_codecs;
1215         /* Received BAC while in codec negotiation. */
1216         if ((bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST) &&
1217             (bta_ag_cb.sco.p_curr_scb == p_scb)) {
1218           bta_ag_codec_negotiate(p_scb);
1219         }
1220       } else {
1221         p_scb->peer_codecs = BTA_AG_CODEC_CVSD;
1222         APPL_TRACE_ERROR(
1223             "Unexpected CMD:AT+BAC, Codec Negotiation is not supported");
1224       }
1225       break;
1226
1227     case BTA_AG_AT_BCS_EVT: {
1228       tBTA_AG_PEER_CODEC codec_type, codec_sent;
1229       bta_ag_send_ok(p_scb);
1230       alarm_cancel(p_scb->codec_negotiation_timer);
1231
1232       switch (int_arg) {
1233         case UUID_CODEC_CVSD:
1234           codec_type = BTA_AG_CODEC_CVSD;
1235           break;
1236         case UUID_CODEC_MSBC:
1237           codec_type = BTA_AG_CODEC_MSBC;
1238           break;
1239         default:
1240           APPL_TRACE_ERROR("Unknown codec_uuid %d", int_arg);
1241           codec_type = 0xFFFF;
1242           break;
1243       }
1244
1245       if (p_scb->codec_fallback)
1246         codec_sent = BTA_AG_CODEC_CVSD;
1247       else
1248         codec_sent = p_scb->sco_codec;
1249
1250       if (codec_type == codec_sent)
1251         bta_ag_sco_codec_nego(p_scb, true);
1252       else
1253         bta_ag_sco_codec_nego(p_scb, false);
1254
1255       /* send final codec info to callback */
1256       val.num = codec_sent;
1257       break;
1258     }
1259     case BTA_AG_LOCAL_EVT_BCC:
1260       bta_ag_send_ok(p_scb);
1261       bta_ag_sco_open(p_scb, NULL);
1262       break;
1263
1264     default:
1265       bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1266       break;
1267   }
1268
1269   /* call callback */
1270   if (event != 0) {
1271     (*bta_ag_cb.p_cback)(event, (tBTA_AG*)&val);
1272   }
1273 }
1274
1275 /*******************************************************************************
1276  *
1277  * Function         bta_ag_at_err_cback
1278  *
1279  * Description      AT command parser error callback.
1280  *
1281  *
1282  * Returns          void
1283  *
1284  ******************************************************************************/
1285 void bta_ag_at_err_cback(tBTA_AG_SCB* p_scb, bool unknown, char* p_arg) {
1286   tBTA_AG_VAL val;
1287
1288   if (unknown && (!strlen(p_arg))) {
1289     APPL_TRACE_DEBUG("Empty AT cmd string received");
1290     bta_ag_send_ok(p_scb);
1291     return;
1292   }
1293
1294   /* if unknown AT command and configured to pass these to app */
1295   if (unknown && (p_scb->features & BTA_AG_FEAT_UNAT)) {
1296     val.hdr.handle = bta_ag_scb_to_idx(p_scb);
1297     val.hdr.app_id = p_scb->app_id;
1298     val.hdr.status = BTA_AG_SUCCESS;
1299     val.num = 0;
1300     strlcpy(val.str, p_arg, sizeof(val.str));
1301     (*bta_ag_cb.p_cback)(BTA_AG_AT_UNAT_EVT, (tBTA_AG*)&val);
1302   } else {
1303     bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1304   }
1305 }
1306
1307 /*******************************************************************************
1308  *
1309  * Function         bta_ag_hsp_result
1310  *
1311  * Description      Handle API result for HSP connections.
1312  *
1313  *
1314  * Returns          void
1315  *
1316  ******************************************************************************/
1317 void bta_ag_hsp_result(tBTA_AG_SCB* p_scb, tBTA_AG_API_RESULT* p_result) {
1318   APPL_TRACE_DEBUG("bta_ag_hsp_result : res = %d", p_result->result);
1319
1320   switch (p_result->result) {
1321     case BTA_AG_SPK_RES:
1322     case BTA_AG_MIC_RES:
1323       bta_ag_send_result(p_scb, p_result->result, NULL, p_result->data.num);
1324       break;
1325
1326     case BTA_AG_IN_CALL_RES:
1327       /* tell sys to stop av if any */
1328       bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1329
1330       /* if sco already opened or no inband ring send ring now */
1331       if (bta_ag_sco_is_open(p_scb) || !bta_ag_inband_enabled(p_scb) ||
1332           (p_scb->features & BTA_AG_FEAT_NOSCO)) {
1333         bta_ag_send_ring(p_scb, (tBTA_AG_DATA*)p_result);
1334       } else {
1335         /* else open sco, send ring after sco opened */
1336         /* HSPv1.2: AG shall not send RING if using in-band ring tone. */
1337         if (p_scb->peer_version >= HSP_VERSION_1_2) {
1338           p_scb->post_sco = BTA_AG_POST_SCO_NONE;
1339         } else {
1340           p_scb->post_sco = BTA_AG_POST_SCO_RING;
1341         }
1342         bta_ag_sco_open(p_scb, (tBTA_AG_DATA*)p_result);
1343       }
1344       break;
1345
1346     case BTA_AG_IN_CALL_CONN_RES:
1347     case BTA_AG_OUT_CALL_ORIG_RES:
1348       /* if incoming call connected stop ring timer */
1349       if (p_result->result == BTA_AG_IN_CALL_CONN_RES) {
1350         alarm_cancel(p_scb->ring_timer);
1351       }
1352
1353       if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
1354         /* if audio connected to this scb AND sco is not opened, open sco */
1355         if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
1356             !bta_ag_sco_is_open(p_scb)) {
1357           bta_ag_sco_open(p_scb, (tBTA_AG_DATA*)p_result);
1358         }
1359         /* else if no audio at call close sco */
1360         else if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE &&
1361                  bta_ag_sco_is_open(p_scb)) {
1362           bta_ag_sco_close(p_scb, (tBTA_AG_DATA*)p_result);
1363         }
1364       }
1365       break;
1366
1367     case BTA_AG_END_CALL_RES:
1368       alarm_cancel(p_scb->ring_timer);
1369
1370       /* close sco */
1371       if ((bta_ag_sco_is_open(p_scb) || bta_ag_sco_is_opening(p_scb)) &&
1372           !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
1373         bta_ag_sco_close(p_scb, (tBTA_AG_DATA*)p_result);
1374       } else {
1375         /* if av got suspended by this call, let it resume. */
1376         bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1377       }
1378       break;
1379
1380     case BTA_AG_INBAND_RING_RES:
1381       p_scb->inband_enabled = p_result->data.state;
1382       APPL_TRACE_DEBUG("inband_enabled set to %d", p_scb->inband_enabled);
1383       break;
1384
1385     case BTA_AG_UNAT_RES:
1386       if (p_result->data.ok_flag != BTA_AG_OK_ERROR) {
1387         if (p_result->data.str[0] != 0) {
1388           bta_ag_send_result(p_scb, p_result->result, p_result->data.str, 0);
1389         }
1390
1391         if (p_result->data.ok_flag == BTA_AG_OK_DONE) bta_ag_send_ok(p_scb);
1392       } else {
1393         bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
1394       }
1395       break;
1396
1397     default:
1398       /* ignore all others */
1399       break;
1400   }
1401 }
1402
1403 /*******************************************************************************
1404  *
1405  * Function         bta_ag_hfp_result
1406  *
1407  * Description      Handle API result for HFP connections.
1408  *
1409  *
1410  * Returns          void
1411  *
1412  ******************************************************************************/
1413 void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, tBTA_AG_API_RESULT* p_result) {
1414   APPL_TRACE_DEBUG("bta_ag_hfp_result : res = %d", p_result->result);
1415
1416   switch (p_result->result) {
1417     case BTA_AG_SPK_RES:
1418     case BTA_AG_MIC_RES:
1419       bta_ag_send_result(p_scb, p_result->result, NULL, p_result->data.num);
1420       break;
1421
1422     case BTA_AG_IN_CALL_RES:
1423       /* tell sys to stop av if any */
1424       bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1425
1426       /* store caller id string.
1427        * append type info at the end.
1428        * make sure a valid type info is passed.
1429        * otherwise add 129 as default type */
1430       if ((p_result->data.num < BTA_AG_CLIP_TYPE_MIN) ||
1431           (p_result->data.num > BTA_AG_CLIP_TYPE_MAX)) {
1432         if (p_result->data.num != BTA_AG_CLIP_TYPE_VOIP)
1433           p_result->data.num = BTA_AG_CLIP_TYPE_DEFAULT;
1434       }
1435
1436       APPL_TRACE_DEBUG("CLIP type :%d", p_result->data.num);
1437       p_scb->clip[0] = 0;
1438       if (p_result->data.str[0] != 0)
1439         snprintf(p_scb->clip, sizeof(p_scb->clip), "%s,%d", p_result->data.str,
1440                  p_result->data.num);
1441
1442       /* send callsetup indicator */
1443       if (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END) {
1444         /* Need to sent 2 callsetup IND's(Call End and Incoming call) after SCO
1445          * close. */
1446         p_scb->post_sco = BTA_AG_POST_SCO_CALL_END_INCALL;
1447       } else {
1448         bta_ag_send_call_inds(p_scb, p_result->result);
1449
1450         /* if sco already opened or no inband ring send ring now */
1451         if (bta_ag_sco_is_open(p_scb) || !bta_ag_inband_enabled(p_scb) ||
1452             (p_scb->features & BTA_AG_FEAT_NOSCO)) {
1453           bta_ag_send_ring(p_scb, (tBTA_AG_DATA*)p_result);
1454         } else {
1455           /* else open sco, send ring after sco opened */
1456           p_scb->post_sco = BTA_AG_POST_SCO_RING;
1457           bta_ag_sco_open(p_scb, (tBTA_AG_DATA*)p_result);
1458         }
1459       }
1460       break;
1461
1462     case BTA_AG_IN_CALL_CONN_RES:
1463       alarm_cancel(p_scb->ring_timer);
1464
1465       /* if sco not opened and we need to open it, send indicators first
1466       ** then  open sco.
1467       */
1468       bta_ag_send_call_inds(p_scb, p_result->result);
1469
1470       if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
1471         if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
1472             !bta_ag_sco_is_open(p_scb)) {
1473           bta_ag_sco_open(p_scb, (tBTA_AG_DATA*)p_result);
1474         } else if ((p_result->data.audio_handle == BTA_AG_HANDLE_NONE) &&
1475                    bta_ag_sco_is_open(p_scb)) {
1476           bta_ag_sco_close(p_scb, (tBTA_AG_DATA*)p_result);
1477         }
1478       }
1479       break;
1480
1481     case BTA_AG_IN_CALL_HELD_RES:
1482       alarm_cancel(p_scb->ring_timer);
1483
1484       bta_ag_send_call_inds(p_scb, p_result->result);
1485
1486       break;
1487
1488     case BTA_AG_OUT_CALL_ORIG_RES:
1489       bta_ag_send_call_inds(p_scb, p_result->result);
1490       if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
1491           !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
1492         bta_ag_sco_open(p_scb, (tBTA_AG_DATA*)p_result);
1493       }
1494       break;
1495
1496     case BTA_AG_OUT_CALL_ALERT_RES:
1497       /* send indicators */
1498       bta_ag_send_call_inds(p_scb, p_result->result);
1499       if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
1500           !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
1501         bta_ag_sco_open(p_scb, (tBTA_AG_DATA*)p_result);
1502       }
1503       break;
1504
1505     case BTA_AG_MULTI_CALL_RES:
1506       /* open SCO at SLC for this three way call */
1507       APPL_TRACE_DEBUG("Headset Connected in three way call");
1508       if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
1509         if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb))
1510           bta_ag_sco_open(p_scb, (tBTA_AG_DATA*)p_result);
1511         else if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE)
1512           bta_ag_sco_close(p_scb, (tBTA_AG_DATA*)p_result);
1513       }
1514       break;
1515
1516     case BTA_AG_OUT_CALL_CONN_RES:
1517       /* send indicators */
1518       bta_ag_send_call_inds(p_scb, p_result->result);
1519
1520       /* open or close sco */
1521       if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) {
1522         if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb)) {
1523           bta_ag_sco_open(p_scb, (tBTA_AG_DATA*)p_result);
1524         } else if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE) {
1525           bta_ag_sco_close(p_scb, (tBTA_AG_DATA*)p_result);
1526         }
1527       }
1528       break;
1529
1530     case BTA_AG_CALL_CANCEL_RES:
1531       /* send indicators */
1532       bta_ag_send_call_inds(p_scb, p_result->result);
1533       break;
1534
1535     case BTA_AG_END_CALL_RES:
1536       alarm_cancel(p_scb->ring_timer);
1537
1538       /* if sco open, close sco then send indicator values */
1539       if ((bta_ag_sco_is_open(p_scb) || bta_ag_sco_is_opening(p_scb)) &&
1540           !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
1541         p_scb->post_sco = BTA_AG_POST_SCO_CALL_END;
1542         bta_ag_sco_close(p_scb, (tBTA_AG_DATA*)p_result);
1543       } else if (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END_INCALL) {
1544         /* sco closing for outgoing call because of incoming call */
1545         /* Send only callsetup end indicator after sco close */
1546         p_scb->post_sco = BTA_AG_POST_SCO_CALL_END;
1547       } else {
1548         bta_ag_send_call_inds(p_scb, p_result->result);
1549
1550         /* if av got suspended by this call, let it resume. */
1551         bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1552       }
1553       break;
1554
1555     case BTA_AG_INBAND_RING_RES:
1556       p_scb->inband_enabled = p_result->data.state;
1557       APPL_TRACE_DEBUG("inband_enabled set to %d", p_scb->inband_enabled);
1558       bta_ag_send_result(p_scb, p_result->result, NULL, p_result->data.state);
1559       break;
1560
1561     case BTA_AG_CIND_RES:
1562       /* store local values */
1563       p_scb->call_ind = p_result->data.str[0] - '0';
1564       p_scb->callsetup_ind = p_result->data.str[2] - '0';
1565       p_scb->service_ind = p_result->data.str[4] - '0';
1566       p_scb->signal_ind = p_result->data.str[6] - '0';
1567       p_scb->roam_ind = p_result->data.str[8] - '0';
1568       p_scb->battchg_ind = p_result->data.str[10] - '0';
1569       p_scb->callheld_ind = p_result->data.str[12] - '0';
1570       APPL_TRACE_DEBUG("cind call:%d callsetup:%d", p_scb->call_ind,
1571                        p_scb->callsetup_ind);
1572
1573       bta_ag_send_result(p_scb, p_result->result, p_result->data.str, 0);
1574       bta_ag_send_ok(p_scb);
1575       break;
1576
1577     case BTA_AG_BINP_RES:
1578     case BTA_AG_CNUM_RES:
1579     case BTA_AG_CLCC_RES:
1580     case BTA_AG_COPS_RES:
1581       if (p_result->data.ok_flag != BTA_AG_OK_ERROR) {
1582         if (p_result->data.str[0] != 0) {
1583           bta_ag_send_result(p_scb, p_result->result, p_result->data.str, 0);
1584         }
1585
1586         if (p_result->data.ok_flag == BTA_AG_OK_DONE) bta_ag_send_ok(p_scb);
1587       } else {
1588         bta_ag_send_error(p_scb, p_result->data.errcode);
1589       }
1590       break;
1591
1592     case BTA_AG_UNAT_RES:
1593       if (p_result->data.ok_flag != BTA_AG_OK_ERROR) {
1594         if (p_result->data.str[0] != 0) {
1595           bta_ag_process_unat_res(p_result->data.str);
1596           APPL_TRACE_DEBUG("BTA_AG_RES :%s", p_result->data.str);
1597           bta_ag_send_result(p_scb, p_result->result, p_result->data.str, 0);
1598         }
1599
1600         if (p_result->data.ok_flag == BTA_AG_OK_DONE) bta_ag_send_ok(p_scb);
1601       } else {
1602         bta_ag_send_error(p_scb, p_result->data.errcode);
1603       }
1604       break;
1605
1606     case BTA_AG_CALL_WAIT_RES:
1607       if (p_scb->ccwa_enabled) {
1608         bta_ag_send_result(p_scb, p_result->result, p_result->data.str, 0);
1609       }
1610       bta_ag_send_call_inds(p_scb, p_result->result);
1611       break;
1612
1613     case BTA_AG_IND_RES:
1614       bta_ag_send_ind(p_scb, p_result->data.ind.id, p_result->data.ind.value,
1615                       false);
1616       break;
1617
1618     case BTA_AG_BVRA_RES:
1619       bta_ag_send_result(p_scb, p_result->result, NULL, p_result->data.state);
1620       break;
1621
1622     case BTA_AG_BTRH_RES:
1623       if (p_result->data.ok_flag != BTA_AG_OK_ERROR) {
1624         /* Don't respond to read if not in response & hold state */
1625         if (p_result->data.num != BTA_AG_BTRH_NO_RESP) {
1626           bta_ag_send_result(p_scb, p_result->result, NULL, p_result->data.num);
1627         }
1628
1629         /* In case of a response to a read request we need to send OK */
1630         if (p_result->data.ok_flag == BTA_AG_OK_DONE) bta_ag_send_ok(p_scb);
1631       } else {
1632         bta_ag_send_error(p_scb, p_result->data.errcode);
1633       }
1634       break;
1635
1636     case BTA_AG_BIND_RES: {
1637       /* Find whether ind_id is supported by local device or not */
1638       int local_index = bta_ag_find_hf_ind_by_id(p_scb->local_hf_indicators,
1639                                                  BTA_AG_MAX_NUM_LOCAL_HF_IND,
1640                                                  p_result->data.ind.id);
1641       if (local_index == -1) {
1642         APPL_TRACE_WARNING("%s Invalid HF Indicator ID %d", __func__,
1643                            p_result->data.ind.id);
1644         return;
1645       }
1646
1647       /* Find whether ind_id is supported by peer device or not */
1648       int peer_index = bta_ag_find_hf_ind_by_id(p_scb->peer_hf_indicators,
1649                                                 BTA_AG_MAX_NUM_PEER_HF_IND,
1650                                                 p_result->data.ind.id);
1651       if (peer_index == -1) {
1652         APPL_TRACE_WARNING("%s Invalid HF Indicator ID %d", __func__,
1653                            p_result->data.ind.id);
1654         return;
1655       } else {
1656         /* If the current state is different from the one upper layer request
1657            change current state and send out the result */
1658         if (p_scb->local_hf_indicators[local_index].is_enable !=
1659             p_result->data.ind.on_demand) {
1660           char buffer[BTA_AG_AT_MAX_LEN] = {0};
1661           char* p = buffer;
1662
1663           p_scb->local_hf_indicators[local_index].is_enable =
1664               p_result->data.ind.on_demand;
1665           p += utl_itoa(p_result->data.ind.id, p);
1666           *p++ = ',';
1667           p += utl_itoa(p_scb->local_hf_indicators[local_index].is_enable, p);
1668
1669           bta_ag_send_result(p_scb, p_result->result, buffer, 0);
1670         } else {
1671           APPL_TRACE_DEBUG(
1672               "%s HF Indicator %d already %s", p_result->data.ind.id,
1673               (p_result->data.ind.on_demand == true) ? "Enabled" : "Disabled");
1674         }
1675       }
1676       break;
1677     }
1678
1679     default:
1680       break;
1681   }
1682 }
1683
1684 /*******************************************************************************
1685  *
1686  * Function         bta_ag_result
1687  *
1688  * Description      Handle API result.
1689  *
1690  *
1691  * Returns          void
1692  *
1693  ******************************************************************************/
1694 void bta_ag_result(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) {
1695   if (p_scb->conn_service == BTA_AG_HSP) {
1696     bta_ag_hsp_result(p_scb, &p_data->api_result);
1697   } else {
1698     bta_ag_hfp_result(p_scb, &p_data->api_result);
1699   }
1700 }
1701
1702 /*******************************************************************************
1703  *
1704  * Function         bta_ag_send_bcs
1705  *
1706  * Description      Send +BCS AT command to peer.
1707  *
1708  * Returns          void
1709  *
1710  ******************************************************************************/
1711 void bta_ag_send_bcs(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) {
1712   uint16_t codec_uuid;
1713
1714   if (p_scb->codec_fallback) {
1715     codec_uuid = UUID_CODEC_CVSD;
1716   } else {
1717     switch (p_scb->sco_codec) {
1718       case BTA_AG_CODEC_NONE:
1719         codec_uuid = UUID_CODEC_CVSD;
1720         break;
1721       case BTA_AG_CODEC_CVSD:
1722         codec_uuid = UUID_CODEC_CVSD;
1723         break;
1724       case BTA_AG_CODEC_MSBC:
1725         codec_uuid = UUID_CODEC_MSBC;
1726         break;
1727       default:
1728         APPL_TRACE_ERROR("bta_ag_send_bcs: unknown codec %d, use CVSD",
1729                          p_scb->sco_codec);
1730         codec_uuid = UUID_CODEC_CVSD;
1731         break;
1732     }
1733   }
1734
1735   /* send +BCS */
1736   APPL_TRACE_DEBUG("send +BCS codec is %d", codec_uuid);
1737   bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_BCS, NULL, codec_uuid);
1738 }
1739
1740 /*******************************************************************************
1741  *
1742  * Function         bta_ag_send_ring
1743  *
1744  * Description      Send RING result code to peer.
1745  *
1746  *
1747  * Returns          void
1748  *
1749  ******************************************************************************/
1750 void bta_ag_send_ring(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) {
1751   /* send RING */
1752   bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_RING, NULL, 0);
1753
1754   /* if HFP and clip enabled and clip data send CLIP */
1755   if (p_scb->conn_service == BTA_AG_HFP && p_scb->clip_enabled &&
1756       p_scb->clip[0] != 0) {
1757     bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_CLIP, p_scb->clip, 0);
1758   }
1759
1760   bta_sys_start_timer(p_scb->ring_timer, BTA_AG_RING_TIMEOUT_MS,
1761                       BTA_AG_RING_TIMEOUT_EVT, bta_ag_scb_to_idx(p_scb));
1762 }