Home | History | Annotate | Download | only in hf_client
      1 /******************************************************************************
      2  *
      3  *  Copyright (c) 2014 The Android Open Source Project
      4  *  Copyright (C) 2003-2012 Broadcom Corporation
      5  *
      6  *  Licensed under the Apache License, Version 2.0 (the "License");
      7  *  you may not use this file except in compliance with the License.
      8  *  You may obtain a copy of the License at:
      9  *
     10  *  http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  *  Unless required by applicable law or agreed to in writing, software
     13  *  distributed under the License is distributed on an "AS IS" BASIS,
     14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  *
     18  ******************************************************************************/
     19 
     20 #define LOG_TAG "bt_hf_client"
     21 
     22 #include <errno.h>
     23 #include <stdio.h>
     24 #include <string.h>
     25 
     26 #include "bta_hf_client_api.h"
     27 #include "bta_hf_client_int.h"
     28 #include "osi/include/log.h"
     29 #include "osi/include/osi.h"
     30 #include "port_api.h"
     31 
     32 /* Uncomment to enable AT traffic dumping */
     33 /* #define BTA_HF_CLIENT_AT_DUMP 1 */
     34 
     35 /* minimum length of AT event */
     36 #define BTA_HF_CLIENT_AT_EVENT_MIN_LEN 3
     37 
     38 /* timeout (in milliseconds) for AT response */
     39 #define BTA_HF_CLIENT_AT_TIMEOUT 29989
     40 
     41 /* timeout (in milliseconds) for AT hold timer */
     42 #define BTA_HF_CLIENT_AT_HOLD_TIMEOUT 41
     43 
     44 /******************************************************************************
     45  *
     46  *          DATA TYPES AND CONTAINERS
     47  *
     48  ******************************************************************************/
     49 extern fixed_queue_t* btu_bta_alarm_queue;
     50 
     51 /******************************************************************************
     52  *       SUPPORTED EVENT MESSAGES
     53  ******************************************************************************/
     54 
     55 /* CIND: supported indicator names */
     56 #define BTA_HF_CLIENT_INDICATOR_BATTERYCHG "battchg"
     57 #define BTA_HF_CLIENT_INDICATOR_SIGNAL "signal"
     58 #define BTA_HF_CLIENT_INDICATOR_SERVICE "service"
     59 #define BTA_HF_CLIENT_INDICATOR_CALL "call"
     60 #define BTA_HF_CLIENT_INDICATOR_ROAM "roam"
     61 #define BTA_HF_CLIENT_INDICATOR_CALLSETUP "callsetup"
     62 #define BTA_HF_CLIENT_INDICATOR_CALLHELD "callheld"
     63 
     64 #define MIN(a, b)           \
     65   ({                        \
     66     __typeof__(a) _a = (a); \
     67     __typeof__(b) _b = (b); \
     68     (_a < _b) ? _a : _b;    \
     69   })
     70 
     71 /* CIND: represents each indicators boundaries */
     72 typedef struct {
     73   const char* name;
     74   uint8_t min;
     75   uint8_t max;
     76   uint8_t namelen;
     77 } tBTA_HF_CLIENT_INDICATOR;
     78 
     79 #define BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT 7
     80 
     81 /* CIND: storage room for indicators value range and their statuses */
     82 static const tBTA_HF_CLIENT_INDICATOR
     83     bta_hf_client_indicators[BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT] = {
     84         /* name                                | min | max | name length -
     85            used by parser */
     86         {BTA_HF_CLIENT_INDICATOR_BATTERYCHG, 0, 5,
     87          sizeof(BTA_HF_CLIENT_INDICATOR_BATTERYCHG)},
     88         {BTA_HF_CLIENT_INDICATOR_SIGNAL, 0, 5,
     89          sizeof(BTA_HF_CLIENT_INDICATOR_SIGNAL)},
     90         {BTA_HF_CLIENT_INDICATOR_SERVICE, 0, 1,
     91          sizeof(BTA_HF_CLIENT_INDICATOR_SERVICE)},
     92         {BTA_HF_CLIENT_INDICATOR_CALL, 0, 1,
     93          sizeof(BTA_HF_CLIENT_INDICATOR_CALL)},
     94         {BTA_HF_CLIENT_INDICATOR_ROAM, 0, 1,
     95          sizeof(BTA_HF_CLIENT_INDICATOR_ROAM)},
     96         {BTA_HF_CLIENT_INDICATOR_CALLSETUP, 0, 3,
     97          sizeof(BTA_HF_CLIENT_INDICATOR_CALLSETUP)},
     98         {BTA_HF_CLIENT_INDICATOR_CALLHELD, 0, 2,
     99          sizeof(BTA_HF_CLIENT_INDICATOR_CALLHELD)}};
    100 
    101 /* +VGM/+VGS - gain min/max values  */
    102 #define BTA_HF_CLIENT_VGS_MIN 0
    103 #define BTA_HF_CLIENT_VGS_MAX 15
    104 #define BTA_HF_CLIENT_VGM_MIN 0
    105 #define BTA_HF_CLIENT_VGM_MAX 15
    106 
    107 uint32_t service_index = 0;
    108 bool service_availability = true;
    109 /* helper functions for handling AT commands queueing */
    110 
    111 static void bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB* client_cb);
    112 
    113 static void bta_hf_client_clear_queued_at(tBTA_HF_CLIENT_CB* client_cb) {
    114   tBTA_HF_CLIENT_AT_QCMD* cur = client_cb->at_cb.queued_cmd;
    115   tBTA_HF_CLIENT_AT_QCMD* next;
    116 
    117   while (cur != NULL) {
    118     next = cur->next;
    119     osi_free(cur);
    120     cur = next;
    121   }
    122 
    123   client_cb->at_cb.queued_cmd = NULL;
    124 }
    125 
    126 static void bta_hf_client_queue_at(tBTA_HF_CLIENT_CB* client_cb,
    127                                    tBTA_HF_CLIENT_AT_CMD cmd, const char* buf,
    128                                    uint16_t buf_len) {
    129   tBTA_HF_CLIENT_AT_QCMD* new_cmd =
    130       (tBTA_HF_CLIENT_AT_QCMD*)osi_malloc(sizeof(tBTA_HF_CLIENT_AT_QCMD));
    131 
    132   APPL_TRACE_DEBUG("%s", __func__);
    133 
    134   new_cmd->cmd = cmd;
    135   new_cmd->buf_len = buf_len;
    136   new_cmd->next = NULL;
    137   memcpy(new_cmd->buf, buf, buf_len);
    138 
    139   if (client_cb->at_cb.queued_cmd != NULL) {
    140     tBTA_HF_CLIENT_AT_QCMD* qcmd = client_cb->at_cb.queued_cmd;
    141 
    142     while (qcmd->next != NULL) qcmd = qcmd->next;
    143 
    144     qcmd->next = new_cmd;
    145   } else {
    146     client_cb->at_cb.queued_cmd = new_cmd;
    147   }
    148 }
    149 
    150 static void bta_hf_client_at_resp_timer_cback(void* data) {
    151   tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
    152   if (client_cb->at_cb.current_cmd == BTA_HF_CLIENT_AT_CNUM) {
    153     LOG_INFO(LOG_TAG,
    154              "%s: timed out waiting for AT+CNUM response; spoofing OK.",
    155              __func__);
    156     bta_hf_client_handle_ok(client_cb);
    157   } else {
    158     APPL_TRACE_ERROR("HFPClient: AT response timeout, disconnecting");
    159 
    160     tBTA_HF_CLIENT_DATA msg;
    161     msg.hdr.layer_specific = client_cb->handle;
    162     bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
    163   }
    164 }
    165 
    166 static void bta_hf_client_start_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
    167   alarm_set_on_queue(client_cb->at_cb.resp_timer, BTA_HF_CLIENT_AT_TIMEOUT,
    168                      bta_hf_client_at_resp_timer_cback, (void*)client_cb,
    169                      btu_bta_alarm_queue);
    170 }
    171 
    172 static void bta_hf_client_stop_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
    173   alarm_cancel(client_cb->at_cb.resp_timer);
    174 }
    175 
    176 static void bta_hf_client_send_at(tBTA_HF_CLIENT_CB* client_cb,
    177                                   tBTA_HF_CLIENT_AT_CMD cmd, const char* buf,
    178                                   uint16_t buf_len) {
    179   APPL_TRACE_DEBUG("%s", __func__);
    180   if ((client_cb->at_cb.current_cmd == BTA_HF_CLIENT_AT_NONE ||
    181        client_cb->svc_conn == false) &&
    182       !alarm_is_scheduled(client_cb->at_cb.hold_timer)) {
    183     uint16_t len;
    184 
    185 #ifdef BTA_HF_CLIENT_AT_DUMP
    186     APPL_TRACE_DEBUG("%s: %.*s", __func__, buf_len - 1, buf);
    187 #endif
    188 
    189     client_cb->at_cb.current_cmd = cmd;
    190     /* Generate fake responses for these because they won't reliably work */
    191     if (!service_availability &&
    192         (cmd == BTA_HF_CLIENT_AT_CNUM || cmd == BTA_HF_CLIENT_AT_COPS)) {
    193       APPL_TRACE_WARNING("%s: No service, skipping %d command", __func__, cmd);
    194       bta_hf_client_handle_ok(client_cb);
    195       return;
    196     }
    197 
    198     APPL_TRACE_DEBUG("%s: writing port data to %d", __func__,
    199                      client_cb->conn_handle);
    200     PORT_WriteData(client_cb->conn_handle, buf, buf_len, &len);
    201 
    202     bta_hf_client_start_at_resp_timer(client_cb);
    203 
    204     return;
    205   }
    206 
    207   bta_hf_client_queue_at(client_cb, cmd, buf, buf_len);
    208 }
    209 
    210 static void bta_hf_client_send_queued_at(tBTA_HF_CLIENT_CB* client_cb) {
    211   tBTA_HF_CLIENT_AT_QCMD* cur = client_cb->at_cb.queued_cmd;
    212 
    213   APPL_TRACE_DEBUG("%s", __func__);
    214 
    215   if (cur != NULL) {
    216     client_cb->at_cb.queued_cmd = cur->next;
    217 
    218     bta_hf_client_send_at(client_cb, cur->cmd, cur->buf, cur->buf_len);
    219 
    220     osi_free(cur);
    221   }
    222 }
    223 
    224 static void bta_hf_client_at_hold_timer_cback(void* data) {
    225   tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
    226   APPL_TRACE_DEBUG("%s", __func__);
    227   bta_hf_client_send_queued_at(client_cb);
    228 }
    229 
    230 static void bta_hf_client_stop_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) {
    231   APPL_TRACE_DEBUG("%s", __func__);
    232   alarm_cancel(client_cb->at_cb.hold_timer);
    233 }
    234 
    235 static void bta_hf_client_start_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) {
    236   APPL_TRACE_DEBUG("%s", __func__);
    237   alarm_set_on_queue(client_cb->at_cb.hold_timer, BTA_HF_CLIENT_AT_HOLD_TIMEOUT,
    238                      bta_hf_client_at_hold_timer_cback, (void*)client_cb,
    239                      btu_bta_alarm_queue);
    240 }
    241 
    242 /******************************************************************************
    243  *
    244  *          COMMON AT EVENT HANDLING funcS
    245  *
    246  *   Receives data (strings, ints, etc.) from the parser and processes this
    247  *   data. No buffer parsing is being done here.
    248  ******************************************************************************/
    249 
    250 static void bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB* client_cb) {
    251   APPL_TRACE_DEBUG("%s", __func__);
    252 
    253   bta_hf_client_stop_at_resp_timer(client_cb);
    254 
    255   if (!client_cb->svc_conn) {
    256     bta_hf_client_slc_seq(client_cb, false);
    257     return;
    258   }
    259 
    260   switch (client_cb->at_cb.current_cmd) {
    261     case BTA_HF_CLIENT_AT_BIA:
    262     case BTA_HF_CLIENT_AT_BCC:
    263       break;
    264     case BTA_HF_CLIENT_AT_BCS:
    265       bta_hf_client_start_at_hold_timer(client_cb);
    266       client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
    267       return;
    268     case BTA_HF_CLIENT_AT_CLIP:  // last cmd is post slc seq
    269       if (client_cb->send_at_reply == false) {
    270         client_cb->send_at_reply = true;
    271       }
    272       break;
    273     case BTA_HF_CLIENT_AT_NONE:
    274       bta_hf_client_stop_at_hold_timer(client_cb);
    275       break;
    276     default:
    277       if (client_cb->send_at_reply) {
    278         bta_hf_client_at_result(client_cb, BTA_HF_CLIENT_AT_RESULT_OK, 0);
    279       }
    280       break;
    281   }
    282 
    283   client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
    284 
    285   bta_hf_client_send_queued_at(client_cb);
    286 }
    287 
    288 static void bta_hf_client_handle_error(tBTA_HF_CLIENT_CB* client_cb,
    289                                        tBTA_HF_CLIENT_AT_RESULT_TYPE type,
    290                                        uint16_t cme) {
    291   APPL_TRACE_DEBUG("%s: %u %u", __func__, type, cme);
    292 
    293   bta_hf_client_stop_at_resp_timer(client_cb);
    294 
    295   if (!client_cb->svc_conn) {
    296     bta_hf_client_slc_seq(client_cb, true);
    297     return;
    298   }
    299 
    300   switch (client_cb->at_cb.current_cmd) {
    301     case BTA_HF_CLIENT_AT_BIA:
    302       break;
    303     case BTA_HF_CLIENT_AT_BCC:
    304     case BTA_HF_CLIENT_AT_BCS:
    305       bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
    306       break;
    307     case BTA_HF_CLIENT_AT_CLIP:  // last cmd is post slc seq
    308       if (client_cb->send_at_reply == false) {
    309         client_cb->send_at_reply = true;
    310       }
    311       break;
    312     default:
    313       if (client_cb->send_at_reply) {
    314         bta_hf_client_at_result(client_cb, type, cme);
    315       }
    316       break;
    317   }
    318 
    319   client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
    320 
    321   bta_hf_client_send_queued_at(client_cb);
    322 }
    323 
    324 static void bta_hf_client_handle_ring(tBTA_HF_CLIENT_CB* client_cb) {
    325   APPL_TRACE_DEBUG("%s", __func__);
    326   bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_RING_INDICATION, 0);
    327 }
    328 
    329 static void bta_hf_client_handle_brsf(tBTA_HF_CLIENT_CB* client_cb,
    330                                       uint32_t value) {
    331   APPL_TRACE_DEBUG("%s: 0x%x", __func__, value);
    332   client_cb->peer_features = value;
    333 }
    334 
    335 /* handles a single indicator descriptor - registers it for value changing
    336  * events */
    337 static void bta_hf_client_handle_cind_list_item(tBTA_HF_CLIENT_CB* client_cb,
    338                                                 char* name, uint32_t min,
    339                                                 uint32_t max, uint32_t index) {
    340   uint8_t i = 0;
    341 
    342   APPL_TRACE_DEBUG("%s: %lu.%s <%lu:%lu>", __func__, index, name, min, max);
    343 
    344   /* look for a matching indicator on list of supported ones */
    345   for (i = 0; i < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT; i++) {
    346     if (strcmp(name, BTA_HF_CLIENT_INDICATOR_SERVICE) == 0) {
    347       service_index = index;
    348     }
    349     /* look for a match - search one sign further than indicators name to check
    350      * for string end */
    351     /* It will distinguish 'callheld' which could be matched by strncmp as
    352      * 'call'.               */
    353     if (strncmp(name, bta_hf_client_indicators[i].name,
    354                 bta_hf_client_indicators[i].namelen) != 0)
    355       continue;
    356 
    357     /* index - enumerates value position in the incoming sequence */
    358     /* if name matches one of the known indicators, add its incoming position */
    359     /* to lookup table for easy value->indicator matching later, when only
    360      * values come  */
    361     client_cb->at_cb.indicator_lookup[index] = i;
    362 
    363     return;
    364   }
    365 }
    366 
    367 static void bta_hf_client_handle_cind_value(tBTA_HF_CLIENT_CB* client_cb,
    368                                             uint32_t index, uint32_t value) {
    369   APPL_TRACE_DEBUG("%s: index: %u value: %u", __func__, index, value);
    370 
    371   if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
    372     return;
    373   }
    374 
    375   if (service_index == index) {
    376     if (value == 0) {
    377       service_availability = false;
    378     } else {
    379       service_availability = true;
    380     }
    381   }
    382   if (client_cb->at_cb.indicator_lookup[index] == -1) {
    383     return;
    384   }
    385 
    386   /* get the real array index from lookup table */
    387   index = client_cb->at_cb.indicator_lookup[index];
    388 
    389   /* Ignore out of range values */
    390   if (value > bta_hf_client_indicators[index].max ||
    391       value < bta_hf_client_indicators[index].min) {
    392     return;
    393   }
    394 
    395   /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
    396   bta_hf_client_ind(client_cb, index, value);
    397 }
    398 
    399 static void bta_hf_client_handle_chld(tBTA_HF_CLIENT_CB* client_cb,
    400                                       uint32_t mask) {
    401   APPL_TRACE_DEBUG("%s: 0x%x", __func__, mask);
    402 
    403   client_cb->chld_features |= mask;
    404 }
    405 
    406 static void bta_hf_client_handle_ciev(tBTA_HF_CLIENT_CB* client_cb,
    407                                       uint32_t index, uint32_t value) {
    408   int8_t realind = -1;
    409 
    410   APPL_TRACE_DEBUG("%s: index: %u value: %u", __func__, index, value);
    411 
    412   if (index == 0 || index > BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
    413     return;
    414   }
    415 
    416   if (service_index == index - 1) {
    417     service_availability = value == 0 ? false : true;
    418   }
    419 
    420   realind = client_cb->at_cb.indicator_lookup[index - 1];
    421 
    422   if (realind >= 0 && realind < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT) {
    423     /* get the real in-array index from lookup table by index it comes at */
    424     /* if there is no bug it should automatically be correctly calculated    */
    425     if (value > bta_hf_client_indicators[realind].max ||
    426         value < bta_hf_client_indicators[realind].min) {
    427       return;
    428     }
    429 
    430     /* update service availability on +ciev from AG. */
    431     if (service_index == (index - 1)) {
    432       if (value == 1) {
    433         service_availability = true;
    434       } else {
    435         service_availability = false;
    436       }
    437     }
    438 
    439     /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
    440     bta_hf_client_ind(client_cb, realind, value);
    441   }
    442 }
    443 
    444 static void bta_hf_client_handle_bcs(tBTA_HF_CLIENT_CB* client_cb,
    445                                      uint32_t codec) {
    446   APPL_TRACE_DEBUG("%s: codec: %u sco listen state: %d", __func__, codec,
    447                    client_cb->sco_state);
    448   if (codec == BTM_SCO_CODEC_CVSD || codec == BTM_SCO_CODEC_MSBC) {
    449     client_cb->negotiated_codec = codec;
    450     bta_hf_client_send_at_bcs(client_cb, codec);
    451   } else {
    452     client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
    453     bta_hf_client_send_at_bac(client_cb);
    454   }
    455 }
    456 
    457 static void bta_hf_client_handle_bsir(tBTA_HF_CLIENT_CB* client_cb,
    458                                       uint32_t provided) {
    459   APPL_TRACE_DEBUG("%s: %u", __func__, provided);
    460 
    461   bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BSIR_EVT, provided);
    462 }
    463 
    464 static void bta_hf_client_handle_cmeerror(tBTA_HF_CLIENT_CB* client_cb,
    465                                           uint32_t code) {
    466   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_CME, code);
    467 }
    468 
    469 static void bta_hf_client_handle_vgm(tBTA_HF_CLIENT_CB* client_cb,
    470                                      uint32_t value) {
    471   APPL_TRACE_DEBUG("%s: %lu", __func__, value);
    472 
    473   if (value <= BTA_HF_CLIENT_VGM_MAX) {
    474     bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_MIC_EVT, value);
    475   }
    476 }
    477 
    478 static void bta_hf_client_handle_vgs(tBTA_HF_CLIENT_CB* client_cb,
    479                                      uint32_t value) {
    480   APPL_TRACE_DEBUG("%s: %lu", __func__, value);
    481 
    482   if (value <= BTA_HF_CLIENT_VGS_MAX) {
    483     bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_SPK_EVT, value);
    484   }
    485 }
    486 
    487 static void bta_hf_client_handle_bvra(tBTA_HF_CLIENT_CB* client_cb,
    488                                       uint32_t value) {
    489   APPL_TRACE_DEBUG("%s: %lu", __func__, value);
    490 
    491   if (value > 1) {
    492     return;
    493   }
    494 
    495   bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_VOICE_REC_EVT, value);
    496 }
    497 
    498 static void bta_hf_client_handle_clip(tBTA_HF_CLIENT_CB* client_cb,
    499                                       char* numstr, uint32_t type) {
    500   APPL_TRACE_DEBUG("%s: %u %s", __func__, type, numstr);
    501 
    502   bta_hf_client_clip(client_cb, numstr);
    503 }
    504 
    505 static void bta_hf_client_handle_ccwa(tBTA_HF_CLIENT_CB* client_cb,
    506                                       char* numstr, uint32_t type) {
    507   APPL_TRACE_DEBUG("%s: %u %s", __func__, type, numstr);
    508 
    509   bta_hf_client_ccwa(client_cb, numstr);
    510 }
    511 
    512 static void bta_hf_client_handle_cops(tBTA_HF_CLIENT_CB* client_cb, char* opstr,
    513                                       uint32_t mode) {
    514   APPL_TRACE_DEBUG("%s: %u %s", __func__, mode, opstr);
    515 
    516   bta_hf_client_operator_name(client_cb, opstr);
    517 }
    518 
    519 static void bta_hf_client_handle_binp(tBTA_HF_CLIENT_CB* client_cb,
    520                                       char* numstr) {
    521   APPL_TRACE_DEBUG("%s: %s", __func__, numstr);
    522 
    523   bta_hf_client_binp(client_cb, numstr);
    524 }
    525 
    526 static void bta_hf_client_handle_clcc(tBTA_HF_CLIENT_CB* client_cb,
    527                                       uint16_t idx, uint16_t dir,
    528                                       uint16_t status, uint16_t mode,
    529                                       uint16_t mpty, char* numstr,
    530                                       uint16_t type) {
    531   APPL_TRACE_DEBUG("%s: idx: %u dir: %u status: %u mode: %u mpty: %u", __func__,
    532                    idx, dir, status, mode, mpty);
    533 
    534   if (numstr) {
    535     APPL_TRACE_DEBUG("%s: number: %s  type: %u", __func__, numstr, type);
    536   }
    537 
    538   bta_hf_client_clcc(client_cb, idx, dir, status, mpty, numstr);
    539 }
    540 
    541 static void bta_hf_client_handle_cnum(tBTA_HF_CLIENT_CB* client_cb,
    542                                       char* numstr, uint16_t type,
    543                                       uint16_t service) {
    544   APPL_TRACE_DEBUG("%s: number: %s type: %u service: %u", __func__, numstr,
    545                    type, service);
    546 
    547   /* TODO: should number be modified according to type? */
    548   bta_hf_client_cnum(client_cb, numstr, service);
    549 }
    550 
    551 static void bta_hf_client_handle_btrh(tBTA_HF_CLIENT_CB* client_cb,
    552                                       uint16_t code) {
    553   APPL_TRACE_DEBUG("%s: %lu", __func__, code);
    554 
    555   bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BTRH_EVT, code);
    556 }
    557 
    558 /*******************************************************************************
    559  *
    560  * Function         bta_hf_client_cback_ind
    561  *
    562  * Description      Send indicator callback event to application.
    563  *
    564  * Returns          void
    565  *
    566  ******************************************************************************/
    567 void bta_hf_client_ind(tBTA_HF_CLIENT_CB* client_cb,
    568                        tBTA_HF_CLIENT_IND_TYPE type, uint16_t value) {
    569   tBTA_HF_CLIENT evt;
    570 
    571   memset(&evt, 0, sizeof(evt));
    572 
    573   evt.ind.type = type;
    574   evt.ind.value = value;
    575 
    576   bdcpy(evt.ind.bd_addr, client_cb->peer_addr);
    577   bta_hf_client_app_callback(BTA_HF_CLIENT_IND_EVT, &evt);
    578 }
    579 
    580 /*******************************************************************************
    581  *
    582  * Function         bta_hf_client_evt_val
    583  *
    584  * Description      Send event to application.
    585  *                  This is a generic helper for events with common data.
    586  *
    587  *
    588  * Returns          void
    589  *
    590  ******************************************************************************/
    591 void bta_hf_client_evt_val(tBTA_HF_CLIENT_CB* client_cb,
    592                            tBTA_HF_CLIENT_EVT type, uint16_t value) {
    593   tBTA_HF_CLIENT evt;
    594 
    595   memset(&evt, 0, sizeof(evt));
    596 
    597   bdcpy(evt.val.bd_addr, client_cb->peer_addr);
    598   evt.val.value = value;
    599 
    600   bta_hf_client_app_callback(type, &evt);
    601 }
    602 
    603 /*******************************************************************************
    604  *
    605  * Function         bta_hf_client_operator_name
    606  *
    607  * Description      Send operator name event to application.
    608  *
    609  *
    610  * Returns          void
    611  *
    612  ******************************************************************************/
    613 void bta_hf_client_operator_name(tBTA_HF_CLIENT_CB* client_cb, char* name) {
    614   tBTA_HF_CLIENT evt;
    615 
    616   memset(&evt, 0, sizeof(evt));
    617 
    618   strlcpy(evt.operator_name.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
    619   evt.operator_name.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
    620 
    621   bdcpy(evt.operator_name.bd_addr, client_cb->peer_addr);
    622   bta_hf_client_app_callback(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
    623 }
    624 
    625 /*******************************************************************************
    626  *
    627  * Function         bta_hf_client_clip
    628  *
    629  * Description      Send CLIP event to application.
    630  *
    631  *
    632  * Returns          void
    633  *
    634  ******************************************************************************/
    635 void bta_hf_client_clip(tBTA_HF_CLIENT_CB* client_cb, char* number) {
    636   tBTA_HF_CLIENT evt;
    637 
    638   memset(&evt, 0, sizeof(evt));
    639 
    640   strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    641   evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    642 
    643   bdcpy(evt.number.bd_addr, client_cb->peer_addr);
    644   bta_hf_client_app_callback(BTA_HF_CLIENT_CLIP_EVT, &evt);
    645 }
    646 
    647 /*******************************************************************************
    648  *
    649  * Function         bta_hf_client_ccwa
    650  *
    651  * Description      Send CLIP event to application.
    652  *
    653  *
    654  * Returns          void
    655  *
    656  ******************************************************************************/
    657 void bta_hf_client_ccwa(tBTA_HF_CLIENT_CB* client_cb, char* number) {
    658   tBTA_HF_CLIENT evt;
    659 
    660   memset(&evt, 0, sizeof(evt));
    661 
    662   strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    663   evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    664 
    665   bdcpy(evt.number.bd_addr, client_cb->peer_addr);
    666   bta_hf_client_app_callback(BTA_HF_CLIENT_CCWA_EVT, &evt);
    667 }
    668 
    669 /*******************************************************************************
    670  *
    671  * Function         bta_hf_client_at_result
    672  *
    673  * Description      Send AT result event to application.
    674  *
    675  *
    676  * Returns          void
    677  *
    678  ******************************************************************************/
    679 void bta_hf_client_at_result(tBTA_HF_CLIENT_CB* client_cb,
    680                              tBTA_HF_CLIENT_AT_RESULT_TYPE type, uint16_t cme) {
    681   tBTA_HF_CLIENT evt;
    682 
    683   memset(&evt, 0, sizeof(evt));
    684 
    685   evt.result.type = type;
    686   evt.result.cme = cme;
    687 
    688   bdcpy(evt.result.bd_addr, client_cb->peer_addr);
    689   bta_hf_client_app_callback(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
    690 }
    691 
    692 /*******************************************************************************
    693  *
    694  * Function         bta_hf_client_clcc
    695  *
    696  * Description      Send clcc event to application.
    697  *
    698  *
    699  * Returns          void
    700  *
    701  ******************************************************************************/
    702 void bta_hf_client_clcc(tBTA_HF_CLIENT_CB* client_cb, uint32_t idx,
    703                         bool incoming, uint8_t status, bool mpty,
    704                         char* number) {
    705   tBTA_HF_CLIENT evt;
    706 
    707   memset(&evt, 0, sizeof(evt));
    708 
    709   evt.clcc.idx = idx;
    710   evt.clcc.inc = incoming;
    711   evt.clcc.status = status;
    712   evt.clcc.mpty = mpty;
    713 
    714   if (number) {
    715     evt.clcc.number_present = true;
    716     strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    717     evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    718   }
    719 
    720   bdcpy(evt.clcc.bd_addr, client_cb->peer_addr);
    721   bta_hf_client_app_callback(BTA_HF_CLIENT_CLCC_EVT, &evt);
    722 }
    723 
    724 /*******************************************************************************
    725  *
    726  * Function         bta_hf_client_cnum
    727  *
    728  * Description      Send cnum event to application.
    729  *
    730  *
    731  * Returns          void
    732  *
    733  ******************************************************************************/
    734 void bta_hf_client_cnum(tBTA_HF_CLIENT_CB* client_cb, char* number,
    735                         uint16_t service) {
    736   tBTA_HF_CLIENT evt;
    737 
    738   memset(&evt, 0, sizeof(evt));
    739 
    740   evt.cnum.service = service;
    741   strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    742   evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    743 
    744   bdcpy(evt.cnum.bd_addr, client_cb->peer_addr);
    745   bta_hf_client_app_callback(BTA_HF_CLIENT_CNUM_EVT, &evt);
    746 }
    747 
    748 /*******************************************************************************
    749  *
    750  * Function         bta_hf_client_binp
    751  *
    752  * Description      Send BINP event to application.
    753  *
    754  *
    755  * Returns          void
    756  *
    757  ******************************************************************************/
    758 void bta_hf_client_binp(tBTA_HF_CLIENT_CB* client_cb, char* number) {
    759   tBTA_HF_CLIENT evt;
    760 
    761   memset(&evt, 0, sizeof(evt));
    762 
    763   strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    764   evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    765 
    766   bdcpy(evt.number.bd_addr, client_cb->peer_addr);
    767   bta_hf_client_app_callback(BTA_HF_CLIENT_BINP_EVT, &evt);
    768 }
    769 
    770 /******************************************************************************
    771  *
    772  *          COMMON AT EVENTS PARSING FUNCTIONS
    773  *
    774  ******************************************************************************/
    775 
    776 /* Check if prefix match and skip spaces if any */
    777 #define AT_CHECK_EVENT(buf, event)                                             \
    778   do {                                                                         \
    779     if (strncmp("\r\n" event, buf, sizeof("\r\n" event) - 1) != 0) return buf; \
    780     (buf) += sizeof("\r\n" event) - 1;                                         \
    781     while (*(buf) == ' ') (buf)++;                                             \
    782   } while (0)
    783 
    784 /* check for <cr><lf> and forward buffer if match */
    785 #define AT_CHECK_RN(buf)                                      \
    786   do {                                                        \
    787     if (strncmp("\r\n", buf, sizeof("\r\n") - 1) != 0) {      \
    788       APPL_TRACE_DEBUG("%s: missing end <cr><lf>", __func__); \
    789       return NULL;                                            \
    790     }                                                         \
    791     (buf) += sizeof("\r\n") - 1;                              \
    792   } while (0)
    793 
    794 /* skip rest of AT string up to <cr> */
    795 #define AT_SKIP_REST(buf)           \
    796   do {                              \
    797     while (*(buf) != '\r') (buf)++; \
    798   } while (0)
    799 
    800 static char* bta_hf_client_parse_ok(tBTA_HF_CLIENT_CB* client_cb,
    801                                     char* buffer) {
    802   AT_CHECK_EVENT(buffer, "OK");
    803   AT_CHECK_RN(buffer);
    804 
    805   bta_hf_client_handle_ok(client_cb);
    806 
    807   return buffer;
    808 }
    809 
    810 static char* bta_hf_client_parse_error(tBTA_HF_CLIENT_CB* client_cb,
    811                                        char* buffer) {
    812   AT_CHECK_EVENT(buffer, "ERROR");
    813   AT_CHECK_RN(buffer);
    814 
    815   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_ERROR, 0);
    816 
    817   return buffer;
    818 }
    819 
    820 static char* bta_hf_client_parse_ring(tBTA_HF_CLIENT_CB* client_cb,
    821                                       char* buffer) {
    822   AT_CHECK_EVENT(buffer, "RING");
    823   AT_CHECK_RN(buffer);
    824 
    825   bta_hf_client_handle_ring(client_cb);
    826 
    827   return buffer;
    828 }
    829 
    830 /* generic uint32 parser */
    831 static char* bta_hf_client_parse_uint32(
    832     tBTA_HF_CLIENT_CB* client_cb, char* buffer,
    833     void (*handler_callback)(tBTA_HF_CLIENT_CB*, uint32_t)) {
    834   uint32_t value;
    835   int res;
    836   int offset;
    837 
    838   res = sscanf(buffer, "%u%n", &value, &offset);
    839   if (res < 1) {
    840     return NULL;
    841   }
    842 
    843   buffer += offset;
    844 
    845   AT_CHECK_RN(buffer);
    846 
    847   handler_callback(client_cb, value);
    848   return buffer;
    849 }
    850 
    851 static char* bta_hf_client_parse_brsf(tBTA_HF_CLIENT_CB* client_cb,
    852                                       char* buffer) {
    853   AT_CHECK_EVENT(buffer, "+BRSF:");
    854 
    855   return bta_hf_client_parse_uint32(client_cb, buffer,
    856                                     bta_hf_client_handle_brsf);
    857 }
    858 
    859 static char* bta_hf_client_parse_cind_values(tBTA_HF_CLIENT_CB* client_cb,
    860                                              char* buffer) {
    861   /* value and its position */
    862   uint16_t index = 0;
    863   uint32_t value = 0;
    864 
    865   int offset;
    866   int res;
    867 
    868   while ((res = sscanf(buffer, "%u%n", &value, &offset)) > 0) {
    869     /* decides if its valid index and value, if yes stores it */
    870     bta_hf_client_handle_cind_value(client_cb, index, value);
    871 
    872     buffer += offset;
    873 
    874     /* check if more values are present */
    875     if (*buffer != ',') {
    876       break;
    877     }
    878 
    879     index++;
    880     buffer++;
    881   }
    882 
    883   if (res > 0) {
    884     AT_CHECK_RN(buffer);
    885     return buffer;
    886   }
    887 
    888   return NULL;
    889 }
    890 
    891 static char* bta_hf_client_parse_cind_list(tBTA_HF_CLIENT_CB* client_cb,
    892                                            char* buffer) {
    893   int offset = 0;
    894   char name[129];
    895   uint32_t min, max;
    896   uint32_t index = 0;
    897   int res;
    898 
    899   while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min,
    900                        &max, &offset)) > 2) {
    901     bta_hf_client_handle_cind_list_item(client_cb, name, min, max, index);
    902     if (offset == 0) {
    903       APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
    904       return NULL;
    905     }
    906 
    907     buffer += offset;
    908     index++;
    909 
    910     if (*buffer != ',') {
    911       break;
    912     }
    913 
    914     buffer++;
    915   }
    916 
    917   if (res > 2) {
    918     AT_CHECK_RN(buffer);
    919     return buffer;
    920   }
    921 
    922   return NULL;
    923 }
    924 
    925 static char* bta_hf_client_parse_cind(tBTA_HF_CLIENT_CB* client_cb,
    926                                       char* buffer) {
    927   AT_CHECK_EVENT(buffer, "+CIND:");
    928 
    929   if (*buffer == '(') return bta_hf_client_parse_cind_list(client_cb, buffer);
    930 
    931   return bta_hf_client_parse_cind_values(client_cb, buffer);
    932 }
    933 
    934 static char* bta_hf_client_parse_chld(tBTA_HF_CLIENT_CB* client_cb,
    935                                       char* buffer) {
    936   AT_CHECK_EVENT(buffer, "+CHLD:");
    937 
    938   if (*buffer != '(') {
    939     return NULL;
    940   }
    941 
    942   buffer++;
    943 
    944   while (*buffer != '\0') {
    945     if (strncmp("0", buffer, 1) == 0) {
    946       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL);
    947       buffer++;
    948     } else if (strncmp("1x", buffer, 2) == 0) {
    949       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_X);
    950       buffer += 2;
    951     } else if (strncmp("1", buffer, 1) == 0) {
    952       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_ACC);
    953       buffer++;
    954     } else if (strncmp("2x", buffer, 2) == 0) {
    955       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_PRIV_X);
    956       buffer += 2;
    957     } else if (strncmp("2", buffer, 1) == 0) {
    958       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_HOLD_ACC);
    959       buffer++;
    960     } else if (strncmp("3", buffer, 1) == 0) {
    961       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE);
    962       buffer++;
    963     } else if (strncmp("4", buffer, 1) == 0) {
    964       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE_DETACH);
    965       buffer++;
    966     } else {
    967       return NULL;
    968     }
    969 
    970     if (*buffer == ',') {
    971       buffer++;
    972       continue;
    973     }
    974 
    975     if (*buffer == ')') {
    976       buffer++;
    977       break;
    978     }
    979 
    980     return NULL;
    981   }
    982 
    983   AT_CHECK_RN(buffer);
    984 
    985   return buffer;
    986 }
    987 
    988 static char* bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB* client_cb,
    989                                       char* buffer) {
    990   uint32_t index, value;
    991   int res;
    992   int offset = 0;
    993 
    994   AT_CHECK_EVENT(buffer, "+CIEV:");
    995 
    996   res = sscanf(buffer, "%u,%u%n", &index, &value, &offset);
    997   if (res < 2) {
    998     return NULL;
    999   }
   1000 
   1001   if (offset == 0) {
   1002     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
   1003     return NULL;
   1004   }
   1005 
   1006   buffer += offset;
   1007 
   1008   AT_CHECK_RN(buffer);
   1009 
   1010   bta_hf_client_handle_ciev(client_cb, index, value);
   1011   return buffer;
   1012 }
   1013 
   1014 static char* bta_hf_client_parse_bcs(tBTA_HF_CLIENT_CB* client_cb,
   1015                                      char* buffer) {
   1016   AT_CHECK_EVENT(buffer, "+BCS:");
   1017 
   1018   return bta_hf_client_parse_uint32(client_cb, buffer,
   1019                                     bta_hf_client_handle_bcs);
   1020 }
   1021 
   1022 static char* bta_hf_client_parse_bsir(tBTA_HF_CLIENT_CB* client_cb,
   1023                                       char* buffer) {
   1024   AT_CHECK_EVENT(buffer, "+BSIR:");
   1025 
   1026   return bta_hf_client_parse_uint32(client_cb, buffer,
   1027                                     bta_hf_client_handle_bsir);
   1028 }
   1029 
   1030 static char* bta_hf_client_parse_cmeerror(tBTA_HF_CLIENT_CB* client_cb,
   1031                                           char* buffer) {
   1032   AT_CHECK_EVENT(buffer, "+CME ERROR:");
   1033 
   1034   return bta_hf_client_parse_uint32(client_cb, buffer,
   1035                                     bta_hf_client_handle_cmeerror);
   1036 }
   1037 
   1038 static char* bta_hf_client_parse_vgm(tBTA_HF_CLIENT_CB* client_cb,
   1039                                      char* buffer) {
   1040   AT_CHECK_EVENT(buffer, "+VGM:");
   1041 
   1042   return bta_hf_client_parse_uint32(client_cb, buffer,
   1043                                     bta_hf_client_handle_vgm);
   1044 }
   1045 
   1046 static char* bta_hf_client_parse_vgme(tBTA_HF_CLIENT_CB* client_cb,
   1047                                       char* buffer) {
   1048   AT_CHECK_EVENT(buffer, "+VGM=");
   1049 
   1050   return bta_hf_client_parse_uint32(client_cb, buffer,
   1051                                     bta_hf_client_handle_vgm);
   1052 }
   1053 
   1054 static char* bta_hf_client_parse_vgs(tBTA_HF_CLIENT_CB* client_cb,
   1055                                      char* buffer) {
   1056   AT_CHECK_EVENT(buffer, "+VGS:");
   1057 
   1058   return bta_hf_client_parse_uint32(client_cb, buffer,
   1059                                     bta_hf_client_handle_vgs);
   1060 }
   1061 
   1062 static char* bta_hf_client_parse_vgse(tBTA_HF_CLIENT_CB* client_cb,
   1063                                       char* buffer) {
   1064   AT_CHECK_EVENT(buffer, "+VGS=");
   1065 
   1066   return bta_hf_client_parse_uint32(client_cb, buffer,
   1067                                     bta_hf_client_handle_vgs);
   1068 }
   1069 
   1070 static char* bta_hf_client_parse_bvra(tBTA_HF_CLIENT_CB* client_cb,
   1071                                       char* buffer) {
   1072   AT_CHECK_EVENT(buffer, "+BVRA:");
   1073 
   1074   return bta_hf_client_parse_uint32(client_cb, buffer,
   1075                                     bta_hf_client_handle_bvra);
   1076 }
   1077 
   1078 static char* bta_hf_client_parse_clip(tBTA_HF_CLIENT_CB* client_cb,
   1079                                       char* buffer) {
   1080   /* spec forces 32 chars, plus \0 here */
   1081   char number[33];
   1082   uint32_t type = 0;
   1083   int res;
   1084   int offset = 0;
   1085 
   1086   AT_CHECK_EVENT(buffer, "+CLIP:");
   1087 
   1088   /* there might be something more after %lu but HFP doesn't care */
   1089   res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
   1090   if (res < 2) {
   1091     return NULL;
   1092   }
   1093 
   1094   if (offset == 0) {
   1095     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
   1096     return NULL;
   1097   }
   1098 
   1099   buffer += offset;
   1100 
   1101   AT_SKIP_REST(buffer);
   1102 
   1103   AT_CHECK_RN(buffer);
   1104 
   1105   bta_hf_client_handle_clip(client_cb, number, type);
   1106   return buffer;
   1107 }
   1108 
   1109 /* in HFP context there is no difference between ccwa and clip */
   1110 static char* bta_hf_client_parse_ccwa(tBTA_HF_CLIENT_CB* client_cb,
   1111                                       char* buffer) {
   1112   /* ac to spec 32 chars max, plus \0 here */
   1113   char number[33];
   1114   uint32_t type = 0;
   1115   int res;
   1116   int offset = 0;
   1117 
   1118   AT_CHECK_EVENT(buffer, "+CCWA:");
   1119 
   1120   /* there might be something more after %lu but HFP doesn't care */
   1121   res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
   1122   if (res < 2) {
   1123     return NULL;
   1124   }
   1125 
   1126   if (offset == 0) {
   1127     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
   1128     return NULL;
   1129   }
   1130 
   1131   buffer += offset;
   1132 
   1133   AT_SKIP_REST(buffer);
   1134 
   1135   AT_CHECK_RN(buffer);
   1136 
   1137   bta_hf_client_handle_ccwa(client_cb, number, type);
   1138   return buffer;
   1139 }
   1140 
   1141 static char* bta_hf_client_parse_cops(tBTA_HF_CLIENT_CB* client_cb,
   1142                                       char* buffer) {
   1143   uint8_t mode;
   1144   /* spec forces 16 chars max, plus \0 here */
   1145   char opstr[17];
   1146   int res;
   1147   int offset = 0;
   1148 
   1149   AT_CHECK_EVENT(buffer, "+COPS:");
   1150 
   1151   /* TODO: Not sure if operator string actually can contain escaped " char
   1152    * inside */
   1153   res = sscanf(buffer, "%hhi,0,\"%16[^\"]\"%n", &mode, opstr, &offset);
   1154   if (res < 2) {
   1155     return NULL;
   1156   }
   1157   /* Abort in case offset not set because of format error */
   1158   if (offset == 0) {
   1159     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
   1160     return NULL;
   1161   }
   1162 
   1163   buffer += offset;
   1164 
   1165   AT_SKIP_REST(buffer);
   1166 
   1167   AT_CHECK_RN(buffer);
   1168 
   1169   bta_hf_client_handle_cops(client_cb, opstr, mode);
   1170   // check for OK Response in end
   1171   AT_CHECK_EVENT(buffer, "OK");
   1172   AT_CHECK_RN(buffer);
   1173 
   1174   bta_hf_client_handle_ok(client_cb);
   1175 
   1176   return buffer;
   1177 }
   1178 
   1179 static char* bta_hf_client_parse_binp(tBTA_HF_CLIENT_CB* client_cb,
   1180                                       char* buffer) {
   1181   /* HFP only supports phone number as BINP data */
   1182   /* phone number is 32 chars plus one for \0*/
   1183   char numstr[33];
   1184   int res;
   1185   int offset = 0;
   1186 
   1187   AT_CHECK_EVENT(buffer, "+BINP:");
   1188 
   1189   res = sscanf(buffer, "\"%32[^\"]\"\r\n%n", numstr, &offset);
   1190   if (res < 1) {
   1191     return NULL;
   1192   }
   1193 
   1194   /* Abort in case offset not set because of format error */
   1195   if (offset == 0) {
   1196     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
   1197     return NULL;
   1198   }
   1199 
   1200   buffer += offset;
   1201 
   1202   /* some phones might sent type as well, just skip it */
   1203   AT_SKIP_REST(buffer);
   1204 
   1205   AT_CHECK_RN(buffer);
   1206 
   1207   bta_hf_client_handle_binp(client_cb, numstr);
   1208 
   1209   // check for OK response in end
   1210   AT_CHECK_EVENT(buffer, "OK");
   1211   AT_CHECK_RN(buffer);
   1212 
   1213   bta_hf_client_handle_ok(client_cb);
   1214 
   1215   return buffer;
   1216 }
   1217 
   1218 static char* bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB* client_cb,
   1219                                       char* buffer) {
   1220   uint16_t idx, dir, status, mode, mpty;
   1221   char numstr[33]; /* spec forces 32 chars, plus one for \0*/
   1222   uint16_t type;
   1223   int res;
   1224   int offset = 0;
   1225 
   1226   AT_CHECK_EVENT(buffer, "+CLCC:");
   1227 
   1228   res = sscanf(buffer, "%hu,%hu,%hu,%hu,%hu%n", &idx, &dir, &status, &mode,
   1229                &mpty, &offset);
   1230   if (res < 5) {
   1231     return NULL;
   1232   }
   1233 
   1234   /* Abort in case offset not set because of format error */
   1235   if (offset == 0) {
   1236     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
   1237     return NULL;
   1238   }
   1239 
   1240   buffer += offset;
   1241   offset = 0;
   1242 
   1243   /* check optional part */
   1244   if (*buffer == ',') {
   1245     int res2 = sscanf(buffer, ",\"%32[^\"]\",%hu%n", numstr, &type, &offset);
   1246     if (res2 < 0) return NULL;
   1247 
   1248     if (res2 == 0) {
   1249       res2 = sscanf(buffer, ",\"\",%hu%n", &type, &offset);
   1250       if (res2 < 0) return NULL;
   1251 
   1252       /* numstr is not matched in second attempt, correct this */
   1253       res2++;
   1254       numstr[0] = '\0';
   1255     }
   1256 
   1257     if (res2 >= 2) {
   1258       res += res2;
   1259       /* Abort in case offset not set because of format error */
   1260       if (offset == 0) {
   1261         APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
   1262         return NULL;
   1263       }
   1264 
   1265       buffer += offset;
   1266     }
   1267   }
   1268 
   1269   /* Skip any remaing param,as they are not defined by BT HFP spec */
   1270   AT_SKIP_REST(buffer);
   1271   AT_CHECK_RN(buffer);
   1272 
   1273   if (res > 6) {
   1274     /* we also have last two optional parameters */
   1275     bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, numstr,
   1276                               type);
   1277   } else {
   1278     /* we didn't get the last two parameters */
   1279     bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, NULL, 0);
   1280   }
   1281 
   1282   // check for OK response in end
   1283   AT_CHECK_EVENT(buffer, "OK");
   1284   AT_CHECK_RN(buffer);
   1285 
   1286   bta_hf_client_handle_ok(client_cb);
   1287   return buffer;
   1288 }
   1289 
   1290 static char* bta_hf_client_parse_cnum(tBTA_HF_CLIENT_CB* client_cb,
   1291                                       char* buffer) {
   1292   char numstr[33]; /* spec forces 32 chars, plus one for \0*/
   1293   uint16_t type;
   1294   uint16_t service =
   1295       0; /* 0 in case this optional parameter is not being sent */
   1296   int res;
   1297   int offset = 0;
   1298 
   1299   AT_CHECK_EVENT(buffer, "+CNUM:");
   1300 
   1301   res = sscanf(buffer, ",\"%32[^\"]\",%hu,,%hu%n", numstr, &type, &service,
   1302                &offset);
   1303   if (res < 0) {
   1304     return NULL;
   1305   }
   1306 
   1307   if (res == 0) {
   1308     res = sscanf(buffer, ",\"\",%hu,,%hu%n", &type, &service, &offset);
   1309     if (res < 0) {
   1310       return NULL;
   1311     }
   1312 
   1313     /* numstr is not matched in second attempt, correct this */
   1314     res++;
   1315     numstr[0] = '\0';
   1316   }
   1317 
   1318   if (res < 3) {
   1319     return NULL;
   1320   }
   1321 
   1322   /* Abort in case offset not set because of format error */
   1323   if (offset == 0) {
   1324     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
   1325     return NULL;
   1326   }
   1327 
   1328   buffer += offset;
   1329 
   1330   AT_CHECK_RN(buffer);
   1331 
   1332   /* service is optional */
   1333   if (res == 2) {
   1334     bta_hf_client_handle_cnum(client_cb, numstr, type, service);
   1335     return buffer;
   1336   }
   1337 
   1338   if (service != 4 && service != 5) {
   1339     return NULL;
   1340   }
   1341 
   1342   bta_hf_client_handle_cnum(client_cb, numstr, type, service);
   1343 
   1344   // check for OK response in end
   1345   AT_CHECK_EVENT(buffer, "OK");
   1346   AT_CHECK_RN(buffer);
   1347 
   1348   bta_hf_client_handle_ok(client_cb);
   1349   return buffer;
   1350 }
   1351 
   1352 static char* bta_hf_client_parse_btrh(tBTA_HF_CLIENT_CB* client_cb,
   1353                                       char* buffer) {
   1354   uint16_t code = 0;
   1355   int res;
   1356   int offset;
   1357 
   1358   AT_CHECK_EVENT(buffer, "+BTRH:");
   1359 
   1360   res = sscanf(buffer, "%hu%n", &code, &offset);
   1361   if (res < 1) {
   1362     return NULL;
   1363   }
   1364 
   1365   buffer += offset;
   1366 
   1367   AT_CHECK_RN(buffer);
   1368 
   1369   bta_hf_client_handle_btrh(client_cb, code);
   1370   return buffer;
   1371 }
   1372 
   1373 static char* bta_hf_client_parse_busy(tBTA_HF_CLIENT_CB* client_cb,
   1374                                       char* buffer) {
   1375   AT_CHECK_EVENT(buffer, "BUSY");
   1376   AT_CHECK_RN(buffer);
   1377 
   1378   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_BUSY, 0);
   1379 
   1380   return buffer;
   1381 }
   1382 
   1383 static char* bta_hf_client_parse_delayed(tBTA_HF_CLIENT_CB* client_cb,
   1384                                          char* buffer) {
   1385   AT_CHECK_EVENT(buffer, "DELAYED");
   1386   AT_CHECK_RN(buffer);
   1387 
   1388   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_DELAY, 0);
   1389 
   1390   return buffer;
   1391 }
   1392 
   1393 static char* bta_hf_client_parse_no_carrier(tBTA_HF_CLIENT_CB* client_cb,
   1394                                             char* buffer) {
   1395   AT_CHECK_EVENT(buffer, "NO CARRIER");
   1396   AT_CHECK_RN(buffer);
   1397 
   1398   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_CARRIER, 0);
   1399 
   1400   return buffer;
   1401 }
   1402 
   1403 static char* bta_hf_client_parse_no_answer(tBTA_HF_CLIENT_CB* client_cb,
   1404                                            char* buffer) {
   1405   AT_CHECK_EVENT(buffer, "NO ANSWER");
   1406   AT_CHECK_RN(buffer);
   1407 
   1408   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_ANSWER, 0);
   1409 
   1410   return buffer;
   1411 }
   1412 
   1413 static char* bta_hf_client_parse_blacklisted(tBTA_HF_CLIENT_CB* client_cb,
   1414                                              char* buffer) {
   1415   AT_CHECK_EVENT(buffer, "BLACKLISTED");
   1416   AT_CHECK_RN(buffer);
   1417 
   1418   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_BLACKLISTED, 0);
   1419 
   1420   return buffer;
   1421 }
   1422 
   1423 static char* bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB* client_cb,
   1424                                         char* buffer) {
   1425   char* start;
   1426   char* tmp;
   1427 
   1428   tmp = strstr(buffer, "\r\n");
   1429   if (tmp == NULL) {
   1430     return NULL;
   1431   }
   1432 
   1433   buffer += 2;
   1434   start = buffer;
   1435 
   1436   tmp = strstr(buffer, "\r\n");
   1437   if (tmp == NULL) {
   1438     return NULL;
   1439   }
   1440 
   1441   buffer = tmp + 2;
   1442 
   1443   APPL_TRACE_DEBUG("%s: %.*s", __func__, buffer - start - 2, start);
   1444 
   1445   return buffer;
   1446 }
   1447 
   1448 /******************************************************************************
   1449  *       SUPPORTED EVENT MESSAGES
   1450  ******************************************************************************/
   1451 
   1452 /* returned values are as follow:
   1453  * != NULL && != buf  : match and parsed ok
   1454  * == NULL            : match but parse failed
   1455  * != NULL && == buf  : no match
   1456  */
   1457 typedef char* (*tBTA_HF_CLIENT_PARSER_CALLBACK)(tBTA_HF_CLIENT_CB*, char*);
   1458 
   1459 static const tBTA_HF_CLIENT_PARSER_CALLBACK bta_hf_client_parser_cb[] = {
   1460     bta_hf_client_parse_ok,          bta_hf_client_parse_error,
   1461     bta_hf_client_parse_ring,        bta_hf_client_parse_brsf,
   1462     bta_hf_client_parse_cind,        bta_hf_client_parse_ciev,
   1463     bta_hf_client_parse_chld,        bta_hf_client_parse_bcs,
   1464     bta_hf_client_parse_bsir,        bta_hf_client_parse_cmeerror,
   1465     bta_hf_client_parse_vgm,         bta_hf_client_parse_vgme,
   1466     bta_hf_client_parse_vgs,         bta_hf_client_parse_vgse,
   1467     bta_hf_client_parse_bvra,        bta_hf_client_parse_clip,
   1468     bta_hf_client_parse_ccwa,        bta_hf_client_parse_cops,
   1469     bta_hf_client_parse_binp,        bta_hf_client_parse_clcc,
   1470     bta_hf_client_parse_cnum,        bta_hf_client_parse_btrh,
   1471     bta_hf_client_parse_busy,        bta_hf_client_parse_delayed,
   1472     bta_hf_client_parse_no_carrier,  bta_hf_client_parse_no_answer,
   1473     bta_hf_client_parse_blacklisted, bta_hf_client_skip_unknown};
   1474 
   1475 /* calculate supported event list length */
   1476 static const uint16_t bta_hf_client_parser_cb_count =
   1477     sizeof(bta_hf_client_parser_cb) / sizeof(bta_hf_client_parser_cb[0]);
   1478 
   1479 #ifdef BTA_HF_CLIENT_AT_DUMP
   1480 static void bta_hf_client_dump_at(tBTA_HF_CLIENT_CB* client_cb) {
   1481   char dump[(4 * BTA_HF_CLIENT_AT_PARSER_MAX_LEN) + 1];
   1482   char *p1, *p2;
   1483 
   1484   p1 = client_cb->at_cb.buf;
   1485   p2 = dump;
   1486 
   1487   while (*p1 != '\0') {
   1488     if (*p1 == '\r') {
   1489       strlcpy(p2, "<cr>", 4);
   1490       p2 += 4;
   1491     } else if (*p1 == '\n') {
   1492       strlcpy(p2, "<lf>", 4);
   1493       p2 += 4;
   1494     } else {
   1495       *p2 = *p1;
   1496       p2++;
   1497     }
   1498     p1++;
   1499   }
   1500 
   1501   *p2 = '\0';
   1502 
   1503   APPL_TRACE_DEBUG("%s: %s", __func__, dump);
   1504 }
   1505 #endif
   1506 
   1507 static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) {
   1508   char* buf = client_cb->at_cb.buf;
   1509 
   1510   APPL_TRACE_DEBUG("%s", __func__);
   1511 
   1512 #ifdef BTA_HF_CLIENT_AT_DUMP
   1513   bta_hf_client_dump_at(client_cb);
   1514 #endif
   1515 
   1516   while (*buf != '\0') {
   1517     int i;
   1518     char* tmp = NULL;
   1519 
   1520     for (i = 0; i < bta_hf_client_parser_cb_count; i++) {
   1521       tmp = bta_hf_client_parser_cb[i](client_cb, buf);
   1522       if (tmp == NULL) {
   1523         APPL_TRACE_ERROR("HFPCient: AT event/reply parsing failed, skipping");
   1524         tmp = bta_hf_client_skip_unknown(client_cb, buf);
   1525         break;
   1526       }
   1527 
   1528       /* matched or unknown skipped, if unknown failed tmp is NULL so
   1529          this is also handled */
   1530       if (tmp != buf) {
   1531         buf = tmp;
   1532         break;
   1533       }
   1534     }
   1535 
   1536     /* could not skip unknown (received garbage?)... disconnect */
   1537     if (tmp == NULL) {
   1538       APPL_TRACE_ERROR(
   1539           "HFPCient: could not skip unknown AT event, disconnecting");
   1540       bta_hf_client_at_reset(client_cb);
   1541 
   1542       tBTA_HF_CLIENT_DATA msg;
   1543       msg.hdr.layer_specific = client_cb->handle;
   1544       bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
   1545       return;
   1546     }
   1547 
   1548     buf = tmp;
   1549   }
   1550 }
   1551 
   1552 static bool bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB* client_cb) {
   1553   bool ret = false;
   1554   tBTA_HF_CLIENT_AT_CB* at_cb = &client_cb->at_cb;
   1555 
   1556   if (at_cb->offset >= BTA_HF_CLIENT_AT_EVENT_MIN_LEN) {
   1557     if (at_cb->buf[at_cb->offset - 2] == '\r' &&
   1558         at_cb->buf[at_cb->offset - 1] == '\n') {
   1559       ret = true;
   1560     }
   1561   }
   1562 
   1563   APPL_TRACE_DEBUG("%s: %d", __func__, ret);
   1564 
   1565   return ret;
   1566 }
   1567 
   1568 static void bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB* client_cb) {
   1569   memset(client_cb->at_cb.buf, 0, sizeof(client_cb->at_cb.buf));
   1570   client_cb->at_cb.offset = 0;
   1571 }
   1572 
   1573 /******************************************************************************
   1574  *
   1575  *          MAIN PARSING FUNCTION
   1576  *
   1577  *
   1578  ******************************************************************************/
   1579 void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf,
   1580                             unsigned int len) {
   1581   APPL_TRACE_DEBUG("%s: offset: %u len: %u", __func__, client_cb->at_cb.offset,
   1582                    len);
   1583 
   1584   if (len + client_cb->at_cb.offset > BTA_HF_CLIENT_AT_PARSER_MAX_LEN) {
   1585     char tmp_buff[BTA_HF_CLIENT_AT_PARSER_MAX_LEN];
   1586     unsigned int tmp = client_cb->at_cb.offset;
   1587     unsigned int space_left =
   1588         BTA_HF_CLIENT_AT_PARSER_MAX_LEN - client_cb->at_cb.offset;
   1589 
   1590     APPL_TRACE_DEBUG("%s: overrun, trying to recover", __func__);
   1591 
   1592     /* fill up parser buffer */
   1593     memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, space_left);
   1594     len -= space_left;
   1595     buf += space_left;
   1596     client_cb->at_cb.offset += space_left;
   1597 
   1598     /* find end of last complete command before proceeding */
   1599     while (bta_hf_client_check_at_complete(client_cb) == false) {
   1600       if (client_cb->at_cb.offset == 0) {
   1601         APPL_TRACE_ERROR("HFPClient: AT parser buffer overrun, disconnecting");
   1602 
   1603         bta_hf_client_at_reset(client_cb);
   1604 
   1605         tBTA_HF_CLIENT_DATA msg;
   1606         msg.hdr.layer_specific = client_cb->handle;
   1607         bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
   1608         return;
   1609       }
   1610 
   1611       client_cb->at_cb.offset--;
   1612     }
   1613 
   1614     /* cut buffer to complete AT event and keep cut data */
   1615     tmp += space_left - client_cb->at_cb.offset;
   1616     memcpy(tmp_buff, client_cb->at_cb.buf + client_cb->at_cb.offset, tmp);
   1617     client_cb->at_cb.buf[client_cb->at_cb.offset] = '\0';
   1618 
   1619     /* parse */
   1620     bta_hf_client_at_parse_start(client_cb);
   1621     bta_hf_client_at_clear_buf(client_cb);
   1622 
   1623     /* recover cut data */
   1624     memcpy(client_cb->at_cb.buf, tmp_buff, tmp);
   1625     client_cb->at_cb.offset += tmp;
   1626   }
   1627 
   1628   memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, len);
   1629   client_cb->at_cb.offset += len;
   1630 
   1631   /* If last event is complete, parsing can be started */
   1632   if (bta_hf_client_check_at_complete(client_cb) == true) {
   1633     bta_hf_client_at_parse_start(client_cb);
   1634     bta_hf_client_at_clear_buf(client_cb);
   1635   }
   1636 }
   1637 
   1638 void bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB* client_cb,
   1639                                 tBTA_HF_CLIENT_FEAT features) {
   1640   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1641   int at_len;
   1642 
   1643   APPL_TRACE_DEBUG("%s", __func__);
   1644 
   1645   at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%u\r", features);
   1646   if (at_len < 0) {
   1647     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   1648     return;
   1649   }
   1650 
   1651   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BRSF, buf, at_len);
   1652 }
   1653 
   1654 void bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB* client_cb) {
   1655   const char* buf;
   1656 
   1657   APPL_TRACE_DEBUG("%s", __func__);
   1658 
   1659   buf = "AT+BAC=1,2\r";
   1660 
   1661   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BAC, buf, strlen(buf));
   1662 }
   1663 
   1664 void bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB* client_cb, uint32_t codec) {
   1665   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1666   int at_len;
   1667 
   1668   APPL_TRACE_DEBUG("%s", __func__);
   1669 
   1670   at_len = snprintf(buf, sizeof(buf), "AT+BCS=%u\r", codec);
   1671   if (at_len < 0) {
   1672     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   1673     return;
   1674   }
   1675 
   1676   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCS, buf, at_len);
   1677 }
   1678 
   1679 void bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB* client_cb, bool status) {
   1680   const char* buf;
   1681   tBTA_HF_CLIENT_AT_CMD cmd;
   1682 
   1683   APPL_TRACE_DEBUG("%s", __func__);
   1684 
   1685   if (status) {
   1686     buf = "AT+CIND?\r";
   1687     cmd = BTA_HF_CLIENT_AT_CIND_STATUS;
   1688   } else {
   1689     buf = "AT+CIND=?\r";
   1690     cmd = BTA_HF_CLIENT_AT_CIND;
   1691   }
   1692 
   1693   bta_hf_client_send_at(client_cb, cmd, buf, strlen(buf));
   1694 }
   1695 
   1696 void bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
   1697   const char* buf;
   1698 
   1699   APPL_TRACE_DEBUG("%s", __func__);
   1700 
   1701   if (activate)
   1702     buf = "AT+CMER=3,0,0,1\r";
   1703   else
   1704     buf = "AT+CMER=3,0,0,0\r";
   1705 
   1706   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMER, buf, strlen(buf));
   1707 }
   1708 
   1709 void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd,
   1710                                 uint32_t idx) {
   1711   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1712   int at_len;
   1713 
   1714   APPL_TRACE_DEBUG("%s", __func__);
   1715 
   1716   if (idx > 0)
   1717     at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c%u\r", cmd, idx);
   1718   else
   1719     at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd);
   1720 
   1721   if (at_len < 0) {
   1722     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   1723     return;
   1724   }
   1725 
   1726   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHLD, buf, at_len);
   1727 }
   1728 
   1729 void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
   1730   const char* buf;
   1731 
   1732   APPL_TRACE_DEBUG("%s", __func__);
   1733 
   1734   if (activate)
   1735     buf = "AT+CLIP=1\r";
   1736   else
   1737     buf = "AT+CLIP=0\r";
   1738 
   1739   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLIP, buf, strlen(buf));
   1740 }
   1741 
   1742 void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
   1743   const char* buf;
   1744 
   1745   APPL_TRACE_DEBUG("%s", __func__);
   1746 
   1747   if (activate)
   1748     buf = "AT+CCWA=1\r";
   1749   else
   1750     buf = "AT+CCWA=0\r";
   1751 
   1752   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CCWA, buf, strlen(buf));
   1753 }
   1754 
   1755 void bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
   1756   const char* buf;
   1757 
   1758   APPL_TRACE_DEBUG("%s", __func__);
   1759 
   1760   if (activate)
   1761     buf = "AT+CMEE=1\r";
   1762   else
   1763     buf = "AT+CMEE=0\r";
   1764 
   1765   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMEE, buf, strlen(buf));
   1766 }
   1767 
   1768 void bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB* client_cb, bool query) {
   1769   const char* buf;
   1770 
   1771   APPL_TRACE_DEBUG("%s", __func__);
   1772 
   1773   if (query)
   1774     buf = "AT+COPS?\r";
   1775   else
   1776     buf = "AT+COPS=3,0\r";
   1777 
   1778   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_COPS, buf, strlen(buf));
   1779 }
   1780 
   1781 void bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB* client_cb) {
   1782   const char* buf;
   1783 
   1784   APPL_TRACE_DEBUG("%s", __func__);
   1785 
   1786   buf = "AT+CLCC\r";
   1787 
   1788   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLCC, buf, strlen(buf));
   1789 }
   1790 
   1791 void bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB* client_cb, bool enable) {
   1792   const char* buf;
   1793 
   1794   APPL_TRACE_DEBUG("%s", __func__);
   1795 
   1796   if (enable)
   1797     buf = "AT+BVRA=1\r";
   1798   else
   1799     buf = "AT+BVRA=0\r";
   1800 
   1801   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BVRA, buf, strlen(buf));
   1802 }
   1803 
   1804 void bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
   1805   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1806   int at_len;
   1807 
   1808   APPL_TRACE_DEBUG("%s", __func__);
   1809 
   1810   at_len = snprintf(buf, sizeof(buf), "AT+VGS=%u\r", volume);
   1811   if (at_len < 0) {
   1812     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   1813     return;
   1814   }
   1815 
   1816   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGS, buf, at_len);
   1817 }
   1818 
   1819 void bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
   1820   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1821   int at_len;
   1822 
   1823   APPL_TRACE_DEBUG("%s", __func__);
   1824 
   1825   at_len = snprintf(buf, sizeof(buf), "AT+VGM=%u\r", volume);
   1826   if (at_len < 0) {
   1827     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   1828     return;
   1829   }
   1830 
   1831   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGM, buf, at_len);
   1832 }
   1833 
   1834 void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb, char* number,
   1835                                uint32_t memory) {
   1836   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1837   int at_len;
   1838 
   1839   APPL_TRACE_DEBUG("%s", __func__);
   1840 
   1841   if (number[0] != '\0') {
   1842     at_len = snprintf(buf, sizeof(buf), "ATD%s;\r", number);
   1843   } else {
   1844     at_len = snprintf(buf, sizeof(buf), "ATD>%u;\r", memory);
   1845   }
   1846 
   1847   if (at_len < 0) {
   1848     APPL_TRACE_ERROR("%s: error preparing ATD command", __func__);
   1849     return;
   1850   }
   1851 
   1852   at_len = MIN((size_t)at_len, sizeof(buf));
   1853 
   1854   if (at_len < 0) {
   1855     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   1856     return;
   1857   }
   1858   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATD, buf, at_len);
   1859 }
   1860 
   1861 void bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB* client_cb) {
   1862   const char* buf;
   1863 
   1864   APPL_TRACE_DEBUG("%s", __func__);
   1865 
   1866   buf = "AT+BLDN\r";
   1867 
   1868   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BLDN, buf, strlen(buf));
   1869 }
   1870 
   1871 void bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB* client_cb) {
   1872   const char* buf;
   1873 
   1874   APPL_TRACE_DEBUG("%s", __func__);
   1875 
   1876   buf = "ATA\r";
   1877 
   1878   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATA, buf, strlen(buf));
   1879 }
   1880 
   1881 void bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB* client_cb) {
   1882   const char* buf;
   1883 
   1884   APPL_TRACE_DEBUG("%s", __func__);
   1885 
   1886   buf = "AT+CHUP\r";
   1887 
   1888   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHUP, buf, strlen(buf));
   1889 }
   1890 
   1891 void bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB* client_cb, bool query,
   1892                                 uint32_t val) {
   1893   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1894   int at_len;
   1895 
   1896   APPL_TRACE_DEBUG("%s", __func__);
   1897 
   1898   if (query == true) {
   1899     at_len = snprintf(buf, sizeof(buf), "AT+BTRH?\r");
   1900   } else {
   1901     at_len = snprintf(buf, sizeof(buf), "AT+BTRH=%u\r", val);
   1902   }
   1903 
   1904   if (at_len < 0) {
   1905     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   1906     return;
   1907   }
   1908 
   1909   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BTRH, buf, at_len);
   1910 }
   1911 
   1912 void bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB* client_cb, char code) {
   1913   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1914   int at_len;
   1915 
   1916   APPL_TRACE_DEBUG("%s", __func__);
   1917 
   1918   at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code);
   1919 
   1920   if (at_len < 0) {
   1921     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   1922     return;
   1923   }
   1924 
   1925   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VTS, buf, at_len);
   1926 }
   1927 
   1928 void bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB* client_cb) {
   1929   const char* buf;
   1930 
   1931   APPL_TRACE_DEBUG("%s", __func__);
   1932 
   1933   buf = "AT+BCC\r";
   1934 
   1935   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCC, buf, strlen(buf));
   1936 
   1937   // At this point we should also open up an incoming SCO connection
   1938   tBTA_HF_CLIENT_DATA p_data;
   1939   p_data.hdr.layer_specific = client_cb->handle;
   1940   bta_hf_client_sco_listen(&p_data);
   1941 }
   1942 
   1943 void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb) {
   1944   const char* buf;
   1945 
   1946   APPL_TRACE_DEBUG("%s", __func__);
   1947 
   1948   buf = "AT+CNUM\r";
   1949 
   1950   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CNUM, buf, strlen(buf));
   1951 }
   1952 
   1953 void bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB* client_cb) {
   1954   const char* buf;
   1955 
   1956   APPL_TRACE_DEBUG("%s", __func__);
   1957 
   1958   if (!(client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_ECNR)) {
   1959     APPL_TRACE_ERROR("%s: Remote does not support NREC.", __func__);
   1960     return;
   1961   }
   1962 
   1963   buf = "AT+NREC=0\r";
   1964 
   1965   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_NREC, buf, strlen(buf));
   1966 }
   1967 
   1968 void bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB* client_cb, uint32_t action) {
   1969   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1970   int at_len;
   1971 
   1972   APPL_TRACE_DEBUG("%s", __func__);
   1973 
   1974   at_len = snprintf(buf, sizeof(buf), "AT+BINP=%u\r", action);
   1975 
   1976   if (at_len < 0) {
   1977     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   1978     return;
   1979   }
   1980 
   1981   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BINP, buf, at_len);
   1982 }
   1983 
   1984 void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb) {
   1985   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   1986   int at_len;
   1987   int i;
   1988 
   1989   APPL_TRACE_DEBUG("%s", __func__);
   1990   if (client_cb->peer_version < HFP_VERSION_1_6) {
   1991     APPL_TRACE_DEBUG("Remote does not Support AT+BIA");
   1992     return;
   1993   }
   1994 
   1995   at_len = snprintf(buf, sizeof(buf), "AT+BIA=");
   1996 
   1997   for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
   1998     int sup = client_cb->at_cb.indicator_lookup[i] == -1 ? 0 : 1;
   1999 
   2000     at_len += snprintf(buf + at_len, sizeof(buf) - at_len, "%u,", sup);
   2001   }
   2002 
   2003   buf[at_len - 1] = '\r';
   2004 
   2005   if (at_len < 0) {
   2006     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
   2007     return;
   2008   }
   2009 
   2010   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BIA, buf, at_len);
   2011 }
   2012 
   2013 void bta_hf_client_at_init(tBTA_HF_CLIENT_CB* client_cb) {
   2014   alarm_free(client_cb->at_cb.resp_timer);
   2015   alarm_free(client_cb->at_cb.hold_timer);
   2016   memset(&(client_cb->at_cb), 0, sizeof(tBTA_HF_CLIENT_AT_CB));
   2017   client_cb->at_cb.resp_timer = alarm_new("bta_hf_client.scb_at_resp_timer");
   2018   client_cb->at_cb.hold_timer = alarm_new("bta_hf_client.scb_at_hold_timer");
   2019   bta_hf_client_at_reset(client_cb);
   2020 }
   2021 
   2022 void bta_hf_client_at_reset(tBTA_HF_CLIENT_CB* client_cb) {
   2023   int i;
   2024 
   2025   bta_hf_client_stop_at_resp_timer(client_cb);
   2026   bta_hf_client_stop_at_hold_timer(client_cb);
   2027 
   2028   bta_hf_client_clear_queued_at(client_cb);
   2029 
   2030   bta_hf_client_at_clear_buf(client_cb);
   2031 
   2032   for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
   2033     client_cb->at_cb.indicator_lookup[i] = -1;
   2034   }
   2035 
   2036   client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
   2037 }
   2038 
   2039 void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) {
   2040   tBTA_HF_CLIENT_CB* client_cb =
   2041       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
   2042   if (!client_cb) {
   2043     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
   2044                      p_data->hdr.layer_specific);
   2045     return;
   2046   }
   2047 
   2048   tBTA_HF_CLIENT_DATA_VAL* p_val = (tBTA_HF_CLIENT_DATA_VAL*)p_data;
   2049   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
   2050 
   2051   APPL_TRACE_DEBUG("%s: at cmd: %d", __func__, p_val->uint8_val);
   2052   switch (p_val->uint8_val) {
   2053     case BTA_HF_CLIENT_AT_CMD_VTS:
   2054       bta_hf_client_send_at_vts(client_cb, (char)p_val->uint32_val1);
   2055       break;
   2056     case BTA_HF_CLIENT_AT_CMD_BTRH:
   2057       bta_hf_client_send_at_btrh(client_cb, false, p_val->uint32_val1);
   2058       break;
   2059     case BTA_HF_CLIENT_AT_CMD_CHUP:
   2060       bta_hf_client_send_at_chup(client_cb);
   2061       break;
   2062     case BTA_HF_CLIENT_AT_CMD_CHLD:
   2063       /* expects ascii code for command */
   2064       bta_hf_client_send_at_chld(client_cb, '0' + p_val->uint32_val1,
   2065                                  p_val->uint32_val2);
   2066       break;
   2067     case BTA_HF_CLIENT_AT_CMD_BCC:
   2068       bta_hf_client_send_at_bcc(client_cb);
   2069       break;
   2070     case BTA_HF_CLIENT_AT_CMD_CNUM:
   2071       bta_hf_client_send_at_cnum(client_cb);
   2072       break;
   2073     case BTA_HF_CLIENT_AT_CMD_ATA:
   2074       bta_hf_client_send_at_ata(client_cb);
   2075       break;
   2076     case BTA_HF_CLIENT_AT_CMD_COPS:
   2077       bta_hf_client_send_at_cops(client_cb, true);
   2078       break;
   2079     case BTA_HF_CLIENT_AT_CMD_ATD:
   2080       bta_hf_client_send_at_atd(client_cb, p_val->str, p_val->uint32_val1);
   2081       break;
   2082     case BTA_HF_CLIENT_AT_CMD_VGM:
   2083       bta_hf_client_send_at_vgm(client_cb, p_val->uint32_val1);
   2084       break;
   2085     case BTA_HF_CLIENT_AT_CMD_VGS:
   2086       bta_hf_client_send_at_vgs(client_cb, p_val->uint32_val1);
   2087       break;
   2088     case BTA_HF_CLIENT_AT_CMD_BVRA:
   2089       bta_hf_client_send_at_bvra(client_cb,
   2090                                  p_val->uint32_val1 == 0 ? false : true);
   2091       break;
   2092     case BTA_HF_CLIENT_AT_CMD_CLCC:
   2093       bta_hf_client_send_at_clcc(client_cb);
   2094       break;
   2095     case BTA_HF_CLIENT_AT_CMD_BINP:
   2096       bta_hf_client_send_at_binp(client_cb, p_val->uint32_val1);
   2097       break;
   2098     case BTA_HF_CLIENT_AT_CMD_BLDN:
   2099       bta_hf_client_send_at_bldn(client_cb);
   2100       break;
   2101     case BTA_HF_CLIENT_AT_CMD_NREC:
   2102       bta_hf_client_send_at_nrec(client_cb);
   2103       break;
   2104     default:
   2105       APPL_TRACE_ERROR("Default case");
   2106       snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN,
   2107                "Cmd %d 1st arg %u 2nd arg %u string arg %s", p_val->uint8_val,
   2108                p_val->uint32_val1, p_val->uint32_val2, p_val->str);
   2109       APPL_TRACE_ERROR("%s: AT buffer: %s ", __func__, buf);
   2110       break;
   2111   }
   2112 }
   2113