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