Home | History | Annotate | Download | only in ag
      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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
    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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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 *******************************************************************************/
   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