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