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