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 "bd.h"
     28 #include "bta_hf_client_api.h"
     29 #include "bta_hf_client_int.h"
     30 #include "bta_dm_int.h"
     31 #include "l2c_api.h"
     32 #include "port_api.h"
     33 #include "bta_sys.h"
     34 #include "utl.h"
     35 #include "bt_utils.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);
    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     int             i;
    268     BD_ADDR         dev_addr;
    269     int             status;
    270 
    271     /* set role */
    272     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
    273 
    274     APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open: serv_handle = %d rfc.port_handle = %d",
    275             bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle);
    276 
    277     /* get bd addr of peer */
    278     if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid)))
    279     {
    280         APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status);
    281     }
    282 
    283     /* Collision Handling */
    284     if (bta_hf_client_cb.scb.colli_tmr_on)
    285     {
    286         /* stop collision timer */
    287         bta_hf_client_cb.scb.colli_tmr_on = FALSE;
    288         bta_sys_stop_timer (&bta_hf_client_cb.scb.colli_timer);
    289 
    290         if (bdcmp (dev_addr, bta_hf_client_cb.scb.peer_addr) == 0)
    291         {
    292             /* If incoming and outgoing device are same, nothing more to do.            */
    293             /* Outgoing conn will be aborted because we have successful incoming conn.  */
    294         }
    295         else
    296         {
    297             /* Resume outgoing connection. */
    298             bta_hf_client_resume_open ();
    299         }
    300     }
    301 
    302     bdcpy (bta_hf_client_cb.scb.peer_addr, dev_addr);
    303     bta_hf_client_cb.scb.conn_handle = p_data->rfc.port_handle;
    304 
    305     /* do service discovery to get features */
    306     bta_hf_client_do_disc();
    307 
    308     /* continue with open processing */
    309     bta_hf_client_rfc_open(p_data);
    310 }
    311 
    312 /*******************************************************************************
    313 **
    314 ** Function         bta_hf_client_rfc_fail
    315 **
    316 ** Description      RFCOMM connection failed.
    317 **
    318 **
    319 ** Returns          void
    320 **
    321 *******************************************************************************/
    322 void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA *p_data)
    323 {
    324     UNUSED(p_data);
    325 
    326     /* reinitialize stuff */
    327     bta_hf_client_cb.scb.conn_handle = 0;
    328     bta_hf_client_cb.scb.peer_features = 0;
    329     bta_hf_client_cb.scb.chld_features = 0;
    330     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
    331     bta_hf_client_cb.scb.svc_conn = FALSE;
    332     bta_hf_client_cb.scb.send_at_reply = FALSE;
    333     bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
    334 
    335     bta_hf_client_at_reset();
    336 
    337     /* reopen server */
    338     bta_hf_client_start_server();
    339 
    340     /* call open cback w. failure */
    341     bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_RFCOMM);
    342 }
    343 
    344 /*******************************************************************************
    345 **
    346 ** Function         bta_hf_client_disc_fail
    347 **
    348 ** Description      This function handles a discovery failure.
    349 **
    350 **
    351 ** Returns          void
    352 **
    353 *******************************************************************************/
    354 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA *p_data)
    355 {
    356     UNUSED(p_data);
    357 
    358     /* reopen server */
    359     bta_hf_client_start_server();
    360 
    361     /* reinitialize stuff */
    362 
    363     /* call open cback w. failure */
    364     bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_SDP);
    365 }
    366 
    367 /*******************************************************************************
    368 **
    369 ** Function         bta_hf_client_open_fail
    370 **
    371 ** Description      open connection failed.
    372 **
    373 **
    374 ** Returns          void
    375 **
    376 *******************************************************************************/
    377 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA *p_data)
    378 {
    379     /* call open cback w. failure */
    380     bta_hf_client_cback_open(p_data, BTA_HF_CLIENT_FAIL_RESOURCES);
    381 }
    382 
    383 /*******************************************************************************
    384 **
    385 ** Function         bta_hf_client_rfc_close
    386 **
    387 ** Description      RFCOMM connection closed.
    388 **
    389 **
    390 ** Returns          void
    391 **
    392 *******************************************************************************/
    393 void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA *p_data)
    394 {
    395     int i, num_active_conn = 0;
    396     UNUSED(p_data);
    397 
    398     /* reinitialize stuff */
    399     bta_hf_client_cb.scb.peer_features = 0;
    400     bta_hf_client_cb.scb.chld_features = 0;
    401     bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
    402     bta_hf_client_cb.scb.svc_conn = FALSE;
    403     bta_hf_client_cb.scb.send_at_reply = FALSE;
    404     bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
    405 
    406     bta_hf_client_at_reset();
    407 
    408     bta_sys_conn_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
    409 
    410     /* call close cback */
    411     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLOSE_EVT, NULL);
    412 
    413     /* if not deregistering reopen server */
    414     if (bta_hf_client_cb.scb.deregister == FALSE)
    415     {
    416         /* Clear peer bd_addr so instance can be reused */
    417         bdcpy(bta_hf_client_cb.scb.peer_addr, bd_addr_null);
    418 
    419         /* start server as it might got closed on open*/
    420         bta_hf_client_start_server();
    421 
    422         bta_hf_client_cb.scb.conn_handle = 0;
    423 
    424         /* Make sure SCO is shutdown */
    425         bta_hf_client_sco_shutdown(NULL);
    426 
    427         bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
    428     }
    429     /* else close port and deallocate scb */
    430     else
    431     {
    432         bta_hf_client_close_server();
    433         bta_hf_client_scb_disable();
    434     }
    435 }
    436 
    437 /*******************************************************************************
    438 **
    439 ** Function         bta_hf_client_disc_int_res
    440 **
    441 ** Description      This function handles a discovery result when initiator.
    442 **
    443 **
    444 ** Returns          void
    445 **
    446 *******************************************************************************/
    447 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA *p_data)
    448 {
    449     UINT16 event = BTA_HF_CLIENT_DISC_FAIL_EVT;
    450 
    451     APPL_TRACE_DEBUG ("bta_hf_client_disc_int_res: Status: %d", p_data->disc_result.status);
    452 
    453     /* if found service */
    454     if (p_data->disc_result.status == SDP_SUCCESS ||
    455         p_data->disc_result.status == SDP_DB_FULL)
    456     {
    457         /* get attributes */
    458         if (bta_hf_client_sdp_find_attr())
    459         {
    460             event = BTA_HF_CLIENT_DISC_OK_EVT;
    461         }
    462     }
    463 
    464     /* free discovery db */
    465     bta_hf_client_free_db(p_data);
    466 
    467     /* send ourselves sdp ok/fail event */
    468     bta_hf_client_sm_execute(event, p_data);
    469 }
    470 
    471 /*******************************************************************************
    472 **
    473 ** Function         bta_hf_client_disc_acp_res
    474 **
    475 ** Description      This function handles a discovery result when acceptor.
    476 **
    477 **
    478 ** Returns          void
    479 **
    480 *******************************************************************************/
    481 void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA *p_data)
    482 {
    483     /* if found service */
    484     if (p_data->disc_result.status == SDP_SUCCESS ||
    485         p_data->disc_result.status == SDP_DB_FULL)
    486     {
    487         /* get attributes */
    488         bta_hf_client_sdp_find_attr();
    489     }
    490 
    491     /* free discovery db */
    492     bta_hf_client_free_db(p_data);
    493 }
    494 
    495 /*******************************************************************************
    496 **
    497 ** Function         bta_hf_client_rfc_data
    498 **
    499 ** Description      Read and process data from RFCOMM.
    500 **
    501 **
    502 ** Returns          void
    503 **
    504 *******************************************************************************/
    505 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA *p_data)
    506 {
    507     UINT16  len;
    508     char    buf[BTA_HF_CLIENT_RFC_READ_MAX];
    509     UNUSED(p_data);
    510 
    511     memset(buf, 0, sizeof(buf));
    512 
    513     /* read data from rfcomm; if bad status, we're done */
    514     while (PORT_ReadData(bta_hf_client_cb.scb.conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX, &len) == PORT_SUCCESS)
    515     {
    516         /* if no data, we're done */
    517         if (len == 0)
    518         {
    519             break;
    520         }
    521 
    522         bta_hf_client_at_parse(buf, len);
    523 
    524         /* no more data to read, we're done */
    525         if (len < BTA_HF_CLIENT_RFC_READ_MAX)
    526         {
    527             break;
    528         }
    529     }
    530 }
    531 
    532 /*******************************************************************************
    533 **
    534 ** Function         bta_hf_client_svc_conn_open
    535 **
    536 ** Description      Service level connection opened
    537 **
    538 **
    539 ** Returns          void
    540 **
    541 *******************************************************************************/
    542 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA *p_data)
    543 {
    544     tBTA_HF_CLIENT evt;
    545     UNUSED(p_data);
    546 
    547     memset(&evt, 0, sizeof(evt));
    548 
    549     if (!bta_hf_client_cb.scb.svc_conn)
    550     {
    551         /* set state variable */
    552         bta_hf_client_cb.scb.svc_conn = TRUE;
    553 
    554         /* call callback */
    555         evt.conn.peer_feat = bta_hf_client_cb.scb.peer_features;
    556         evt.conn.chld_feat = bta_hf_client_cb.scb.chld_features;
    557 
    558         (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CONN_EVT, &evt);
    559     }
    560 }
    561 
    562 /*******************************************************************************
    563 **
    564 ** Function         bta_hf_client_cback_ind
    565 **
    566 ** Description      Send indicator callback event to application.
    567 **
    568 ** Returns          void
    569 **
    570 *******************************************************************************/
    571 void bta_hf_client_ind(tBTA_HF_CLIENT_IND_TYPE type, UINT16 value)
    572 {
    573     tBTA_HF_CLIENT evt;
    574 
    575     memset(&evt, 0, sizeof(evt));
    576 
    577     evt.ind.type = type;
    578     evt.ind.value = value;
    579 
    580     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_IND_EVT, &evt);
    581 }
    582 
    583 /*******************************************************************************
    584 **
    585 ** Function         bta_hf_client_evt_val
    586 **
    587 ** Description      Send event to application.
    588 **                  This is a generic helper for events with common data.
    589 **
    590 **
    591 ** Returns          void
    592 **
    593 *******************************************************************************/
    594 void bta_hf_client_evt_val(tBTA_HF_CLIENT_EVT type, UINT16 value)
    595 {
    596     tBTA_HF_CLIENT evt;
    597 
    598     memset(&evt, 0, sizeof(evt));
    599 
    600     evt.val.value = value;
    601 
    602     (*bta_hf_client_cb.p_cback)(type, &evt);
    603 }
    604 
    605 /*******************************************************************************
    606 **
    607 ** Function         bta_hf_client_operator_name
    608 **
    609 ** Description      Send operator name event to application.
    610 **
    611 **
    612 ** Returns          void
    613 **
    614 *******************************************************************************/
    615 void bta_hf_client_operator_name(char *name)
    616 {
    617     tBTA_HF_CLIENT evt;
    618 
    619     memset(&evt, 0, sizeof(evt));
    620 
    621     strlcpy(evt.operator.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
    622     evt.operator.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
    623 
    624     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
    625 }
    626 
    627 
    628 /*******************************************************************************
    629 **
    630 ** Function         bta_hf_client_clip
    631 **
    632 ** Description      Send CLIP event to application.
    633 **
    634 **
    635 ** Returns          void
    636 **
    637 *******************************************************************************/
    638 void bta_hf_client_clip(char *number)
    639 {
    640     tBTA_HF_CLIENT evt;
    641 
    642     memset(&evt, 0, sizeof(evt));
    643 
    644     strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    645     evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    646 
    647     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLIP_EVT, &evt);
    648 }
    649 
    650 /*******************************************************************************
    651 **
    652 ** Function         bta_hf_client_ccwa
    653 **
    654 ** Description      Send CLIP event to application.
    655 **
    656 **
    657 ** Returns          void
    658 **
    659 *******************************************************************************/
    660 void bta_hf_client_ccwa(char *number)
    661 {
    662     tBTA_HF_CLIENT evt;
    663 
    664     memset(&evt, 0, sizeof(evt));
    665 
    666     strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    667     evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    668 
    669     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CCWA_EVT, &evt);
    670 }
    671 
    672 /*******************************************************************************
    673 **
    674 ** Function         bta_hf_client_at_result
    675 **
    676 ** Description      Send AT result event to application.
    677 **
    678 **
    679 ** Returns          void
    680 **
    681 *******************************************************************************/
    682 void bta_hf_client_at_result(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT16 cme)
    683 {
    684     tBTA_HF_CLIENT evt;
    685 
    686     memset(&evt, 0, sizeof(evt));
    687 
    688     evt.result.type = type;
    689     evt.result.cme = cme;
    690 
    691     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
    692 }
    693 
    694 /*******************************************************************************
    695 **
    696 ** Function         bta_hf_client_clcc
    697 **
    698 ** Description      Send clcc event to application.
    699 **
    700 **
    701 ** Returns          void
    702 **
    703 *******************************************************************************/
    704 void bta_hf_client_clcc(UINT32 idx, BOOLEAN incoming, UINT8 status, BOOLEAN mpty, char *number)
    705 {
    706     tBTA_HF_CLIENT evt;
    707 
    708     memset(&evt, 0, sizeof(evt));
    709 
    710     evt.clcc.idx = idx;
    711     evt.clcc.inc = incoming;
    712     evt.clcc.status = status;
    713     evt.clcc.mpty = mpty;
    714 
    715     if (number)
    716     {
    717         evt.clcc.number_present = TRUE;
    718         strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    719         evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    720     }
    721 
    722     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLCC_EVT, &evt);
    723 }
    724 
    725 /*******************************************************************************
    726 **
    727 ** Function         bta_hf_client_cnum
    728 **
    729 ** Description      Send cnum event to application.
    730 **
    731 **
    732 ** Returns          void
    733 **
    734 *******************************************************************************/
    735 void bta_hf_client_cnum(char *number, UINT16 service)
    736 {
    737     tBTA_HF_CLIENT evt;
    738 
    739     memset(&evt, 0, sizeof(evt));
    740 
    741     evt.cnum.service = service;
    742     strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    743     evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    744 
    745     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CNUM_EVT, &evt);
    746 }
    747 
    748 /*******************************************************************************
    749 **
    750 ** Function         bta_hf_client_binp
    751 **
    752 ** Description      Send BINP event to application.
    753 **
    754 **
    755 ** Returns          void
    756 **
    757 *******************************************************************************/
    758 void bta_hf_client_binp(char *number)
    759 {
    760     tBTA_HF_CLIENT evt;
    761 
    762     memset(&evt, 0, sizeof(evt));
    763 
    764     strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
    765     evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
    766 
    767     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_BINP_EVT, &evt);
    768 }
    769