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