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