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