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