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