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