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