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