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