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