• 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             bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1250             break;
1251     }
1252 
1253     /* call callback */
1254     if (event != 0)
1255     {
1256         (*bta_ag_cb.p_cback)(event, (tBTA_AG *) &val);
1257     }
1258 }
1259 
1260 /*******************************************************************************
1261 **
1262 ** Function         bta_ag_at_err_cback
1263 **
1264 ** Description      AT command parser error callback.
1265 **
1266 **
1267 ** Returns          void
1268 **
1269 *******************************************************************************/
bta_ag_at_err_cback(tBTA_AG_SCB * p_scb,BOOLEAN unknown,char * p_arg)1270 void bta_ag_at_err_cback(tBTA_AG_SCB *p_scb, BOOLEAN unknown, char *p_arg)
1271 {
1272     tBTA_AG_VAL     val;
1273 
1274     if(unknown && (!strlen(p_arg)))
1275     {
1276         APPL_TRACE_DEBUG0("Empty AT cmd string received");
1277         bta_ag_send_ok(p_scb);
1278         return;
1279     }
1280 
1281     /* if unknown AT command and configured to pass these to app */
1282     if (unknown && (p_scb->features & BTA_AG_FEAT_UNAT))
1283     {
1284         val.hdr.handle = bta_ag_scb_to_idx(p_scb);
1285         val.hdr.app_id = p_scb->app_id;
1286         val.num = 0;
1287         BCM_STRNCPY_S(val.str, sizeof(val.str), p_arg, BTA_AG_AT_MAX_LEN);
1288         val.str[BTA_AG_AT_MAX_LEN] = 0;
1289         (*bta_ag_cb.p_cback)(BTA_AG_AT_UNAT_EVT, (tBTA_AG *) &val);
1290     }
1291     else
1292     {
1293         bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
1294     }
1295 }
1296 
1297 /*******************************************************************************
1298 **
1299 ** Function         bta_ag_hsp_result
1300 **
1301 ** Description      Handle API result for HSP connections.
1302 **
1303 **
1304 ** Returns          void
1305 **
1306 *******************************************************************************/
bta_ag_hsp_result(tBTA_AG_SCB * p_scb,tBTA_AG_API_RESULT * p_result)1307 void bta_ag_hsp_result(tBTA_AG_SCB *p_scb, tBTA_AG_API_RESULT *p_result)
1308 {
1309     UINT8 code = bta_ag_trans_result[p_result->result];
1310 
1311     APPL_TRACE_DEBUG1("bta_ag_hsp_result : res = %d", p_result->result);
1312 
1313     switch(p_result->result)
1314     {
1315         case BTA_AG_SPK_RES:
1316         case BTA_AG_MIC_RES:
1317             bta_ag_send_result(p_scb, code, NULL, p_result->data.num);
1318             break;
1319 
1320         case BTA_AG_IN_CALL_RES:
1321             /* tell sys to stop av if any */
1322             bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1323 
1324             /* if sco already opened or no inband ring send ring now */
1325             if (bta_ag_sco_is_open(p_scb) || !bta_ag_inband_enabled(p_scb) ||
1326                 (p_scb->features & BTA_AG_FEAT_NOSCO))
1327             {
1328                 bta_ag_send_ring(p_scb, (tBTA_AG_DATA *) p_result);
1329             }
1330             /* else open sco, send ring after sco opened */
1331             else
1332             {
1333                 /* HSPv1.2: AG shall not send RING if using in-band ring tone. */
1334                 if (p_scb->hsp_version >= HSP_VERSION_1_2)
1335                     p_scb->post_sco = BTA_AG_POST_SCO_NONE;
1336                 else
1337                     p_scb->post_sco = BTA_AG_POST_SCO_RING;
1338 
1339                 bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
1340             }
1341             break;
1342 
1343         case BTA_AG_IN_CALL_CONN_RES:
1344         case BTA_AG_OUT_CALL_ORIG_RES:
1345             /* if incoming call connected stop ring timer */
1346             if (p_result->result == BTA_AG_IN_CALL_CONN_RES)
1347             {
1348                 bta_sys_stop_timer(&p_scb->act_timer);
1349             }
1350 
1351             if (!(p_scb->features & BTA_AG_FEAT_NOSCO))
1352             {
1353                 /* if audio connected to this scb open sco */
1354                 if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb))
1355                 {
1356                     bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
1357                 }
1358                 /* else if no audio at call close sco */
1359                 else if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE)
1360                 {
1361                     bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
1362                 }
1363             }
1364             break;
1365 
1366         case BTA_AG_END_CALL_RES:
1367             /* stop ring timer */
1368             bta_sys_stop_timer(&p_scb->act_timer);
1369 
1370             /* close sco */
1371             if ((bta_ag_sco_is_open(p_scb) || bta_ag_sco_is_opening(p_scb)) && !(p_scb->features & BTA_AG_FEAT_NOSCO))
1372             {
1373                 bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
1374             }
1375             else
1376             {
1377                 /* if av got suspended by this call, let it resume. */
1378                 bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1379             }
1380             break;
1381 
1382         case BTA_AG_INBAND_RING_RES:
1383             p_scb->inband_enabled = p_result->data.state;
1384             APPL_TRACE_DEBUG1("inband_enabled set to %d", p_scb->inband_enabled);
1385             break;
1386 
1387         case BTA_AG_UNAT_RES:
1388             if (p_result->data.ok_flag != BTA_AG_OK_ERROR)
1389             {
1390                 if (p_result->data.str[0] != 0)
1391                 {
1392                     bta_ag_send_result(p_scb, code, p_result->data.str, 0);
1393                 }
1394 
1395                 if (p_result->data.ok_flag == BTA_AG_OK_DONE)
1396                     bta_ag_send_ok(p_scb);
1397             }
1398             else
1399             {
1400                 bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR);
1401             }
1402             break;
1403 
1404         default:
1405             /* ignore all others */
1406             break;
1407     }
1408 }
1409 
1410 /*******************************************************************************
1411 **
1412 ** Function         bta_ag_hfp_result
1413 **
1414 ** Description      Handle API result for HFP connections.
1415 **
1416 **
1417 ** Returns          void
1418 **
1419 *******************************************************************************/
bta_ag_hfp_result(tBTA_AG_SCB * p_scb,tBTA_AG_API_RESULT * p_result)1420 void bta_ag_hfp_result(tBTA_AG_SCB *p_scb, tBTA_AG_API_RESULT *p_result)
1421 {
1422     UINT8 code = bta_ag_trans_result[p_result->result];
1423 
1424     APPL_TRACE_DEBUG1("bta_ag_hfp_result : res = %d", p_result->result);
1425 
1426     switch(p_result->result)
1427     {
1428         case BTA_AG_SPK_RES:
1429         case BTA_AG_MIC_RES:
1430             bta_ag_send_result(p_scb, code, NULL, p_result->data.num);
1431             break;
1432 
1433         case BTA_AG_IN_CALL_RES:
1434             /* tell sys to stop av if any */
1435             bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1436 
1437             /* store caller id string.
1438              * append type info at the end.
1439              * make sure a valid type info is passed.
1440              * otherwise add 129 as default type */
1441             if ((p_result->data.num < BTA_AG_CLIP_TYPE_MIN) || (p_result->data.num > BTA_AG_CLIP_TYPE_MAX))
1442             {
1443                 if (p_result->data.num != BTA_AG_CLIP_TYPE_VOIP)
1444                     p_result->data.num = BTA_AG_CLIP_TYPE_DEFAULT;
1445             }
1446 
1447             APPL_TRACE_DEBUG1("CLIP type :%d", p_result->data.num);
1448             p_scb->clip[0] = 0;
1449             if (p_result->data.str[0] != 0)
1450                 sprintf(p_scb->clip,"%s,%d", p_result->data.str, p_result->data.num);
1451 
1452             /* send callsetup indicator */
1453             if (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END)
1454             {
1455                 /* Need to sent 2 callsetup IND's(Call End and Incoming call) after SCO close. */
1456                 p_scb->post_sco = BTA_AG_POST_SCO_CALL_END_INCALL;
1457             }
1458             else
1459             {
1460                 bta_ag_send_call_inds(p_scb, p_result->result);
1461 
1462                 /* if sco already opened or no inband ring send ring now */
1463                 if (bta_ag_sco_is_open(p_scb) || !bta_ag_inband_enabled(p_scb) ||
1464                     (p_scb->features & BTA_AG_FEAT_NOSCO))
1465                 {
1466                     bta_ag_send_ring(p_scb, (tBTA_AG_DATA *) p_result);
1467                 }
1468                 /* else open sco, send ring after sco opened */
1469                 else
1470                 {
1471                     p_scb->post_sco = BTA_AG_POST_SCO_RING;
1472                     bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
1473                 }
1474             }
1475             break;
1476 
1477         case BTA_AG_IN_CALL_CONN_RES:
1478             /* stop ring timer */
1479             bta_sys_stop_timer(&p_scb->act_timer);
1480 
1481             /* if sco not opened and we need to open it, open sco first
1482             ** then send indicators
1483             */
1484             if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
1485                 !bta_ag_sco_is_open(p_scb) && !(p_scb->features & BTA_AG_FEAT_NOSCO))
1486             {
1487                 p_scb->post_sco = BTA_AG_POST_SCO_CALL_CONN;
1488                 bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
1489             }
1490             /* else if sco open and we need to close it, close sco first
1491             ** then send indicators
1492             */
1493             else if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE &&
1494                      bta_ag_sco_is_open(p_scb) && !(p_scb->features & BTA_AG_FEAT_NOSCO))
1495             {
1496                 p_scb->post_sco = BTA_AG_POST_SCO_CALL_CONN;
1497                 bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
1498             }
1499             /* else send indicators now */
1500             else
1501             {
1502                 bta_ag_send_call_inds(p_scb, p_result->result);
1503             }
1504             break;
1505 
1506         case BTA_AG_IN_CALL_HELD_RES:
1507             /* stop ring timer */
1508             bta_sys_stop_timer(&p_scb->act_timer);
1509 
1510             bta_ag_send_call_inds(p_scb, p_result->result);
1511 
1512             break;
1513 
1514         case BTA_AG_OUT_CALL_ORIG_RES:
1515             /* if sco open and we need to close it, close sco first
1516             ** then send indicators; else send indicators now
1517             */
1518             if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE &&
1519                 bta_ag_sco_is_open(p_scb) && !(p_scb->features & BTA_AG_FEAT_NOSCO))
1520             {
1521                 p_scb->post_sco = BTA_AG_POST_SCO_CALL_ORIG;
1522                 bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
1523             }
1524             else
1525             {
1526                 bta_ag_send_call_inds(p_scb, p_result->result);
1527                 if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb) &&
1528                     !(p_scb->features & BTA_AG_FEAT_NOSCO))
1529                 {
1530                     bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
1531                 }
1532             }
1533             break;
1534 
1535         case BTA_AG_OUT_CALL_ALERT_RES:
1536             /* send indicators */
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             break;
1544 
1545         case BTA_AG_OUT_CALL_CONN_RES:
1546             /* send indicators */
1547             bta_ag_send_call_inds(p_scb, p_result->result);
1548 
1549             /* open or close sco */
1550             if (!(p_scb->features & BTA_AG_FEAT_NOSCO))
1551             {
1552                 if (p_result->data.audio_handle == bta_ag_scb_to_idx(p_scb))
1553                 {
1554                     bta_ag_sco_open(p_scb, (tBTA_AG_DATA *) p_result);
1555                 }
1556                 else if (p_result->data.audio_handle == BTA_AG_HANDLE_NONE)
1557                 {
1558                     bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
1559                 }
1560             }
1561             break;
1562 
1563         case BTA_AG_CALL_CANCEL_RES:
1564             /* send indicators */
1565             bta_ag_send_call_inds(p_scb, p_result->result);
1566             break;
1567 
1568         case BTA_AG_END_CALL_RES:
1569             /* stop ring timer */
1570             bta_sys_stop_timer(&p_scb->act_timer);
1571 
1572             /* if sco open, close sco then send indicator values */
1573             if ((bta_ag_sco_is_open(p_scb) || bta_ag_sco_is_opening(p_scb)) && !(p_scb->features & BTA_AG_FEAT_NOSCO))
1574             {
1575                 p_scb->post_sco = BTA_AG_POST_SCO_CALL_END;
1576                 bta_ag_sco_close(p_scb, (tBTA_AG_DATA *) p_result);
1577             }
1578             else if (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END_INCALL)
1579             {
1580                 /* sco closing for outgoing call because of incoming call */
1581                 /* Send only callsetup end indicator after sco close */
1582                 p_scb->post_sco = BTA_AG_POST_SCO_CALL_END;
1583             }
1584             else
1585             {
1586                 bta_ag_send_call_inds(p_scb, p_result->result);
1587 
1588                 /* if av got suspended by this call, let it resume. */
1589                 bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1590             }
1591             break;
1592 
1593         case BTA_AG_INBAND_RING_RES:
1594             p_scb->inband_enabled = p_result->data.state;
1595             APPL_TRACE_DEBUG1("inband_enabled set to %d", p_scb->inband_enabled);
1596             bta_ag_send_result(p_scb, code, NULL, p_result->data.state);
1597             break;
1598 
1599         case BTA_AG_CIND_RES:
1600             /* store local values */
1601             p_scb->call_ind = p_result->data.str[0] - '0';
1602             p_scb->callsetup_ind = p_result->data.str[2] - '0';
1603             p_scb->service_ind = p_result->data.str[4] - '0';
1604             p_scb->signal_ind = p_result->data.str[6] - '0';
1605             p_scb->roam_ind = p_result->data.str[8] - '0';
1606             p_scb->battchg_ind = p_result->data.str[10] - '0';
1607             APPL_TRACE_DEBUG2("cind call:%d callsetup:%d", p_scb->call_ind, p_scb->callsetup_ind);
1608 
1609             bta_ag_send_result(p_scb, code, p_result->data.str, 0);
1610             bta_ag_send_ok(p_scb);
1611             break;
1612 
1613         case BTA_AG_BINP_RES:
1614         case BTA_AG_CNUM_RES:
1615         case BTA_AG_CLCC_RES:
1616         case BTA_AG_COPS_RES:
1617             if (p_result->data.ok_flag != BTA_AG_OK_ERROR)
1618             {
1619                 if (p_result->data.str[0] != 0)
1620                 {
1621                    bta_ag_send_result(p_scb, code, p_result->data.str, 0);
1622                 }
1623 
1624                 if (p_result->data.ok_flag == BTA_AG_OK_DONE)
1625                     bta_ag_send_ok(p_scb);
1626             }
1627             else
1628             {
1629                 bta_ag_send_error(p_scb, p_result->data.errcode);
1630             }
1631             break;
1632 
1633 
1634         case BTA_AG_UNAT_RES:
1635             if (p_result->data.ok_flag != BTA_AG_OK_ERROR)
1636             {
1637                 if (p_result->data.str[0] != 0)
1638                 {
1639                     bta_ag_process_unat_res(p_result->data.str);
1640                     APPL_TRACE_DEBUG1("BTA_AG_RES :%s",p_result->data.str);
1641                     bta_ag_send_result(p_scb, code, p_result->data.str, 0);
1642                 }
1643 
1644                 if (p_result->data.ok_flag == BTA_AG_OK_DONE)
1645                     bta_ag_send_ok(p_scb);
1646             }
1647             else
1648             {
1649                 bta_ag_send_error(p_scb, p_result->data.errcode);
1650             }
1651             break;
1652 
1653         case BTA_AG_CALL_WAIT_RES:
1654             if (p_scb->ccwa_enabled)
1655             {
1656                 bta_ag_send_result(p_scb, code, p_result->data.str, 0);
1657             }
1658             bta_ag_send_call_inds(p_scb, p_result->result);
1659             break;
1660 
1661         case BTA_AG_IND_RES:
1662             bta_ag_send_ind(p_scb, p_result->data.ind.id, p_result->data.ind.value, FALSE);
1663             break;
1664 
1665         case BTA_AG_BVRA_RES:
1666             bta_ag_send_result(p_scb, code, NULL, p_result->data.state);
1667             break;
1668 
1669         case BTA_AG_BTRH_RES:
1670             if (p_result->data.ok_flag != BTA_AG_OK_ERROR)
1671             {
1672                 /* Don't respond to read if not in response & hold state */
1673                 if (p_result->data.num != BTA_AG_BTRH_NO_RESP)
1674                 {
1675                     bta_ag_send_result(p_scb, code, NULL, p_result->data.num);
1676                 }
1677 
1678                 /* In case of a response to a read request we need to send OK */
1679                 if (p_result->data.ok_flag == BTA_AG_OK_DONE)
1680                     bta_ag_send_ok(p_scb);
1681             }
1682             else
1683             {
1684                 bta_ag_send_error(p_scb, p_result->data.errcode);
1685             }
1686             break;
1687 
1688        default:
1689             break;
1690     }
1691 }
1692 
1693 
1694 /*******************************************************************************
1695 **
1696 ** Function         bta_ag_result
1697 **
1698 ** Description      Handle API result.
1699 **
1700 **
1701 ** Returns          void
1702 **
1703 *******************************************************************************/
bta_ag_result(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1704 void bta_ag_result(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1705 {
1706     if (p_scb->conn_service == BTA_AG_HSP)
1707     {
1708         bta_ag_hsp_result(p_scb, &p_data->api_result);
1709     }
1710     else
1711     {
1712         bta_ag_hfp_result(p_scb, &p_data->api_result);
1713     }
1714 }
1715 
1716 /*******************************************************************************
1717 **
1718 ** Function         bta_ag_setcodec
1719 **
1720 ** Description      Handle API SetCodec
1721 **
1722 **
1723 ** Returns          void
1724 **
1725 *******************************************************************************/
bta_ag_setcodec(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1726 void bta_ag_setcodec(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1727 {
1728 #if (BTM_WBS_INCLUDED == TRUE )
1729     tBTA_AG_PEER_CODEC codec_type = p_data->api_setcodec.codec;
1730 
1731     /* Check if the requested codec type is valid */
1732     if((codec_type != BTA_AG_CODEC_NONE) &&
1733        (codec_type != BTA_AG_CODEC_CVSD) &&
1734        (codec_type != BTA_AG_CODEC_MSBC))
1735     {
1736         APPL_TRACE_ERROR1("bta_ag_setcodec error: unsupported codec type %d", codec_type);
1737         return;
1738     }
1739 
1740     if((p_scb->peer_codecs & codec_type) || (codec_type == BTA_AG_CODEC_NONE) || (codec_type == BTA_AG_CODEC_CVSD))
1741     {
1742         p_scb->sco_codec = codec_type;
1743         p_scb->codec_updated = TRUE;
1744         APPL_TRACE_DEBUG1("bta_ag_setcodec: Updated codec type %d", codec_type);
1745     }
1746     else
1747     {
1748         APPL_TRACE_ERROR1("bta_ag_setcodec error: unsupported codec type %d", codec_type);
1749     }
1750 #endif
1751 }
1752 
1753 
1754 #if (BTM_WBS_INCLUDED == TRUE )
1755 /*******************************************************************************
1756 **
1757 ** Function         bta_ag_send_bcs
1758 **
1759 ** Description      Send +BCS AT command to peer.
1760 **
1761 ** Returns          void
1762 **
1763 *******************************************************************************/
bta_ag_send_bcs(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1764 void bta_ag_send_bcs(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1765 {
1766     UINT16 codec_uuid;
1767 
1768     if (p_scb->codec_fallback)
1769     {
1770         codec_uuid = UUID_CODEC_CVSD;
1771     }
1772     else
1773     {
1774         switch(p_scb->sco_codec)
1775         {
1776             case BTA_AG_CODEC_NONE:     codec_uuid = UUID_CODEC_CVSD;   break;
1777             case BTA_AG_CODEC_CVSD:     codec_uuid = UUID_CODEC_CVSD;   break;
1778             case BTA_AG_CODEC_MSBC:     codec_uuid = UUID_CODEC_MSBC;   break;
1779             default:
1780                 APPL_TRACE_ERROR1("bta_ag_send_bcs: unknown codec %d, use CVSD", p_scb->sco_codec);
1781                 codec_uuid = UUID_CODEC_CVSD;
1782                 break;
1783         }
1784     }
1785 
1786     /* send +BCS */
1787     bta_ag_send_result(p_scb, BTA_AG_RES_BCS, NULL, codec_uuid);
1788 
1789 }
1790 #endif
1791 
1792 /*******************************************************************************
1793 **
1794 ** Function         bta_ag_send_ring
1795 **
1796 ** Description      Send RING result code to peer.
1797 **
1798 **
1799 ** Returns          void
1800 **
1801 *******************************************************************************/
bta_ag_send_ring(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1802 void bta_ag_send_ring(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1803 {
1804 #if defined(BTA_AG_MULTI_RESULT_INCLUDED) && (BTA_AG_MULTI_RESULT_INCLUDED == TRUE)
1805     tBTA_AG_MULTI_RESULT_CB m_res_cb;
1806 
1807     if (p_scb->conn_service == BTA_AG_HFP && p_scb->clip_enabled && p_scb->clip[0] != 0)
1808     {
1809         memset(&m_res_cb, NULL, sizeof(tBTA_AG_MULTI_RESULT_CB));
1810 
1811         m_res_cb.num_result = 2;
1812         AT_SET_RES_CB(m_res_cb.res_cb[0], BTA_AG_RES_RING, NULL, 0)
1813         AT_SET_RES_CB(m_res_cb.res_cb[1], BTA_AG_RES_CLIP, p_scb->clip, 0)
1814 
1815         bta_ag_send_multi_result(p_scb, &m_res_cb);
1816     }
1817     else
1818     {
1819         /* send RING ONLY */
1820         bta_ag_send_result(p_scb, BTA_AG_RES_RING, NULL, 0);
1821     }
1822 #else
1823     /* send RING */
1824     bta_ag_send_result(p_scb, BTA_AG_RES_RING, NULL, 0);
1825 
1826     /* if HFP and clip enabled and clip data send CLIP */
1827     if (p_scb->conn_service == BTA_AG_HFP && p_scb->clip_enabled && p_scb->clip[0] != 0)
1828     {
1829         bta_ag_send_result(p_scb, BTA_AG_RES_CLIP, p_scb->clip, 0);
1830     }
1831 #endif
1832 
1833     /* restart ring timer */
1834     bta_sys_start_timer(&p_scb->act_timer, BTA_AG_RING_TOUT_EVT, BTA_AG_RING_TOUT);
1835 }
1836 
1837 
1838