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