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