OSDN Git Service

518ceb62c1d29befe11bd99d84b54240dd533d9d
[android-x86/system-bt.git] / bta / ag / bta_ag_cmd.c
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
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 indicator;
193     size_t result_code;
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_IN_CALL_CONN_RES,   BTA_AG_CALLSETUP_NONE},
201     {BTA_AG_CALL_WAIT_RES,      BTA_AG_CALLSETUP_INCOMING},
202     {BTA_AG_OUT_CALL_ORIG_RES,  BTA_AG_CALLSETUP_OUTGOING},
203     {BTA_AG_OUT_CALL_ALERT_RES, BTA_AG_CALLSETUP_ALERTING},
204     {BTA_AG_OUT_CALL_CONN_RES,  BTA_AG_CALLSETUP_NONE},
205     {BTA_AG_CALL_CANCEL_RES,    BTA_AG_CALLSETUP_NONE},
206     {BTA_AG_END_CALL_RES,       BTA_AG_CALLSETUP_NONE},
207     {BTA_AG_IN_CALL_HELD_RES,   BTA_AG_CALLSETUP_NONE},
208     {BTA_AG_BIND_RES,           BTA_AG_CALLSETUP_NONE}
209 };
210
211 static size_t bta_ag_indicator_by_result_code(size_t code)
212 {
213     for (size_t i = 0; i != sizeof(callsetup_indicator_map) /
214       sizeof(callsetup_indicator_map[0]); ++i)
215     {
216         if (code == callsetup_indicator_map[i].result_code)
217             return callsetup_indicator_map[i].indicator;
218     }
219     return BTA_AG_CALLSETUP_NONE;
220 }
221
222 /*******************************************************************************
223 **
224 ** Function         bta_ag_send_result
225 **
226 ** Description      Send an AT result code.
227 **
228 **
229 ** Returns          void
230 **
231 *******************************************************************************/
232 static void bta_ag_send_result(tBTA_AG_SCB *p_scb, size_t code, char *p_arg,
233                                INT16 int_arg)
234 {
235     const tBTA_AG_RESULT *result = bta_ag_result_by_code(code);
236     if (result == 0)
237     {
238         LOG_ERROR(LOG_TAG, "%s Unable to lookup result for code %zu", __func__, code);
239         return;
240     }
241
242     char buf[BTA_AG_AT_MAX_LEN + 16];
243     char *p = buf;
244     memset(buf, 0, sizeof(buf));
245
246     /* init with \r\n */
247     *p++ = '\r';
248     *p++ = '\n';
249
250     /* copy result code string */
251     strlcpy(p, result->result_string, sizeof(buf) - 2);
252
253     if (p_scb->conn_service == BTA_AG_HSP)
254     {
255         /* If HSP then ":"symbol should be changed as "=" for HSP compatibility */
256         switch(code)
257         {
258         case BTA_AG_SPK_RES:
259         case BTA_AG_MIC_RES:
260             if(*(p+COLON_IDX_4_VGSVGM) == ':')
261             {
262                 *(p+COLON_IDX_4_VGSVGM) = '=';
263             }
264             break;
265         }
266     }
267
268     p += strlen(result->result_string);
269
270     /* copy argument if any */
271     if (result->arg_type == BTA_AG_RES_FMT_INT)
272     {
273         p += utl_itoa((UINT16) int_arg, p);
274     }
275     else if (result->arg_type == BTA_AG_RES_FMT_STR)
276     {
277         strcpy(p, p_arg);
278         p += strlen(p_arg);
279     }
280
281     /* finish with \r\n */
282     *p++ = '\r';
283     *p++ = '\n';
284
285     /* send to RFCOMM */
286     UINT16 len = 0;
287     PORT_WriteData(p_scb->conn_handle, buf, (UINT16) (p - buf), &len);
288 }
289
290 /*******************************************************************************
291 **
292 ** Function         bta_ag_send_ok
293 **
294 ** Description      Send an OK result code.
295 **
296 **
297 ** Returns          void
298 **
299 *******************************************************************************/
300 static void bta_ag_send_ok(tBTA_AG_SCB *p_scb)
301 {
302     bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_OK, NULL, 0);
303 }
304
305 /*******************************************************************************
306 **
307 ** Function         bta_ag_send_error
308 **
309 ** Description      Send an ERROR result code.
310 **                      errcode - used to send verbose errocode
311 **
312 **
313 ** Returns          void
314 **
315 *******************************************************************************/
316 static void bta_ag_send_error(tBTA_AG_SCB *p_scb, INT16 errcode)
317 {
318     /* If HFP and extended audio gateway error codes are enabled */
319     if (p_scb->conn_service == BTA_AG_HFP && p_scb->cmee_enabled)
320         bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_CMEE, NULL, errcode);
321     else
322         bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_ERROR, NULL, 0);
323 }
324
325 /*******************************************************************************
326 **
327 ** Function         bta_ag_send_ind
328 **
329 ** Description      Send an indicator CIEV result code.
330 **
331 **
332 ** Returns          void
333 **
334 *******************************************************************************/
335 static void bta_ag_send_ind(tBTA_AG_SCB *p_scb, UINT16 id, UINT16 value, BOOLEAN on_demand)
336 {
337     char    str[12];
338     char    *p = str;
339
340     /* If the indicator is masked out, just return */
341     /* Mandatory indicators can not be masked out. */
342     if ((p_scb->bia_masked_out & ((UINT32)1 << id)) &&
343         ((id != BTA_AG_IND_CALL) && (id != BTA_AG_IND_CALLSETUP) && (id != BTA_AG_IND_CALLHELD)))
344         return;
345
346     /* Ensure we do not send duplicate indicators if not requested by app */
347     /* If it was requested by app, transmit CIEV even if it is duplicate. */
348     if (id == BTA_AG_IND_CALL)
349     {
350         if ((value == p_scb->call_ind) && (on_demand == FALSE))
351             return;
352
353         p_scb->call_ind = (UINT8)value;
354     }
355
356     if ((id == BTA_AG_IND_CALLSETUP) && (on_demand == FALSE))
357     {
358         if (value == p_scb->callsetup_ind)
359             return;
360
361         p_scb->callsetup_ind = (UINT8)value;
362     }
363
364     if ((id == BTA_AG_IND_SERVICE) && (on_demand == FALSE))
365     {
366         if (value == p_scb->service_ind)
367             return;
368
369         p_scb->service_ind = (UINT8)value;
370     }
371     if ((id == BTA_AG_IND_SIGNAL) && (on_demand == FALSE))
372     {
373         if (value == p_scb->signal_ind)
374             return;
375
376         p_scb->signal_ind = (UINT8)value;
377     }
378     if ((id == BTA_AG_IND_ROAM) && (on_demand == FALSE))
379     {
380         if (value == p_scb->roam_ind)
381             return;
382
383         p_scb->roam_ind = (UINT8)value;
384     }
385     if ((id == BTA_AG_IND_BATTCHG) && (on_demand == FALSE))
386     {
387         if (value == p_scb->battchg_ind)
388             return;
389
390         p_scb->battchg_ind = (UINT8)value;
391     }
392
393     if ((id == BTA_AG_IND_CALLHELD) && (on_demand == FALSE))
394     {
395         /* call swap could result in sending callheld=1 multiple times */
396         if ((value != 1) && (value == p_scb->callheld_ind))
397             return;
398
399         p_scb->callheld_ind = (UINT8)value;
400     }
401
402     if (p_scb->cmer_enabled)
403     {
404         p += utl_itoa(id, p);
405         *p++ = ',';
406         utl_itoa(value, p);
407         bta_ag_send_result(p_scb, BTA_AG_IND_RES, str, 0);
408     }
409 }
410
411 /*******************************************************************************
412 **
413 ** Function         bta_ag_parse_cmer
414 **
415 ** Description      Parse AT+CMER parameter string.
416 **
417 **
418 ** Returns          TRUE if parsed ok, FALSE otherwise.
419 **
420 *******************************************************************************/
421 static BOOLEAN bta_ag_parse_cmer(char *p_s, BOOLEAN *p_enabled)
422 {
423     INT16   n[4] = {-1, -1, -1, -1};
424     int     i;
425     char    *p;
426
427     for (i = 0; i < 4; i++)
428     {
429         /* skip to comma delimiter */
430         for (p = p_s; *p != ',' && *p != 0; p++);
431
432         /* get integer value */
433         *p = 0;
434         n[i] = utl_str2int(p_s);
435         p_s = p + 1;
436         if (p_s == 0)
437         {
438             break;
439         }
440     }
441
442     /* process values */
443     if (n[0] < 0 || n[3] < 0)
444     {
445         return FALSE;
446     }
447
448     if ((n[0] == 3) && ((n[3] == 1) || (n[3] == 0)))
449     {
450         *p_enabled = (BOOLEAN) n[3];
451     }
452
453     return TRUE;
454 }
455
456 /*******************************************************************************
457 **
458 ** Function         bta_ag_parse_chld
459 **
460 ** Description      Parse AT+CHLD parameter string.
461 **
462 **
463 ** Returns          Returns idx (1-7), 0 if ECC not enabled or BTA_AG_INVALID_CHLD
464                     if idx doesn't exist/1st character of argument is not a digit
465 **
466 *******************************************************************************/
467 static UINT8 bta_ag_parse_chld(tBTA_AG_SCB *p_scb, char *p_s)
468 {
469     UINT8   retval = 0;
470     INT16   idx = -1;
471     UNUSED(p_scb);
472
473     if (!isdigit(p_s[0]))
474     {
475         return BTA_AG_INVALID_CHLD;
476     }
477
478     if (p_s[1] != 0)
479     {
480         /* p_idxstr++;  point to beginning of call number */
481         idx = utl_str2int(&p_s[1]);
482         if (idx != -1 && idx < 255)
483         {
484             retval = (UINT8)idx;
485         }
486         else
487         {
488             retval = BTA_AG_INVALID_CHLD;
489         }
490     }
491
492     return (retval);
493 }
494
495 #if (BTM_WBS_INCLUDED == TRUE )
496 /*******************************************************************************
497 **
498 ** Function         bta_ag_parse_bac
499 **
500 ** Description      Parse AT+BAC parameter string.
501 **
502 ** Returns          Returns bitmap of supported codecs.
503 **
504 *******************************************************************************/
505 static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB *p_scb, char *p_s)
506 {
507     tBTA_AG_PEER_CODEC  retval = BTA_AG_CODEC_NONE;
508     UINT16  uuid_codec;
509     BOOLEAN cont = FALSE;       /* Continue processing */
510     char *p;
511
512     while(p_s)
513     {
514         /* skip to comma delimiter */
515         for(p = p_s; *p != ',' && *p != 0; p++);
516
517         /* get integre value */
518         if (*p != 0)
519         {
520             *p = 0;
521             cont = TRUE;
522         }
523         else
524             cont = FALSE;
525
526         uuid_codec = utl_str2int(p_s);
527         switch(uuid_codec)
528         {
529             case UUID_CODEC_CVSD:   retval |= BTA_AG_CODEC_CVSD;     break;
530             case UUID_CODEC_MSBC:   retval |= BTA_AG_CODEC_MSBC;     break;
531             default:
532                 APPL_TRACE_ERROR("Unknown Codec UUID(%d) received", uuid_codec);
533                 break;
534         }
535
536         if (cont)
537             p_s = p + 1;
538         else
539             break;
540     }
541
542     return (retval);
543 }
544 #endif
545
546 /*******************************************************************************
547 **
548 ** Function         bta_ag_process_unat_res
549 **
550 ** Description      Process the unat response data and remove extra carriage return
551 **                  and line feed
552 **
553 **
554 ** Returns          void
555 **
556 *******************************************************************************/
557
558 static void bta_ag_process_unat_res(char *unat_result)
559 {
560     UINT8   str_leng;
561     UINT8   i = 0;
562     UINT8   j = 0;
563     UINT8   pairs_of_nl_cr;
564     char    trim_data[BTA_AG_AT_MAX_LEN];
565
566
567
568     str_leng = strlen(unat_result);
569
570     /* If no extra CR and LF, just return */
571     if(str_leng < 4)
572         return;
573
574     /* Remove the carriage return and left feed */
575     while(unat_result[0] =='\r' && unat_result[1] =='\n'
576         && unat_result[str_leng-2] =='\r' && unat_result[str_leng-1] =='\n')
577     {
578         pairs_of_nl_cr = 1;
579         for (i=0;i<(str_leng-4*pairs_of_nl_cr);i++)
580         {
581             trim_data[j++] = unat_result[i+pairs_of_nl_cr*2];
582         }
583         /* Add EOF */
584         trim_data[j] = '\0';
585         str_leng = str_leng - 4;
586         strlcpy(unat_result, trim_data, str_leng+1);
587         i=0;
588         j=0;
589
590         if(str_leng <4)
591             return;
592
593
594     }
595     return;
596 }
597
598
599 /*******************************************************************************
600 **
601 ** Function         bta_ag_inband_enabled
602 **
603 ** Description      Determine whether in-band ring can be used.
604 **
605 **
606 ** Returns          void
607 **
608 *******************************************************************************/
609 BOOLEAN bta_ag_inband_enabled(tBTA_AG_SCB *p_scb)
610 {
611     /* if feature is enabled and no other scbs connected */
612     if (p_scb->inband_enabled && !bta_ag_other_scb_open(p_scb))
613     {
614         return TRUE;
615     }
616     else
617     {
618         return FALSE;
619     }
620 }
621
622 /*******************************************************************************
623 **
624 ** Function         bta_ag_send_call_inds
625 **
626 ** Description      Send call and callsetup indicators.
627 **
628 **
629 ** Returns          void
630 **
631 *******************************************************************************/
632 void bta_ag_send_call_inds(tBTA_AG_SCB *p_scb, tBTA_AG_RES result)
633 {
634     UINT8 call = p_scb->call_ind;
635
636     /* set new call and callsetup values based on BTA_AgResult */
637     size_t callsetup = bta_ag_indicator_by_result_code(result);
638
639     if (result == BTA_AG_END_CALL_RES)
640     {
641         call = BTA_AG_CALL_INACTIVE;
642     }
643     else if (result == BTA_AG_IN_CALL_CONN_RES || result == BTA_AG_OUT_CALL_CONN_RES
644              || result == BTA_AG_IN_CALL_HELD_RES)
645     {
646         call = BTA_AG_CALL_ACTIVE;
647     }
648     else
649     {
650         call = p_scb->call_ind;
651     }
652
653     /* Send indicator function tracks if the values have actually changed */
654     bta_ag_send_ind(p_scb, BTA_AG_IND_CALL, call, FALSE);
655     bta_ag_send_ind(p_scb, BTA_AG_IND_CALLSETUP, callsetup, FALSE);
656 }
657
658 /*******************************************************************************
659 **
660 ** Function         bta_ag_at_hsp_cback
661 **
662 ** Description      AT command processing callback for HSP.
663 **
664 **
665 ** Returns          void
666 **
667 *******************************************************************************/
668 void bta_ag_at_hsp_cback(tBTA_AG_SCB *p_scb, UINT16 command_id, UINT8 arg_type,
669                                 char *p_arg, INT16 int_arg)
670 {
671     APPL_TRACE_DEBUG("AT cmd:%d arg_type:%d arg:%d arg:%s", command_id, arg_type,
672                       int_arg, p_arg);
673
674     bta_ag_send_ok(p_scb);
675
676     tBTA_AG_VAL val;
677     val.hdr.handle = bta_ag_scb_to_idx(p_scb);
678     val.hdr.app_id = p_scb->app_id;
679     val.num = (UINT16) int_arg;
680     strlcpy(val.str, p_arg, BTA_AG_AT_MAX_LEN);
681
682     /* call callback with event */
683     (*bta_ag_cb.p_cback)(command_id, (tBTA_AG *) &val);
684 }
685
686 /*******************************************************************************
687 **
688 ** Function         bta_ag_find_empty_hf_ind)
689 **
690 ** Description      This function returns the index of an empty HF indicator
691 **                  structure.
692 **
693 ** Returns          int : index of the empty HF indicator structure or
694 **                            -1 if no empty indicator
695 **                            is available.
696 **
697 *******************************************************************************/
698 static int bta_ag_find_empty_hf_ind(tBTA_AG_SCB *p_scb)
699 {
700     for (int index = 0; index < BTA_AG_MAX_NUM_PEER_HF_IND; index++)
701     {
702         if (p_scb->peer_hf_indicators[index].ind_id == 0)
703             return index;
704     }
705
706     return -1;
707 }
708
709
710 /*******************************************************************************
711 **
712 ** Function         bta_ag_find_hf_ind_by_id
713 **
714 ** Description      This function returns the index of the HF indicator
715 **                  structure by the indicator id
716 **
717 ** Returns          int : index of the HF indicator structure
718 **                            -1 if the indicator
719 **                            was not found.
720 **
721 *******************************************************************************/
722 static int bta_ag_find_hf_ind_by_id(tBTA_AG_HF_IND *p_hf_ind, int size, uint32_t ind_id)
723 {
724     for (int index = 0; index < size; index++)
725     {
726         if (p_hf_ind[index].ind_id == ind_id)
727             return index;
728     }
729
730     return -1;
731 }
732
733 /*******************************************************************************
734 **
735 ** Function         bta_ag_parse_bind_set
736 **
737 ** Description      Parse AT+BIND set command and save the indicators
738 **
739 ** Returns          true if successful
740 **
741 *******************************************************************************/
742 static bool bta_ag_parse_bind_set(tBTA_AG_SCB *p_scb, tBTA_AG_VAL val)
743 {
744     char *p_token = strtok(val.str, ",");
745     if (p_token == NULL)
746         return false;
747
748     while (p_token != NULL)
749     {
750         uint16_t rcv_ind_id = atoi(p_token);
751         int index = bta_ag_find_empty_hf_ind(p_scb);
752         if (index == -1)
753         {
754             APPL_TRACE_WARNING("%s Can't save more indicators", __func__);
755             return false;
756         }
757
758         p_scb->peer_hf_indicators[index].ind_id = rcv_ind_id;
759         APPL_TRACE_DEBUG("%s peer_hf_ind[%d] = %d", __func__, index, rcv_ind_id);
760
761         p_token = strtok(NULL, ",");
762     }
763
764     return true;
765 }
766
767 /*******************************************************************************
768 **
769 ** Function         bta_ag_bind_response
770 **
771 ** Description      Send response for the AT+BIND command (HFP 1.7) received
772 **                  from the headset based on the argument types.
773 **
774 ** Returns          Void
775 **
776 *******************************************************************************/
777 static void bta_ag_bind_response(tBTA_AG_SCB *p_scb, uint8_t arg_type)
778 {
779     char buffer[BTA_AG_AT_MAX_LEN];
780     memset(buffer, 0, BTA_AG_AT_MAX_LEN);
781
782     if (arg_type == BTA_AG_AT_TEST)
783     {
784         int index = 0;
785         buffer[index++] = '(';
786
787         for (uint32_t i = 0; i < bta_ag_local_hf_ind_cfg[0].ind_id; i++)
788         {
789             if (bta_ag_local_hf_ind_cfg[i+1].is_supported == true)
790             {
791                 /* Add ',' from second indicator */
792                 if (index > 1)
793                     buffer[index++] = ',';
794                 sprintf(&buffer[index++], "%d", bta_ag_local_hf_ind_cfg[i+1].ind_id);
795             }
796         }
797
798         buffer[index++] = ')';
799
800         bta_ag_send_result(p_scb, BTA_AG_BIND_RES, buffer, 0);
801         bta_ag_send_ok(p_scb);
802     }
803     else if (arg_type == BTA_AG_AT_READ)
804     {
805         char *p = buffer;
806
807         /* bta_ag_local_hf_ind_cfg[0].ind_id is used as BTA_AG_NUM_LOCAL_HF_IND */
808         for (uint32_t i = 0; i < bta_ag_local_hf_ind_cfg[0].ind_id; i++)
809         {
810             if (i == BTA_AG_MAX_NUM_LOCAL_HF_IND)
811             {
812                 APPL_TRACE_WARNING("%s No space for more HF indicators", __func__);
813                 break;
814             }
815
816             p_scb->local_hf_indicators[i].ind_id = bta_ag_local_hf_ind_cfg[i+1].ind_id;
817             p_scb->local_hf_indicators[i].is_supported = bta_ag_local_hf_ind_cfg[i+1].is_supported;
818             p_scb->local_hf_indicators[i].is_enable = bta_ag_local_hf_ind_cfg[i+1].is_enable;
819
820             int peer_index = bta_ag_find_hf_ind_by_id(p_scb->peer_hf_indicators,
821                                                     BTA_AG_MAX_NUM_PEER_HF_IND,
822                                                     p_scb->local_hf_indicators[i].ind_id);
823
824             /* Check whether local and peer sides support this indicator */
825             if (p_scb->local_hf_indicators[i].is_supported == true && peer_index != -1)
826             {
827                 /* In the format of ind, state */
828                 p += utl_itoa((uint16_t) p_scb->local_hf_indicators[i].ind_id, p);
829                 *p++ = ',';
830                 p += utl_itoa((uint16_t) p_scb->local_hf_indicators[i].is_enable, p);
831
832                 bta_ag_send_result(p_scb, BTA_AG_BIND_RES, buffer, 0);
833
834                 memset(buffer, 0, sizeof(buffer));
835                 p = buffer;
836             } else {
837                 /* If indicator is not supported, also set it to disable */
838                 p_scb->local_hf_indicators[i].is_enable = false;
839             }
840         }
841
842         bta_ag_send_ok(p_scb);
843
844         /* If the service level connection wan't already open, now it's open */
845         if (!p_scb->svc_conn)
846             bta_ag_svc_conn_open(p_scb, NULL);
847     }
848 }
849
850 /*******************************************************************************
851 **
852 ** Function         bta_ag_parse_biev_response
853 **
854 ** Description      Send response for AT+BIEV command (HFP 1.7) received from
855 **                  the headset based on the argument types.
856 **
857 ** Returns          true if the response was parsed successfully
858 **
859 *******************************************************************************/
860 static bool bta_ag_parse_biev_response(tBTA_AG_SCB *p_scb, tBTA_AG_VAL *val)
861 {
862     char *p_token = strtok(val->str, ",");
863     uint16_t rcv_ind_id = atoi(p_token);
864
865     p_token = strtok(NULL, ",");
866     uint16_t rcv_ind_val = atoi(p_token);
867
868     APPL_TRACE_DEBUG("%s BIEV indicator id %d, value %d", __func__, rcv_ind_id, rcv_ind_val);
869
870     /* Check whether indicator ID is valid or not */
871     if (rcv_ind_id > BTA_AG_NUM_LOCAL_HF_IND)
872     {
873         APPL_TRACE_WARNING("%s received invalid indicator id %d", __func__, rcv_ind_id);
874         return false;
875     }
876
877     /* Check this indicator is support or not and enabled or not */
878     int local_index = bta_ag_find_hf_ind_by_id(p_scb->local_hf_indicators,
879                                 BTA_AG_MAX_NUM_LOCAL_HF_IND, rcv_ind_id);
880     if (local_index == -1 ||
881         p_scb->local_hf_indicators[local_index].is_supported != true ||
882         p_scb->local_hf_indicators[local_index].is_enable != true)
883     {
884         APPL_TRACE_WARNING("%s indicator id %d not supported or disabled", __func__, rcv_ind_id);
885         return false;
886     }
887
888     /* For each indicator ID, check whether the indicator value is in range */
889     if (rcv_ind_val < bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_min_val ||
890         rcv_ind_val > bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_max_val)
891     {
892         APPL_TRACE_WARNING("%s invalid ind_val %d", __func__, rcv_ind_val);
893         return false;
894     }
895
896     val->lidx = rcv_ind_id;
897     val->num = rcv_ind_val;
898
899     return true;
900 }
901
902 /*******************************************************************************
903 **
904 ** Function         bta_ag_at_hfp_cback
905 **
906 ** Description      AT command processing callback for HFP.
907 **
908 **
909 ** Returns          void
910 **
911 *******************************************************************************/
912 void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
913                                 char *p_arg, INT16 int_arg)
914 {
915     tBTA_AG_VAL     val;
916     tBTA_AG_SCB     *ag_scb;
917     UINT32          i, ind_id;
918     UINT32          bia_masked_out;
919 #if (BTM_WBS_INCLUDED == TRUE )
920     tBTA_AG_PEER_CODEC  codec_type, codec_sent;
921 #endif
922     if (p_arg == NULL)
923     {
924         APPL_TRACE_ERROR("%s: p_arg is null, send error and return", __func__);
925         bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
926         return;
927     }
928
929     APPL_TRACE_DEBUG("HFP AT cmd:%d arg_type:%d arg:%d arg:%s", cmd, arg_type,
930                       int_arg, p_arg);
931
932     val.hdr.handle = bta_ag_scb_to_idx(p_scb);
933     val.hdr.app_id = p_scb->app_id;
934     val.hdr.status = BTA_AG_SUCCESS;
935     val.num = int_arg;
936     bdcpy(val.bd_addr, p_scb->peer_addr);
937     strlcpy(val.str, p_arg, BTA_AG_AT_MAX_LEN);
938
939     /**
940      * Unless this this is a local event, by default we'll forward
941      * the event code to the application.
942      * If |event| is 0 at the end of this function, the application
943      * callback is NOT invoked.
944      */
945     tBTA_AG_EVT event = 0;
946     if (cmd < BTA_AG_LOCAL_EVT_FIRST)
947         event = cmd;
948
949     switch (cmd)
950     {
951         case BTA_AG_AT_A_EVT:
952         case BTA_AG_SPK_EVT:
953         case BTA_AG_MIC_EVT:
954         case BTA_AG_AT_CHUP_EVT:
955         case BTA_AG_AT_CBC_EVT:
956             /* send OK */
957             bta_ag_send_ok(p_scb);
958             break;
959
960         case BTA_AG_AT_BLDN_EVT:
961             /* Do not send OK, App will send error or OK depending on
962             ** last dial number enabled or not */
963             break;
964
965         case BTA_AG_AT_D_EVT:
966             /* Do not send OK for Dial cmds
967             ** Let application decide whether to send OK or ERROR*/
968
969             /* if mem dial cmd, make sure string contains only digits */
970             if(p_arg[0] == '>')
971             {
972                 if(!utl_isintstr(p_arg+1))
973                 {
974                     event = 0;
975                     bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR);
976                 }
977             }
978             else if (p_arg[0] == 'V')   /* ATDV : Dial VoIP Call */
979             {
980                 /* We do not check string. Code will be added later if needed. */
981                 if(!((p_scb->peer_features & BTA_AG_PEER_FEAT_VOIP) && (p_scb->features & BTA_AG_FEAT_VOIP)))
982                 {
983                     event = 0;
984                     bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
985                 }
986             }
987             /* If dial cmd, make sure string contains only dial digits
988             ** Dial digits are 0-9, A-C, *, #, + */
989             else
990             {
991                 if(!utl_isdialstr(p_arg))
992                 {
993                     event = 0;
994                     bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR);
995                 }
996             }
997             break;
998
999         case BTA_AG_LOCAL_EVT_CCWA:
1000             /* store setting */
1001             p_scb->ccwa_enabled = (BOOLEAN) int_arg;
1002
1003             /* send OK */
1004             bta_ag_send_ok(p_scb);
1005             break;
1006
1007         case BTA_AG_AT_CHLD_EVT:
1008             if (arg_type == BTA_AG_AT_TEST)
1009             {
1010                 /* don't call callback */
1011                 event = 0;
1012
1013                 /* send CHLD string */
1014                 /* Form string based on supported 1.5 feature */
1015                 if ((p_scb->peer_version >= HFP_VERSION_1_5) &&
1016                     (p_scb->features & BTA_AG_FEAT_ECC) &&
1017                     (p_scb->peer_features & BTA_AG_PEER_FEAT_ECC))
1018                     bta_ag_send_result(p_scb, BTA_AG_IN_CALL_HELD_RES,
1019                                        p_bta_ag_cfg->chld_val_ecc, 0);
1020                 else
1021                     bta_ag_send_result(p_scb, BTA_AG_IN_CALL_HELD_RES,
1022                                        p_bta_ag_cfg->chld_val, 0);
1023
1024                 /* send OK */
1025                 bta_ag_send_ok(p_scb);
1026
1027                 /* if service level conn. not already open, now it's open */
1028                 bta_ag_svc_conn_open(p_scb, NULL);
1029             }
1030             else
1031             {
1032                 val.idx = bta_ag_parse_chld(p_scb, val.str);
1033
1034                 if (val.idx == BTA_AG_INVALID_CHLD)
1035                 {
1036                     event = 0;
1037                     bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1038                     break;
1039                 }
1040                 if(val.idx && !((p_scb->features & BTA_AG_FEAT_ECC) && (p_scb->peer_features & BTA_AG_PEER_FEAT_ECC)))
1041                 {
1042                     /* we do not support ECC, but HF is sending us a CHLD with call index*/
1043                     event = 0;
1044                     bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1045
1046                 }
1047                 else
1048                 {
1049
1050                 /* If it is swap between calls, set call held indicator to 3(out of valid 0-2)
1051                 ** Application will set it back to 1
1052                 ** callheld indicator will be sent across to the peer. */
1053                 if(val.str[0] == '2')
1054                 {
1055                     for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, ag_scb++)
1056                     {
1057                         if (ag_scb->in_use)
1058                         {
1059                             if((ag_scb->call_ind == BTA_AG_CALL_ACTIVE)
1060                                 && (ag_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE))
1061                                 ag_scb->callheld_ind = BTA_AG_CALLHELD_NOACTIVE + 1;
1062                         }
1063                     }
1064                 }
1065                 }
1066
1067                 /* Do not send OK. Let app decide after parsing the val str */
1068                 /* bta_ag_send_ok(p_scb); */
1069             }
1070             break;
1071
1072         case BTA_AG_AT_BIND_EVT:
1073             APPL_TRACE_DEBUG("%s BTA_AG_AT_BIND_EVT arg_type: %d", __func__, arg_type);
1074             if (arg_type == BTA_AG_AT_SET)
1075             {
1076                 if (bta_ag_parse_bind_set(p_scb, val))
1077                 {
1078                     bta_ag_send_ok(p_scb);
1079                 } else {
1080                     event = 0;/* don't call callback */
1081                     bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
1082                 }
1083             } else {
1084                 bta_ag_bind_response(p_scb, arg_type);
1085
1086                 /* Need not pass this command beyond BTIF.*/
1087                 /* Stack handles it internally */
1088                 event = 0;/* don't call callback */
1089             }
1090             break;
1091
1092         case BTA_AG_AT_BIEV_EVT:
1093             if (bta_ag_parse_biev_response(p_scb, &val))
1094             {
1095                 bta_ag_send_ok(p_scb);
1096             } else {
1097                 bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
1098                 /* don't call callback receiving invalid indicator */
1099                 event = 0;
1100             }
1101             break;
1102
1103         case BTA_AG_AT_CIND_EVT:
1104             if (arg_type == BTA_AG_AT_TEST)
1105             {
1106                 /* don't call callback */
1107                 event = 0;
1108
1109                 /* send CIND string, send OK */
1110                 bta_ag_send_result(p_scb, BTA_AG_CIND_RES, p_bta_ag_cfg->cind_info, 0);
1111                 bta_ag_send_ok(p_scb);
1112             }
1113             break;
1114
1115         case BTA_AG_LOCAL_EVT_CLIP:
1116             /* store setting, send OK */
1117             p_scb->clip_enabled = (BOOLEAN) int_arg;
1118             bta_ag_send_ok(p_scb);
1119             break;
1120
1121         case BTA_AG_LOCAL_EVT_CMER:
1122             /* if parsed ok store setting, send OK */
1123             if (bta_ag_parse_cmer(p_arg, &p_scb->cmer_enabled))
1124             {
1125                 bta_ag_send_ok(p_scb);
1126
1127                 /* if service level conn. not already open and our features and
1128                 ** peer features do not have 3-way, service level conn. now open
1129                 */
1130                 if (!p_scb->svc_conn &&
1131                     !((p_scb->features & BTA_AG_FEAT_3WAY) && (p_scb->peer_features & BTA_AG_PEER_FEAT_3WAY)))
1132                 {
1133                     bta_ag_svc_conn_open(p_scb, NULL);
1134                 }
1135             }
1136             else
1137             {
1138                 bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
1139             }
1140             break;
1141
1142         case BTA_AG_AT_VTS_EVT:
1143             /* check argument */
1144             if (strlen(p_arg) == 1)
1145             {
1146                 bta_ag_send_ok(p_scb);
1147             }
1148             else
1149             {
1150                 event = 0;
1151                 bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
1152             }
1153             break;
1154
1155         case BTA_AG_AT_BINP_EVT:
1156             /* if feature not set don't call callback, send ERROR */
1157             if (!(p_scb->features & BTA_AG_FEAT_VTAG))
1158             {
1159                 event = 0;
1160                 bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1161             }
1162             break;
1163
1164         case BTA_AG_AT_BVRA_EVT:
1165             /* if feature not supported don't call callback, send ERROR. App will send OK */
1166             if (!(p_scb->features & BTA_AG_FEAT_VREC))
1167             {
1168                 event = 0;
1169                 bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1170             }
1171             break;
1172
1173         case BTA_AG_LOCAL_EVT_BRSF:
1174             /* store peer features */
1175             p_scb->peer_features = (uint16_t) int_arg;
1176 #if (BTA_HFP_VERSION < HFP_VERSION_1_7 || BTA_HFP_HF_IND_SUPPORTED != true)
1177             p_scb->features &= ~BTA_AG_FEAT_HF_IND;
1178 #endif
1179             APPL_TRACE_DEBUG("%s BRSF HF: 0x%x, phone: 0x%x", __func__,
1180                 p_scb->peer_features, p_scb->features);
1181
1182             /* send BRSF, send OK */
1183             bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_BRSF, NULL,
1184                                (INT16) (p_scb->features & BTA_AG_BSRF_FEAT_SPEC));
1185             bta_ag_send_ok(p_scb);
1186             break;
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 *******************************************************************************/
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 *******************************************************************************/
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 *******************************************************************************/
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 *******************************************************************************/
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 *******************************************************************************/
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 *******************************************************************************/
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 }