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