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 /******************************************************************************
     21  *
     22  *  This file contains action functions for the handsfree client.
     23  *
     24  ******************************************************************************/
     25 
     26 #include "bta_api.h"
     27 #include "bta_hf_client_api.h"
     28 #include "bta_hf_client_int.h"
     29 #include "bta_dm_int.h"
     30 #include "l2c_api.h"
     31 #include "port_api.h"
     32 #include "bta_sys.h"
     33 #include "utl.h"
     34 #include "bt_utils.h"
     35 #include "osi/include/compat.h"
     36 #include <string.h>
     37 
     38 /*****************************************************************************
     39 **  Constants
     40 *****************************************************************************/
     41 
     42 /* maximum length of data to read from RFCOMM */
     43 #define BTA_HF_CLIENT_RFC_READ_MAX     512
     44 
     45 /*******************************************************************************
     46 **
     47 ** Function         bta_hf_client_register
     48 **
     49 ** Description      This function initializes values of the scb and sets up
     50 **                  the SDP record for the services.
     51 **
     52 **
     53 ** Returns          void
     54 **
     55 *******************************************************************************/
     56 void bta_hf_client_register(tBTA_HF_CLIENT_DATA *p_data)
     57 {
     58     tBTA_HF_CLIENT evt;
     59     tBTA_UTL_COD   cod;
     60 
     61     memset(&evt, 0, sizeof(evt));
     62 
     63     /* initialize control block */
     64     bta_hf_client_scb_init();
     65 
     66     bta_hf_client_cb.scb.serv_sec_mask = p_data->api_register.sec_mask;
     67     bta_hf_client_cb.scb.features = p_data->api_register.features;
     68 
     69     /* initialize AT control block */
     70     bta_hf_client_at_init();
     71 
     72     /* create SDP records */
     73     bta_hf_client_create_record(p_data);
     74 
     75     /* Set the Audio service class bit */
     76     cod.service = BTM_COD_SERVICE_AUDIO;
     77     utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
     78 
     79     /* start RFCOMM server */
     80     bta_hf_client_start_server();
     81 
     82     /* call app callback with register event */
     83     evt.reg.status = BTA_HF_CLIENT_SUCCESS;
     84     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_REGISTER_EVT, &evt);
     85 }
     86 
     87 /*******************************************************************************
     88 **
     89 ** Function         bta_hf_client_deregister
     90 **
     91 ** Description      This function removes the sdp records, closes the RFCOMM
     92 **                  servers, and deallocates the service control block.
     93 **
     94 **
     95 ** Returns          void
     96 **
     97 *******************************************************************************/
     98 void bta_hf_client_deregister(tBTA_HF_CLIENT_DATA *p_data)
     99 {
    100     bta_hf_client_cb.scb.deregister = TRUE;
    101 
    102     /* remove sdp record */
    103     bta_hf_client_del_record(p_data);
    104 
    105     /* remove rfcomm server */
    106     bta_hf_client_close_server();
    107 
    108     /* disable */
    109     bta_hf_client_scb_disable();
    110 }
    111 
    112 /*******************************************************************************
    113 **
    114 ** Function         bta_hf_client_start_dereg
    115 **
    116 ** Description      Start a deregister event.
    117 **
    118 **
    119 ** Returns          void
    120 **
    121 *******************************************************************************/
    122 void bta_hf_client_start_dereg(tBTA_HF_CLIENT_DATA *p_data)
    123 {
    124     bta_hf_client_cb.scb.deregister = TRUE;
    125 
    126     /* remove sdp record */
    127     bta_hf_client_del_record(p_data);
    128 }
    129 
    130 /*******************************************************************************
    131 **
    132 ** Function         bta_hf_client_start_close
    133 **
    134 ** Description      Start the process of closing SCO and RFCOMM connection.
    135 **
    136 **
    137 ** Returns          void
    138 **
    139 *******************************************************************************/
    140 void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA *p_data)
    141 {
    142     /* Take the link out of sniff and set L2C idle time to 0 */
    143     bta_dm_pm_active(bta_hf_client_cb.scb.peer_addr);
    144     L2CA_SetIdleTimeoutByBdAddr(bta_hf_client_cb.scb.peer_addr, 0, BT_TRANSPORT_BR_EDR);
    145 
    146     /* if SCO is open close SCO and wait on RFCOMM close */
    147     if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_OPEN_ST)
    148     {
    149         bta_hf_client_cb.scb.sco_close_rfc = TRUE;
    150     }
    151     else
    152     {
    153         bta_hf_client_rfc_do_close(p_data);
    154     }
    155 
    156     /* always do SCO shutdown to handle all SCO corner cases */
    157     bta_hf_client_sco_shutdown(NULL);
    158 }
    159 
    160 /*******************************************************************************
    161 **
    162 ** Function         bta_hf_client_start_open
    163 **
    164 ** Description      This starts an HF Client open.
    165 **
    166 **
    167 ** Returns          void
    168 **
    169 *******************************************************************************/
    170 void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA *p_data)
    171 {
    172     BD_ADDR pending_bd_addr;
    173 
    174     /* store parameters */
    175     if (p_data)
    176     {
    177         bdcpy(bta_hf_client_cb.scb.peer_addr, p_data->api_open.bd_addr);
    178         bta_hf_client_cb.scb.cli_sec_mask = p_data->api_open.sec_mask;
    179     }
    180 
    181     /* Check if RFCOMM has any incoming connection to avoid collision. */
    182     if (PORT_IsOpening (pending_bd_addr))
    183     {
    184         /* Let the incoming connection goes through.                        */
    185         /* Issue collision for now.                                         */
    186         /* We will decide what to do when we find incoming connection later.*/
    187         bta_hf_client_collision_cback (0, BTA_ID_HS, 0, bta_hf_client_cb.scb.peer_addr);
    188         return;
    189     }
    190 
    191     /* close server */
    192     bta_hf_client_close_server();
    193 
    194     /* set role */
    195     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_INT;
    196 
    197     /* do service search */
    198     bta_hf_client_do_disc();
    199 }
    200 
    201 /*******************************************************************************
    202 **
    203 ** Function         bta_hf_client_cback_open
    204 **
    205 ** Description      Send open callback event to application.
    206 **
    207 **
    208 ** Returns          void
    209 **
    210 *******************************************************************************/
    211 static void bta_hf_client_cback_open(tBTA_HF_CLIENT_DATA *p_data, tBTA_HF_CLIENT_STATUS status)
    212 {
    213     tBTA_HF_CLIENT evt;
    214 
    215     memset(&evt, 0, sizeof(evt));
    216 
    217     /* call app callback with open event */
    218     evt.open.status = status;
    219     if(p_data)
    220     {
    221         /* if p_data is provided then we need to pick the bd address from the open api structure */
    222         bdcpy(evt.open.bd_addr, p_data->api_open.bd_addr);
    223     }
    224     else
    225     {
    226         bdcpy(evt.open.bd_addr, bta_hf_client_cb.scb.peer_addr);
    227     }
    228 
    229     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPEN_EVT, &evt);
    230 }
    231 
    232 /*******************************************************************************
    233 **
    234 ** Function         bta_hf_client_rfc_open
    235 **
    236 ** Description      Handle RFCOMM channel open.
    237 **
    238 **
    239 ** Returns          void
    240 **
    241 *******************************************************************************/
    242 void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA *p_data)
    243 {
    244     UNUSED(p_data);
    245 
    246     bta_sys_conn_open(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
    247 
    248     bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_SUCCESS);
    249 
    250     /* start SLC procedure */
    251     bta_hf_client_slc_seq(FALSE);
    252 }
    253 
    254 /*******************************************************************************
    255 **
    256 ** Function         bta_hf_client_rfc_acp_open
    257 **
    258 ** Description      Handle RFCOMM channel open when accepting connection.
    259 **
    260 **
    261 ** Returns          void
    262 **
    263 *******************************************************************************/
    264 void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data)
    265 {
    266     UINT16          lcid;
    267     BD_ADDR         dev_addr;
    268     int             status;
    269 
    270     /* set role */
    271     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
    272 
    273     APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open: serv_handle = %d rfc.port_handle = %d",
    274             bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle);
    275 
    276     /* get bd addr of peer */
    277     if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid)))
    278     {
    279         APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status);
    280     }
    281 
    282     /* Collision Handling */
    283     if (bta_hf_client_cb.scb.colli_tmr_on)
    284     {
    285         /* stop collision timer */
    286         bta_hf_client_cb.scb.colli_tmr_on = FALSE;
    287         bta_sys_stop_timer (&bta_hf_client_cb.scb.colli_timer);
    288 
    289         if (bdcmp (dev_addr, bta_hf_client_cb.scb.peer_addr) == 0)
    290         {
    291             /* If incoming and outgoing device are same, nothing more to do.            */
    292             /* Outgoing conn will be aborted because we have successful incoming conn.  */
    293         }
    294         else
    295         {
    296             /* Resume outgoing connection. */
    297             bta_hf_client_resume_open ();
    298         }
    299     }
    300 
    301     bdcpy (bta_hf_client_cb.scb.peer_addr, dev_addr);
    302     bta_hf_client_cb.scb.conn_handle = p_data->rfc.port_handle;
    303 
    304     /* do service discovery to get features */
    305     bta_hf_client_do_disc();
    306 
    307     /* continue with open processing */
    308     bta_hf_client_rfc_open(p_data);
    309 }
    310 
    311 /*******************************************************************************
    312 **
    313 ** Function         bta_hf_client_rfc_fail
    314 **
    315 ** Description      RFCOMM connection failed.
    316 **
    317 **
    318 ** Returns          void
    319 **
    320 *******************************************************************************/
    321 void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA *p_data)
    322 {
    323     UNUSED(p_data);
    324 
    325     /* reinitialize stuff */
    326     bta_hf_client_cb.scb.conn_handle = 0;
    327     bta_hf_client_cb.scb.peer_features = 0;
    328     bta_hf_client_cb.scb.chld_features = 0;
    329     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
    330     bta_hf_client_cb.scb.svc_conn = FALSE;
    331     bta_hf_client_cb.scb.send_at_reply = FALSE;
    332     bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
    333 
    334     bta_hf_client_at_reset();
    335 
    336     /* reopen server */
    337     bta_hf_client_start_server();
    338 
    339     /* call open cback w. failure */
    340     bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_RFCOMM);
    341 }
    342 
    343 /*******************************************************************************
    344 **
    345 ** Function         bta_hf_client_disc_fail
    346 **
    347 ** Description      This function handles a discovery failure.
    348 **
    349 **
    350 ** Returns          void
    351 **
    352 *******************************************************************************/
    353 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA *p_data)
    354 {
    355     UNUSED(p_data);
    356 
    357     /* reopen server */
    358     bta_hf_client_start_server();
    359 
    360     /* reinitialize stuff */
    361 
    362     /* call open cback w. failure */
    363     bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_SDP);
    364 }
    365 
    366 /*******************************************************************************
    367 **
    368 ** Function         bta_hf_client_open_fail
    369 **
    370 ** Description      open connection failed.
    371 **
    372 **
    373 ** Returns          void
    374 **
    375 *******************************************************************************/
    376 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA *p_data)
    377 {
    378     /* call open cback w. failure */
    379     bta_hf_client_cback_open(p_data, BTA_HF_CLIENT_FAIL_RESOURCES);
    380 }
    381 
    382 /*******************************************************************************
    383 **
    384 ** Function         bta_hf_client_rfc_close
    385 **
    386 ** Description      RFCOMM connection closed.
    387 **
    388 **
    389 ** Returns          void
    390 **
    391 *******************************************************************************/
    392 void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA *p_data)
    393 {
    394     UNUSED(p_data);
    395 
    396     /* reinitialize stuff */
    397     bta_hf_client_cb.scb.peer_features = 0;
    398     bta_hf_client_cb.scb.chld_features = 0;
    399     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
    400     bta_hf_client_cb.scb.svc_conn = FALSE;
    401     bta_hf_client_cb.scb.send_at_reply = FALSE;
    402     bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
    403 
    404     bta_hf_client_at_reset();
    405 
    406     bta_sys_conn_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
    407 
    408     /* call close cback */
    409     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLOSE_EVT, NULL);
    410 
    411     /* if not deregistering reopen server */
    412     if (bta_hf_client_cb.scb.deregister == FALSE)
    413     {
    414         /* Clear peer bd_addr so instance can be reused */
    415         bdcpy(bta_hf_client_cb.scb.peer_addr, bd_addr_null);
    416 
    417         /* start server as it might got closed on open*/
    418         bta_hf_client_start_server();
    419 
    420         bta_hf_client_cb.scb.conn_handle = 0;
    421 
    422         /* Make sure SCO is shutdown */
    423         bta_hf_client_sco_shutdown(NULL);
    424 
    425         bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
    426     }
    427     /* else close port and deallocate scb */
    428     else
    429     {
    430         bta_hf_client_close_server();
    431         bta_hf_client_scb_disable();
    432     }
    433 }
    434 
    435 /*******************************************************************************
    436 **
    437 ** Function         bta_hf_client_disc_int_res
    438 **
    439 ** Description      This function handles a discovery result when initiator.
    440 **
    441 **
    442 ** Returns          void
    443 **
    444 *******************************************************************************/
    445 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA *p_data)
    446 {
    447     UINT16 event = BTA_HF_CLIENT_DISC_FAIL_EVT;
    448 
    449     APPL_TRACE_DEBUG ("bta_hf_client_disc_int_res: Status: %d", p_data->disc_result.status);
    450 
    451     /* if found service */
    452     if (p_data->disc_result.status == SDP_SUCCESS ||
    453         p_data->disc_result.status == SDP_DB_FULL)
    454     {
    455         /* get attributes */
    456         if (bta_hf_client_sdp_find_attr())
    457         {
    458             event = BTA_HF_CLIENT_DISC_OK_EVT;
    459         }
    460     }
    461 
    462     /* free discovery db */
    463     bta_hf_client_free_db(p_data);
    464 
    465     /* send ourselves sdp ok/fail event */
    466     bta_hf_client_sm_execute(event, p_data);
    467 }
    468 
    469 /*******************************************************************************
    470 **
    471 ** Function         bta_hf_client_disc_acp_res
    472 **
    473 ** Description      This function handles a discovery result when acceptor.
    474 **
    475 **
    476 ** Returns          void
    477 **
    478 *******************************************************************************/
    479 void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA *p_data)
    480 {
    481     /* if found service */
    482     if (p_data->disc_result.status == SDP_SUCCESS ||
    483         p_data->disc_result.status == SDP_DB_FULL)
    484     {
    485         /* get attributes */
    486         bta_hf_client_sdp_find_attr();
    487     }
    488 
    489     /* free discovery db */
    490     bta_hf_client_free_db(p_data);
    491 }
    492 
    493 /*******************************************************************************
    494 **
    495 ** Function         bta_hf_client_rfc_data
    496 **
    497 ** Description      Read and process data from RFCOMM.
    498 **
    499 **
    500 ** Returns          void
    501 **
    502 *******************************************************************************/
    503 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA *p_data)
    504 {
    505     UINT16  len;
    506     char    buf[BTA_HF_CLIENT_RFC_READ_MAX];
    507     UNUSED(p_data);
    508 
    509     memset(buf, 0, sizeof(buf));
    510 
    511     /* read data from rfcomm; if bad status, we're done */
    512     while (PORT_ReadData(bta_hf_client_cb.scb.conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX, &len) == PORT_SUCCESS)
    513     {
    514         /* if no data, we're done */
    515         if (len == 0)
    516         {
    517             break;
    518         }
    519 
    520         bta_hf_client_at_parse(buf, len);
    521 
    522         /* no more data to read, we're done */
    523         if (len < BTA_HF_CLIENT_RFC_READ_MAX)
    524         {
    525             break;
    526         }
    527     }
    528 }
    529 
    530 /*******************************************************************************
    531 **
    532 ** Function         bta_hf_client_svc_conn_open
    533 **
    534 ** Description      Service level connection opened
    535 **
    536 **
    537 ** Returns          void
    538 **
    539 *******************************************************************************/
    540 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA *p_data)
    541 {
    542     tBTA_HF_CLIENT evt;
    543     UNUSED(p_data);
    544 
    545     memset(&evt, 0, sizeof(evt));
    546 
    547     if (!bta_hf_client_cb.scb.svc_conn)
    548     {
    549         /* set state variable */
    550         bta_hf_client_cb.scb.svc_conn = TRUE;
    551 
    552         /* call callback */
    553         evt.conn.peer_feat = bta_hf_client_cb.scb.peer_features;
    554         evt.conn.chld_feat = bta_hf_client_cb.scb.chld_features;
    555 
    556         (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CONN_EVT, &evt);
    557     }
    558 }
    559 
    560 /*******************************************************************************
    561 **
    562 ** Function         bta_hf_client_cback_ind
    563 **
    564 ** Description      Send indicator callback event to application.
    565 **
    566 ** Returns          void
    567 **
    568 *******************************************************************************/
    569 void bta_hf_client_ind(tBTA_HF_CLIENT_IND_TYPE type, UINT16 value)
    570 {
    571     tBTA_HF_CLIENT evt;
    572 
    573     memset(&evt, 0, sizeof(evt));
    574 
    575     evt.ind.type = type;
    576     evt.ind.value = value;
    577 
    578     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_IND_EVT, &evt);
    579 }
    580 
    581 /*******************************************************************************
    582 **
    583 ** Function         bta_hf_client_evt_val
    584 **
    585 ** Description      Send event to application.
    586 **                  This is a generic helper for events with common data.
    587 **
    588 **
    589 ** Returns          void
    590 **
    591 *******************************************************************************/
    592 void bta_hf_client_evt_val(tBTA_HF_CLIENT_EVT type, UINT16 value)
    593 {
    594     tBTA_HF_CLIENT evt;
    595 
    596     memset(&evt, 0, sizeof(evt));
    597 
    598     evt.val.value = value;
    599 
    600     (*bta_hf_client_cb.p_cback)(type, &evt);
    601 }
    602 
    603 /*******************************************************************************
    604 **
    605 ** Function         bta_hf_client_operator_name
    606 **
    607 ** Description      Send operator name event to application.
    608 **
    609 **
    610 ** Returns          void
    611 **
    612 *******************************************************************************/
    613 void bta_hf_client_operator_name(char *name)
    614 {
    615     tBTA_HF_CLIENT evt;
    616 
    617     memset(&evt, 0, sizeof(evt));
    618 
    619     strlcpy(evt.operator.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
    620     evt.operator.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
    621 
    622     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
    623 }
    624 
    625 
    626 /*******************************************************************************
    627 **
    628 ** Function         bta_hf_client_clip
    629 **
    630 ** Description      Send CLIP event to application.
    631 **
    632 **
    633 ** Returns          void
    634 **
    635 *******************************************************************************/
    636 void bta_hf_client_clip(char *number)
    637 {
    638     tBTA_HF_CLIENT evt;
    639 
    640     memset(&evt, 0, sizeof(evt));
    641 
    642     strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    643     evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    644 
    645     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLIP_EVT, &evt);
    646 }
    647 
    648 /*******************************************************************************
    649 **
    650 ** Function         bta_hf_client_ccwa
    651 **
    652 ** Description      Send CLIP event to application.
    653 **
    654 **
    655 ** Returns          void
    656 **
    657 *******************************************************************************/
    658 void bta_hf_client_ccwa(char *number)
    659 {
    660     tBTA_HF_CLIENT evt;
    661 
    662     memset(&evt, 0, sizeof(evt));
    663 
    664     strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    665     evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    666 
    667     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CCWA_EVT, &evt);
    668 }
    669 
    670 /*******************************************************************************
    671 **
    672 ** Function         bta_hf_client_at_result
    673 **
    674 ** Description      Send AT result event to application.
    675 **
    676 **
    677 ** Returns          void
    678 **
    679 *******************************************************************************/
    680 void bta_hf_client_at_result(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT16 cme)
    681 {
    682     tBTA_HF_CLIENT evt;
    683 
    684     memset(&evt, 0, sizeof(evt));
    685 
    686     evt.result.type = type;
    687     evt.result.cme = cme;
    688 
    689     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
    690 }
    691 
    692 /*******************************************************************************
    693 **
    694 ** Function         bta_hf_client_clcc
    695 **
    696 ** Description      Send clcc event to application.
    697 **
    698 **
    699 ** Returns          void
    700 **
    701 *******************************************************************************/
    702 void bta_hf_client_clcc(UINT32 idx, BOOLEAN incoming, UINT8 status, BOOLEAN mpty, char *number)
    703 {
    704     tBTA_HF_CLIENT evt;
    705 
    706     memset(&evt, 0, sizeof(evt));
    707 
    708     evt.clcc.idx = idx;
    709     evt.clcc.inc = incoming;
    710     evt.clcc.status = status;
    711     evt.clcc.mpty = mpty;
    712 
    713     if (number)
    714     {
    715         evt.clcc.number_present = TRUE;
    716         strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    717         evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    718     }
    719 
    720     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLCC_EVT, &evt);
    721 }
    722 
    723 /*******************************************************************************
    724 **
    725 ** Function         bta_hf_client_cnum
    726 **
    727 ** Description      Send cnum event to application.
    728 **
    729 **
    730 ** Returns          void
    731 **
    732 *******************************************************************************/
    733 void bta_hf_client_cnum(char *number, UINT16 service)
    734 {
    735     tBTA_HF_CLIENT evt;
    736 
    737     memset(&evt, 0, sizeof(evt));
    738 
    739     evt.cnum.service = service;
    740     strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    741     evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    742 
    743     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CNUM_EVT, &evt);
    744 }
    745 
    746 /*******************************************************************************
    747 **
    748 ** Function         bta_hf_client_binp
    749 **
    750 ** Description      Send BINP event to application.
    751 **
    752 **
    753 ** Returns          void
    754 **
    755 *******************************************************************************/
    756 void bta_hf_client_binp(char *number)
    757 {
    758     tBTA_HF_CLIENT evt;
    759 
    760     memset(&evt, 0, sizeof(evt));
    761 
    762     strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    763     evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    764 
    765     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_BINP_EVT, &evt);
    766 }
    767