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