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