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