static void btif_in_pan_generic_evt(UINT16 event, char *p_param)
{
    BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event);
    switch (event) {
        case BTIF_PAN_CB_DISCONNECTING:
        {
            bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)p_param;
            btpan_conn_t* conn = btpan_find_conn_addr(bd_addr->address);
            int btpan_conn_local_role;
            int btpan_remote_role;
            asrt(conn != NULL);
            if (conn) {
                btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
                btpan_remote_role = bta_role_to_btpan(conn->remote_role);
                callback.connection_state_cb(BTPAN_STATE_DISCONNECTING, BT_STATUS_SUCCESS,
                        (const bt_bdaddr_t*)conn->peer, btpan_conn_local_role, btpan_remote_role);
            }
        } break;
        default:
        {
            BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event);
        }
        break;
    }
}
/*******************************************************************************
**
** Function         bta_fs_co_resume
**
** Description      This function is executed by BTA when resuming a session.
**                  This is used to retrieve the session ID and related information
**
** Parameters       evt     - event that must be passed into the call-in function.
**                  app_id  - application ID specified in the enable functions.
**                            It can be used to identify which profile is the caller
**                            of the call-out function.
**
** Returns          void
**
**                  Note: Upon completion of the request, the related session information,
**                        if successful, and an error code (tBTA_FS_CO_STATUS)
**                        are returned in the call-in function, bta_fs_ci_resume().
**
*******************************************************************************/
void bta_fs_co_resume(UINT16 evt, UINT8 app_id)
{
    UNUSED(evt);
    UNUSED(app_id);

    BTIF_TRACE_WARNING("[CO] bta_fs_co_resume - NOT implemented");
}
Пример #3
0
static int tap_if_up(const char *devname, const bt_bdaddr_t *addr)
{
    struct ifreq ifr;
    int sk, err;

    sk = socket(AF_INET, SOCK_DGRAM, 0);
    if (sk < 0)
        return -1;

    //set mac addr
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1);
    err = ioctl(sk, SIOCGIFHWADDR, &ifr);
    if (err < 0)
    {
        BTIF_TRACE_ERROR("Could not get network hardware for interface:%s, errno:%s", devname, strerror(errno));
        close(sk);
        return -1;
    }

    strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1);
    memcpy(ifr.ifr_hwaddr.sa_data, addr->address, 6);

    /* The IEEE has specified that the most significant bit of the most significant byte is used to
     * determine a multicast address. If its a 1, that means multicast, 0 means unicast.
     * Kernel returns an error if we try to set a multicast address for the tun-tap ethernet interface.
     * Mask this bit to avoid any issue with auto generated address.
     */
    if (ifr.ifr_hwaddr.sa_data[0] & 0x01) {
        BTIF_TRACE_WARNING("Not a unicast MAC address, force multicast bit flipping");
        ifr.ifr_hwaddr.sa_data[0] &= ~0x01;
    }

    err = ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr);

    if (err < 0) {
        BTIF_TRACE_ERROR("Could not set bt address for interface:%s, errno:%s", devname, strerror(errno));
        close(sk);
        return -1;
    }

    //bring it up
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1);

    ifr.ifr_flags |= IFF_UP;
    ifr.ifr_flags |= IFF_MULTICAST;

    err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);


    if (err < 0) {
        BTIF_TRACE_ERROR("Could not bring up network interface:%s, errno:%d", devname, errno);
        close(sk);
        return -1;
    }
    close(sk);
    BTIF_TRACE_DEBUG("network interface: %s is up", devname);
    return 0;
}
/*******************************************************************************
**
** Function         bta_fs_co_sess_ssn
**
** Description      This function is executed by BTA when resuming a session.
**                  This is used to inform call-out module if the ssn/file offset
**                  needs to be adjusted.
**
** Parameters       ssn     - the session sequence number of the first request
**                            after resume.
**                  app_id  - application ID specified in the enable functions.
**                            It can be used to identify which profile is the caller
**                            of the call-out function.
**
** Returns          void
**
*******************************************************************************/
void bta_fs_co_sess_ssn(int fd, UINT8 ssn, UINT8 app_id)
{
    UNUSED(fd);
    UNUSED(ssn);
    UNUSED(app_id);

    BTIF_TRACE_WARNING("[CO] bta_fs_co_suspend - NOT implemented");
}
/*******************************************************************************
**
** Function         register_app
**
** Description      Registers HID Device application
**
** Returns          bt_status_t
**
*******************************************************************************/
static bt_status_t register_app(bthd_app_param_t *p_app_param, bthd_qos_param_t *p_in_qos,
                                            bthd_qos_param_t *p_out_qos)
{
    tBTA_HD_APP_INFO app_info;
    tBTA_HD_QOS_INFO in_qos;
    tBTA_HD_QOS_INFO out_qos;

    BTIF_TRACE_API("%s", __FUNCTION__);

    if (btif_hd_cb.app_registered)
    {
        BTIF_TRACE_WARNING("%s: application already registered", __FUNCTION__);
        return BT_STATUS_BUSY;
    }

    if (btif_hd_cb.status != BTIF_HD_ENABLED)
    {
        BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __FUNCTION__, btif_hd_cb.status);
        return BT_STATUS_NOT_READY;
    }

    app_info.p_name = p_app_param->name;
    app_info.p_description = p_app_param->description;
    app_info.p_provider = p_app_param->provider;
    app_info.subclass = p_app_param->subclass;
    app_info.descriptor.dl_len = p_app_param->desc_list_len;
    app_info.descriptor.dsc_list = p_app_param->desc_list;

    in_qos.service_type = p_in_qos->service_type;
    in_qos.token_rate = p_in_qos->token_rate;
    in_qos.token_bucket_size = p_in_qos->token_bucket_size;
    in_qos.peak_bandwidth = p_in_qos->peak_bandwidth;
    in_qos.access_latency = p_in_qos->access_latency;
    in_qos.delay_variation = p_in_qos->delay_variation;

    out_qos.service_type = p_out_qos->service_type;
    out_qos.token_rate = p_out_qos->token_rate;
    out_qos.token_bucket_size = p_out_qos->token_bucket_size;
    out_qos.peak_bandwidth = p_out_qos->peak_bandwidth;
    out_qos.access_latency = p_out_qos->access_latency;
    out_qos.delay_variation = p_out_qos->delay_variation;

    BTA_HdRegisterApp(&app_info, &in_qos, &out_qos);

    return BT_STATUS_SUCCESS;
}
/*******************************************************************************
**
** Function         bta_fs_co_set_perms
**
** Description      This function is called to set the permission a file/directory
**                  with name as p_src_path.
**
** Parameters       p_src_path  - (input) name of file/directory to set permission (fully qualified path).
**                  p_perms     - the permission .
**                  app_id   - (input) application ID specified in the enable functions.
**                                     It can be used to identify which profile is the caller
**                                     of the call-out function.
**
** Returns          (tBTA_FS_CO_STATUS) status of the call.
**                      [BTA_FS_CO_OK if successful]
**                      [BTA_FS_CO_EACCES if p_dest_path already exists or could not be created (invalid path);
**                                        or p_src_path is a directory and p_dest_path specifies a different path. ]
**                      [BTA_FS_CO_FAIL otherwise]
**
*******************************************************************************/
void bta_fs_co_set_perms(const char *p_src_path,  UINT8 *p_perms, UINT16 evt, UINT8 app_id)
{
    UNUSED(p_src_path);
    UNUSED(p_perms);
    UNUSED(evt);
    UNUSED(app_id);

    BTIF_TRACE_WARNING("[CO] bta_fs_co_set_perms - NOT implemented");
}
/*******************************************************************************
**
** Function         virtual_cable_unplug
**
** Description      Sends Virtual Cable Unplug to host
**
** Returns          bt_status_t
**
*******************************************************************************/
static bt_status_t virtual_cable_unplug(void)
{
    BTIF_TRACE_API("%s", __FUNCTION__);

    if (!btif_hd_cb.app_registered)
    {
        BTIF_TRACE_WARNING("%s: application not yet registered", __FUNCTION__);
        return BT_STATUS_NOT_READY;
    }

    if (btif_hd_cb.status != BTIF_HD_ENABLED)
    {
        BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __FUNCTION__, btif_hd_cb.status);
        return BT_STATUS_NOT_READY;
    }

    BTA_HdVirtualCableUnplug();

    return BT_STATUS_SUCCESS;
}
/*******************************************************************************
**
** Function         report_error
**
** Description      Sends HANDSHAKE with error info for invalid SET_REPORT
**
** Returns          bt_status_t
**
*******************************************************************************/
static bt_status_t report_error(uint8_t error)
{
    BTIF_TRACE_API("%s", __FUNCTION__);

    if (!btif_hd_cb.app_registered)
    {
        BTIF_TRACE_WARNING("%s: application not yet registered", __FUNCTION__);
        return BT_STATUS_NOT_READY;
    }

    if (btif_hd_cb.status != BTIF_HD_ENABLED)
    {
        BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __FUNCTION__, btif_hd_cb.status);
        return BT_STATUS_NOT_READY;
    }

    BTA_HdReportError(error);

    return BT_STATUS_SUCCESS;
}
/*******************************************************************************
**
** Function         bta_fs_co_session_info
**
** Description      This function is executed by BTA when a reliable session is
**                  established (p_sess_info != NULL) or ended (p_sess_info == NULL).
**
** Parameters       bd_addr     - the peer address
**                  p_sess_info - the session ID and related information.
**                  app_id  - application ID specified in the enable functions.
**                            It can be used to identify which profile is the caller
**                            of the call-out function.
**
** Returns          void
**
*******************************************************************************/
void bta_fs_co_session_info(BD_ADDR bd_addr, UINT8 *p_sess_info, UINT8 ssn,
                                           tBTA_FS_CO_SESS_ST new_st, char *p_path, UINT8 *p_info, UINT8 app_id)
{
    UNUSED(bd_addr);
    UNUSED(p_sess_info);
    UNUSED(ssn);
    UNUSED(new_st);
    UNUSED(p_path);
    UNUSED(p_info);
    UNUSED(app_id);

    BTIF_TRACE_WARNING("[CO] bta_fs_co_session_info - NOT implemented");
}
/*******************************************************************************
**
** Function         bta_fs_co_suspend
**
** Description      This function is executed by BTA when a reliable session is
**                  suspended.
**
** Parameters       bd_addr - the peer address
**                  ssn     - the session sequence number.
**                  info    - the BTA specific information (like last active operation).
**                  p_offset- the location to receive object offset of the suspended session
**                  app_id  - application ID specified in the enable functions.
**                            It can be used to identify which profile is the caller
**                            of the call-out function.
**
** Returns          void
**
*******************************************************************************/
void bta_fs_co_suspend(BD_ADDR bd_addr, UINT8 *p_sess_info, UINT8 ssn,
                                      UINT32 *p_timeout, UINT32 *p_offset, UINT8 info, UINT8 app_id)
{
    UNUSED(bd_addr);
    UNUSED(p_sess_info);
    UNUSED(ssn);
    UNUSED(p_timeout);
    UNUSED(p_offset);
    UNUSED(info);
    UNUSED(app_id);

    BTIF_TRACE_WARNING("[CO] bta_fs_co_suspend - NOT implemented");
}
/*******************************************************************************
 **
 ** Function        btapp_fs_check_space
 **
 ** Description     determines access and if there is enough space for given files size on given path
 **
 ** Parameters      p_path  - Fully qualified path and file name.
 **                           WARNING: file name is stripped off! so it must be present!
 **                 size    - size of file to put (0 if unavailable or not applicable)
 **                 app_id  - in case application specific treatement is required (e.g opp versus ftp)
 ** Returns         0 if enough space, otherwise errno failure codes
 **
 *******************************************************************************/
static int btapp_fs_check_space( const char *p_path, const UINT32 size, const UINT8 app_id )
{
    unsigned long long max_space;
    struct statfs fs_buffer;
    int err = 0;
    char *p_dir;
    char *p_end;
    UNUSED(app_id);

    if(size==BTA_FS_LEN_UNKNOWN)
        return 0;
    /* fail silently in case of no memory. write will catch if not enough space */

    if (NULL != (p_dir = (char *) GKI_getbuf(strlen(p_path) + 1)))
    {
        strcpy(p_dir, p_path);
        if (NULL != (p_end = strrchr(p_dir, '/')))
        {

            *p_end = '\0';
            /* get fs info and calculate available space. if not enough, the fs error EFBIG is returned */

            if (0 == statfs(p_dir, &fs_buffer))
            {

                max_space = fs_buffer.f_bavail * fs_buffer.f_bsize;
#if (BTA_FS_DEBUG==TRUE)
                BTIF_TRACE_DEBUG("btapp_fs_enough_space(file size: %d): (uint)max_size: %u", size, (UINT32)max_space);
#endif
                if (max_space < size)
                    err = EFBIG;
            }
            else
            {
                err = errno;
                BTIF_TRACE_WARNING("btapp_fs_enough_space(): statfs() failed with err: %d", err);
            }
        }
        else
        {
            err = ENOENT;
        }
        GKI_freebuf(p_dir);
    }
    else
    {
        err = ENOMEM;
    }
    return err;

} /* btapp_fs_check_access_space() */
/*******************************************************************************
**
** Function         bta_fs_co_mkdir
**
** Description      This function is called to create a directory with
**                  the pathname given by path. The pathname is a null terminated
**                  string. All components of the path must already exist.
**
** Parameters       p_path   - (input) name of directory to create (fully qualified path).
**                  app_id   - (input) application ID specified in the enable functions.
**                                     It can be used to identify which profile is the caller
**                                     of the call-out function.
**
** Returns          (tBTA_FS_CO_STATUS) status of the call.
**                  [BTA_FS_CO_OK if successful]
**                  [BTA_FS_CO_FAIL if unsuccessful]
**
*******************************************************************************/
tBTA_FS_CO_STATUS bta_fs_co_mkdir(const char *p_path, UINT8 app_id)
{
    int err;
    tBTA_FS_CO_STATUS status = BTA_FS_CO_OK;

    if ((mkdir (p_path, 0666)) != 0)
    {
        err = errno;
        status = BTA_FS_CO_FAIL;
        BTIF_TRACE_WARNING("[CO] bta_fs_co_mkdir: error=%d, path [%s] app_id:%d",
                            err, p_path, app_id);
    }
    return (status);
}
Пример #13
0
/*******************************************************************************
**
** Function         register_app
**
** Description      Registers HID Device application
**
** Returns          bt_status_t
**
*******************************************************************************/
static bt_status_t send_report(bthd_report_type_t type, uint8_t id, uint16_t len, uint8_t *p_data)
{
    tBTA_HD_REPORT report;

    APPL_TRACE_VERBOSE("%s: type=%d id=%d len=%d", __FUNCTION__, type, id, len);

    if (!btif_hd_cb.app_registered)
    {
        BTIF_TRACE_WARNING("%s: application not yet registered", __FUNCTION__);
        return BT_STATUS_NOT_READY;
    }

    if (btif_hd_cb.status != BTIF_HD_ENABLED)
    {
        BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __FUNCTION__, btif_hd_cb.status);
        return BT_STATUS_NOT_READY;
    }

    if (type == BTHD_REPORT_TYPE_INTRDATA)
    {
        report.type = BTHD_REPORT_TYPE_INPUT;
        report.use_intr = TRUE;
    }
    else
    {
        report.type = (type & 0x03);
        report.use_intr = FALSE;
    }

    report.id = id;
    report.len = len;
    report.p_data = p_data;

    BTA_HdSendReport(&report);

    return BT_STATUS_SUCCESS;
}
/*******************************************************************************
**
** Function         bta_fs_co_close
**
** Description      This function is called by BTA when a connection to a
**                  client is closed.
**
** Parameters       fd      - file descriptor of file to close.
**                  app_id  - application ID specified in the enable functions.
**                            It can be used to identify which profile is the caller
**                            of the call-out function.
**
** Returns          (tBTA_FS_CO_STATUS) status of the call.
**                      [BTA_FS_CO_OK if successful],
**                      [BTA_FS_CO_FAIL if failed  ]
**
*******************************************************************************/
tBTA_FS_CO_STATUS bta_fs_co_close(int fd, UINT8 app_id)
{
    tBTA_FS_CO_STATUS status = BTA_FS_CO_OK;
    int err;

    BTIF_TRACE_DEBUG("[CO] bta_fs_co_close: handle:%d, app id:%d",
        fd, app_id);
    if (close (fd) < 0)
    {
        err = errno;
        status = BTA_FS_CO_FAIL;
        BTIF_TRACE_WARNING("[CO] bta_fs_co_close: handle:%d error=%d app_id:%d", fd, err, app_id);
    }

    return (status);
}
Пример #15
0
static void btpan_tap_fd_signaled(int fd, int type, int flags, uint32_t user_id) {
    assert(btpan_cb.tap_fd == INVALID_FD || btpan_cb.tap_fd == fd);

    if (btpan_cb.tap_fd != fd) {
        BTIF_TRACE_WARNING("%s Signaled on mismatched fds exp:%d act:%d\n",
                __func__, btpan_cb.tap_fd, fd);
        return;
    }

    if (flags & SOCK_THREAD_FD_EXCEPTION) {
        btpan_cb.tap_fd = INVALID_FD;
        btpan_tap_close(fd);
        btif_pan_close_all_conns();
    } else if (flags & SOCK_THREAD_FD_RD)
        bta_dmexecutecallback(btu_exec_tap_fd_read, INT_TO_PTR(fd));
}
Пример #16
0
/*******************************************************************************
**
** Function        btif_in_hf_client_generic_evt
**
** Description     Processes generic events to be sent to JNI that are not triggered from the BTA.
**                 Always runs in BTIF context
**
** Returns          void
**
*******************************************************************************/
static void btif_in_hf_client_generic_evt(UINT16 event, char *p_param)
{
    UNUSED(p_param);

    BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event);
    switch (event) {
        case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING:
        {
            HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, (bthf_client_audio_state_t)BTHF_AUDIO_STATE_CONNECTING,
                      &btif_hf_client_cb.connected_bda);
        } break;
        default:
        {
            BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event);
        }
        break;
    }
}
/*******************************************************************************
**
** Function         bta_fs_co_read
**
** Description      This function is called by BTA to read in data from the
**                  previously opened file on the phone.
**
** Parameters       fd      - file descriptor of file to read from.
**                  p_buf   - buffer to read the data into.
**                  nbytes  - number of bytes to read into the buffer.
**                  evt     - event that must be passed into the call-in function.
**                  ssn     - session sequence number. Ignored, if bta_fs_co_open
**							  was not called with BTA_FS_CO_RELIABLE.
**                  app_id  - application ID specified in the enable functions.
**                            It can be used to identify which profile is the caller
**                            of the call-out function.
**
** Returns          void
**
**                  Note: Upon completion of the request, bta_fs_ci_read() is
**                        called with the buffer of data, along with the number
**                        of bytes read into the buffer, and a status.  The
**                        call-in function should only be called when ALL requested
**                        bytes have been read, the end of file has been detected,
**                        or an error has occurred.
**
*******************************************************************************/
void bta_fs_co_read(int fd, UINT8 *p_buf, UINT16 nbytes, UINT16 evt, UINT8 ssn, UINT8 app_id)
{
    tBTA_FS_CO_STATUS  status = BTA_FS_CO_OK;
    INT32   num_read;
    int     err;
    UNUSED(ssn);

    if ((num_read = read (fd, p_buf, nbytes)) < 0)
    {
        err = errno;
        status = BTA_FS_CO_FAIL;
        BTIF_TRACE_WARNING("[CO] bta_fs_co_read: handle:%d error=%d app_id:%d",
                            fd, err, app_id);
    }
    else if (num_read < nbytes)
        status = BTA_FS_CO_EOF;

    bta_fs_ci_read(fd, (UINT16)num_read, status, evt);
}
Пример #18
0
/*******************************************************************************
**
** Function         btif_hd_upstreams_evt
**
** Description      Executes events in btif context
**
** Returns          void
**
*******************************************************************************/
static void btif_hd_upstreams_evt(UINT16 event, char* p_param)
{
    tBTA_HD *p_data = (tBTA_HD *)p_param;

    BTIF_TRACE_API("%s: event=%s", __FUNCTION__, dump_hd_event(event));

    switch (event)
    {
        case BTA_HD_ENABLE_EVT:
            BTIF_TRACE_DEBUG("%s: status=%d", __FUNCTION__, p_data->status);
            if (p_data->status == BTA_HD_OK)
            {
                btif_storage_load_hidd();
                btif_hd_cb.status = BTIF_HD_ENABLED;
            }
            else
            {
                btif_hd_cb.status = BTIF_HD_DISABLED;
                BTIF_TRACE_WARNING("Failed to enable BT-HD, status=%d", p_data->status);
            }
            break;

        case BTA_HD_DISABLE_EVT:
            BTIF_TRACE_DEBUG("%s: status=%d", __FUNCTION__, p_data->status);
            btif_hd_cb.status = BTIF_HD_DISABLED;
            if (p_data->status == BTA_HD_OK)
                memset(&btif_hd_cb, 0, sizeof(btif_hd_cb));
            else
                BTIF_TRACE_WARNING("Failed to disable BT-HD, status=%d", p_data->status);
            break;

        case BTA_HD_REGISTER_APP_EVT:
            {
                bt_bdaddr_t *addr = (bt_bdaddr_t*) &p_data->reg_status.bda;

                if (!p_data->reg_status.in_use)
                {
                    addr = NULL;
                }

                btif_hd_cb.app_registered = TRUE;
                HAL_CBACK(bt_hd_callbacks, application_state_cb, addr, BTHD_APP_STATE_REGISTERED);
        }
            break;

        case BTA_HD_UNREGISTER_APP_EVT:
            btif_hd_cb.app_registered = FALSE;
            HAL_CBACK(bt_hd_callbacks, application_state_cb, NULL, BTHD_APP_STATE_NOT_REGISTERED);
            break;

        case BTA_HD_OPEN_EVT:
            btif_storage_set_hidd((bt_bdaddr_t*) &p_data->conn.bda);

            HAL_CBACK(bt_hd_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,
                BTHD_CONN_STATE_CONNECTED);
            break;

        case BTA_HD_CLOSE_EVT:
             HAL_CBACK(bt_hd_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,
                BTHD_CONN_STATE_DISCONNECTED);
             break;

        case BTA_HD_GET_REPORT_EVT:
            HAL_CBACK(bt_hd_callbacks, get_report_cb,
                        p_data->get_report.report_type, p_data->get_report.report_id,
                        p_data->get_report.buffer_size);
            break;

        case BTA_HD_SET_REPORT_EVT:
            HAL_CBACK(bt_hd_callbacks, set_report_cb, p_data->set_report.report_type,
                p_data->set_report.report_id, p_data->set_report.len,
                p_data->set_report.p_data);
            break;

        case BTA_HD_SET_PROTOCOL_EVT:
            HAL_CBACK(bt_hd_callbacks, set_protocol_cb, p_data->set_protocol);
            break;

        case BTA_HD_INTR_DATA_EVT:
            HAL_CBACK(bt_hd_callbacks, intr_data_cb, p_data->intr_data.report_id,
                p_data->intr_data.len, p_data->intr_data.p_data);
            break;

        case BTA_HD_VC_UNPLUG_EVT:
            HAL_CBACK(bt_hd_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda,
                BTHD_CONN_STATE_DISCONNECTED);
            if (bta_dm_check_if_only_hd_connected(p_data->conn.bda)) {
                BTIF_TRACE_DEBUG("%s: Removing bonding as only HID profile connected",
                    __FUNCTION__);
                BTA_DmRemoveDevice((UINT8 *) &p_data->conn.bda);
            } else {
                bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)&p_data->conn.bda;
                BTIF_TRACE_DEBUG("%s: Only removing HID data as some other profiles "
                    "connected", __FUNCTION__);
                btif_hd_remove_device(*bd_addr);
            }
            HAL_CBACK(bt_hd_callbacks, vc_unplug_cb);
            break;

        default:
            BTIF_TRACE_WARNING("%s: unknown event (%d)", __FUNCTION__, event);
            break;
    }
}
static void bta_pan_callback_transfer(UINT16 event, char *p_param)
{
    tBTA_PAN *p_data = (tBTA_PAN *)p_param;
    switch(event)
    {
        case BTA_PAN_ENABLE_EVT:
            BTIF_TRACE_DEBUG("BTA_PAN_ENABLE_EVT");
            break;
        case BTA_PAN_SET_ROLE_EVT:
            {
                int btpan_role = bta_role_to_btpan(p_data->set_role.role);
                bt_status_t status = p_data->set_role.status == BTA_PAN_SUCCESS ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
                btpan_control_state_t state = btpan_role == 0 ? BTPAN_STATE_DISABLED : BTPAN_STATE_ENABLED;
                callback.control_state_cb(state, btpan_role, status, TAP_IF_NAME);
                break;
            }
        case BTA_PAN_OPENING_EVT:
            {
                btpan_conn_t* conn;
                bdstr_t bds;
                bd2str((bt_bdaddr_t*)p_data->opening.bd_addr, &bds);
                BTIF_TRACE_DEBUG("BTA_PAN_OPENING_EVT handle %d, addr: %s", p_data->opening.handle, bds);
                conn = btpan_find_conn_addr(p_data->opening.bd_addr);

                asrt(conn != NULL);
                if (conn)
                {
                    conn->handle = p_data->opening.handle;
                    int btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
                    int btpan_remote_role = bta_role_to_btpan(conn->remote_role);
                    callback.connection_state_cb(BTPAN_STATE_CONNECTING, BT_STATUS_SUCCESS,
                            (const bt_bdaddr_t*)p_data->opening.bd_addr, btpan_conn_local_role, btpan_remote_role);
                }
                else
                    BTIF_TRACE_ERROR("connection not found");
                break;
            }
        case BTA_PAN_OPEN_EVT:
            {
                /* debug("BTA_PAN_OPEN_EVT, open status:%d, bd_addr = [%02X:%02X:%02X:%02X:%02X:%02X]", */
                /*         p_data->open.status, */
                /*         p_data->open.bd_addr[0], p_data->open.bd_addr[1], p_data->open.bd_addr[2], */
                /*         p_data->open.bd_addr[3], p_data->open.bd_addr[4], p_data->open.bd_addr[5]); */
                btpan_connection_state_t state;
                bt_status_t status;
                btpan_conn_t *conn = btpan_find_conn_handle(p_data->open.handle);

                ALOGV("%s pan connection open status: %d", __func__, p_data->open.status);
                if(p_data->open.status == BTA_PAN_SUCCESS)
                {
                    state = BTPAN_STATE_CONNECTED;
                    status = BT_STATUS_SUCCESS;
                }
                else
                {
                    state = BTPAN_STATE_DISCONNECTED;
                    status = BT_STATUS_FAIL;
                    btpan_cleanup_conn(conn);
                }
                /* debug("BTA_PAN_OPEN_EVT handle:%d, conn:%p",  p_data->open.handle, conn); */
                /* debug("conn bta local_role:%d, bta remote role:%d", conn->local_role, conn->remote_role); */
                int btpan_conn_local_role = bta_role_to_btpan(p_data->open.local_role);
                /* debug("bta local_role:%d, bta remote role:%d", p_data->open.local_role, p_data->open.peer_role); */
                int btpan_remote_role = bta_role_to_btpan(p_data->open.peer_role);
                callback.connection_state_cb(state, status, (const bt_bdaddr_t*)p_data->open.bd_addr,
                        btpan_conn_local_role, btpan_remote_role);
                break;
            }
        case BTA_PAN_CLOSE_EVT:
            {
                btpan_conn_t* conn = btpan_find_conn_handle(p_data->close.handle);

                ALOGI("%s: event = BTA_PAN_CLOSE_EVT handle %d", __FUNCTION__, p_data->close.handle);

                if(conn && conn->handle >= 0)
                {
                    /* debug("BTA_PAN_CLOSE_EVT, conn local_role:%d, remote_role:%d", conn->local_role, conn->remote_role); */
                    int btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
                    int btpan_remote_role = bta_role_to_btpan(conn->remote_role);
                    callback.connection_state_cb(BTPAN_STATE_DISCONNECTED, 0, (const bt_bdaddr_t*)conn->peer,
                            btpan_conn_local_role, btpan_remote_role);
                    btpan_cleanup_conn(conn);
                }
                else
                    BTIF_TRACE_ERROR("pan handle not found (%d)", p_data->close.handle);
                break;
            }
        default:
            BTIF_TRACE_WARNING("Unknown pan event %d", event);
            break;
    }
}
static void btu_exec_tap_fd_read(void *p_param) {
    struct pollfd ufd;
    int fd = (int)p_param;

    if (fd == -1 || fd != btpan_cb.tap_fd)
        return;

    // Don't occupy BTU context too long, avoid GKI buffer overruns and
    // give other profiles a chance to run by limiting the amount of memory
    // PAN can use from the shared pool buffer.
    for(int i = 0; i < PAN_POOL_MAX && btif_is_enabled() && btpan_cb.flow; i++) {
        BT_HDR *buffer = (BT_HDR *)GKI_getpoolbuf(PAN_POOL_ID);
        if (!buffer) {
            BTIF_TRACE_WARNING("%s unable to allocate buffer for packet.", __func__);
            break;
        }
        buffer->offset = PAN_MINIMUM_OFFSET;
        buffer->len = GKI_get_buf_size(buffer) - sizeof(BT_HDR) - buffer->offset;

        UINT8 *packet = (UINT8 *)buffer + sizeof(BT_HDR) + buffer->offset;

        // If we don't have an undelivered packet left over, pull one from the TAP driver.
        // We save it in the congest_packet right away in case we can't deliver it in this
        // attempt.
        if (!btpan_cb.congest_packet_size) {
            ssize_t ret = read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet));
            switch (ret) {
                case -1:
                    BTIF_TRACE_ERROR("%s unable to read from driver: %s", __func__, strerror(errno));
                    GKI_freebuf(buffer);
                    return;
                case 0:
                    BTIF_TRACE_WARNING("%s end of file reached.", __func__);
                    GKI_freebuf(buffer);
                    return;
                default:
                    btpan_cb.congest_packet_size = ret;
                    break;
            }
        }

        memcpy(packet, btpan_cb.congest_packet, MIN(btpan_cb.congest_packet_size, buffer->len));
        buffer->len = MIN(btpan_cb.congest_packet_size, buffer->len);

        if (buffer->len > sizeof(tETH_HDR) && should_forward((tETH_HDR *)packet)) {
            // Extract the ethernet header from the buffer since the PAN_WriteBuf inside
            // forward_bnep can't handle two pointers that point inside the same GKI buffer.
            tETH_HDR hdr;
            memcpy(&hdr, packet, sizeof(tETH_HDR));

            // Skip the ethernet header.
            buffer->len -= sizeof(tETH_HDR);
            buffer->offset += sizeof(tETH_HDR);
            if (forward_bnep(&hdr, buffer) != FORWARD_CONGEST)
                btpan_cb.congest_packet_size = 0;
        } else {
            BTIF_TRACE_WARNING("%s dropping packet of length %d", __func__, buffer->len);
            btpan_cb.congest_packet_size = 0;
            GKI_freebuf(buffer);
        }

        // Bail out of the loop if reading from the TAP fd would block.
        ufd.fd = fd;
        ufd.events = POLLIN;
        ufd.revents = 0;
        if(poll(&ufd, 1, 0) <= 0 || IS_EXCEPTION(ufd.revents)) {
            btsock_thread_add_fd(pan_pth, fd, 0, SOCK_THREAD_FD_RD, 0);
            return;
        }
    }
}
/*******************************************************************************
**
** Function         bta_fs_co_rmdir
**
** Description      This function is called to remove a directory whose
**                  name is given by path. The directory must be empty.
**
** Parameters       p_path   - (input) name of directory to remove (fully qualified path).
**                  app_id   - (input) application ID specified in the enable functions.
**                                     It can be used to identify which profile is the caller
**                                     of the call-out function.
**
** Returns          (tBTA_FS_CO_STATUS) status of the call.
**                      [BTA_FS_CO_OK if successful]
**                      [BTA_FS_CO_EACCES if read-only]
**                      [BTA_FS_CO_ENOTEMPTY if directory is not empty]
**                      [BTA_FS_CO_FAIL otherwise]
**
*******************************************************************************/
tBTA_FS_CO_STATUS bta_fs_co_rmdir(const char *p_path, UINT8 app_id)
{
    int err, path_len;
    tBTA_FS_CO_STATUS status = BTA_FS_CO_OK;
    struct stat buffer;
    char *dirName, *tmp = NULL;

    path_len = strlen( p_path )+1;
    BTIF_TRACE_DEBUG( "bta_fs_co_rmdir( app_id: %d ): path_len: %d", app_id, path_len );
#if (TRUE==BTA_FS_DEBUG)
    BTIF_TRACE_DEBUG( "bta_fs_co_rmdir():path_len: %d, p_path", app_id );
    BTIF_TRACE_DEBUG( p_path );
#endif

    /* allocate a temp buffer for path with 0 char. make sure not to crash if path is too big! */
    dirName = (char*) calloc(1, path_len+1);
    if ( NULL != dirName )
    {
        strcpy( dirName, p_path );
    }
    else
    {
        BTIF_TRACE_WARNING( "bta_fs_co_rmdir( app_id: %d ) for path_len: %d::out of memory",
                             app_id, path_len );
        return BTA_FS_CO_FAIL;
    }

    if (NULL!= (tmp = strrchr(dirName, '/')))
    {
        *tmp = '\0';
    }
    if (stat(dirName, &buffer) == 0)
    {
        status = getAccess(6, &buffer, dirName);
    }
    else
    {
        free(dirName);
#if (TRUE==BTA_FS_DEBUG)
        BTIF_TRACE_WARNING( "bta_fs_co_rmdir()::stat(dirName) failed" );
#endif
        return BTA_FS_CO_FAIL;
    }

    free(dirName);
    if (status != BTA_FS_CO_OK)
    {
#if (TRUE==BTA_FS_DEBUG)
        BTIF_TRACE_WARNING( "bta_fs_co_rmdir()::getAccess(dirName) FAILED");
#endif
        return status;
    }

    if (stat(p_path, &buffer) == 0)
    {
        status = getAccess(6, &buffer, (char*)p_path);
    }
    else
    {
#if (TRUE==BTA_FS_DEBUG)
        BTIF_TRACE_WARNING( "bta_fs_co_rmdir()::stat(p_path) FAILED");
#endif
        return BTA_FS_CO_FAIL;
    }

    if (status != BTA_FS_CO_OK)
    {
#if (TRUE==BTA_FS_DEBUG)
        BTIF_TRACE_DEBUG( "bta_fs_co_rmdir()::getAccess(p_path) FAILED");
#endif
        return status;
    }
    //if ((rmdir (p_path)) != 0)
    if (del_path(p_path) != 0)
    {
        err = errno;
        BTIF_TRACE_WARNING( "bta_fs_co_rmdir():rmdir/del_path FAILED with err: %d", err );
        if (err == EACCES)
            status = BTA_FS_CO_EACCES;
        else if (err == ENOTEMPTY)
            status = BTA_FS_CO_ENOTEMPTY;
        else
            status = BTA_FS_CO_FAIL;
    }
    return (status);
}
/*******************************************************************************
**
** Function         bta_fs_co_getdirentry
**
** Description      This function is called to get a directory entry for the
**                  specified p_path.  The first/next directory should be filled
**                  into the location specified by p_entry.
**
** Parameters       p_path      - directory to search (Fully qualified path)
**                  first_item  - TRUE if first search, FALSE if next search
**                                      (p_cur contains previous)
**                  p_entry (input/output) - Points to last entry data (valid when
**                                           first_item is FALSE)
**                  evt     - event that must be passed into the call-in function.
**                  app_id  - application ID specified in the enable functions.
**                            It can be used to identify which profile is the caller
**                            of the call-out function.
**
** Returns          void
**
**                  Note: Upon completion of the request, the status is passed
**                        in the bta_fs_ci_direntry() call-in function.
**                        BTA_FS_CO_OK is returned when p_entry is valid,
**                        BTA_FS_CO_EODIR is returned when no more entries [finished]
**                        BTA_FS_CO_FAIL is returned if an error occurred
**
*******************************************************************************/
void bta_fs_co_getdirentry(const char *p_path, BOOLEAN first_item,
                           tBTA_FS_DIRENTRY *p_entry, UINT16 evt, UINT8 app_id)
{
    tBTA_FS_CO_STATUS    co_status = BTA_FS_CO_FAIL;
    int                  status = -1;    /* '0' - success, '-1' - fail */
    struct tm           *p_tm;
    DIR *dir;
    struct dirent *dirent;
    struct stat buf;
    char fullname[500];
    UNUSED(app_id);

    BTIF_TRACE_DEBUG("Entered bta_fs_co_getdirentry");

    /* First item is to be retrieved */
    if (first_item)
    {
        BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: path = %s", p_path);

        dir = opendir(p_path);
        if(dir == NULL)
        {
     	    BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dir is NULL so error out with errno=%d", errno);
            co_status = BTA_FS_CO_EODIR;
            bta_fs_ci_direntry(co_status, evt);
            return;
        }

        BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dir = %p", dir);
        if((dirent = readdir(dir)) != NULL)
        {
            p_entry->refdata = (UINT32) dir;     /* Save this for future searches */
            status = 0;
            BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dirent = %p", dirent);
        }
        else
        {
            BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dirent = %p", dirent);
            /* Close the search if there are no more items */
            closedir( (DIR*) p_entry->refdata);
            co_status = BTA_FS_CO_EODIR;
        }
    }
    else    /* Get the next entry based on the p_ref data from previous search */
    {
        if ((dirent = readdir((DIR*)p_entry->refdata))  == NULL)
        {
            /* Close the search if there are no more items */
            closedir( (DIR*) p_entry->refdata);
            co_status = BTA_FS_CO_EODIR;
            BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dirent = %p", dirent);
        }
        else
        {
            BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dirent = %p", dirent);
            status = 0;
        }
    }

    if (status == 0)
    {
        BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: status = 0");

        sprintf(fullname, "%s/%s", p_path,  dirent->d_name);

        /* Load new values into the return structure (refdata is left untouched) */
        if (stat(fullname, &buf) == 0) {
            p_entry->filesize = buf.st_size;
            p_entry->mode = 0; /* Default is normal read/write file access */

            if (S_ISDIR(buf.st_mode))
                p_entry->mode |= BTA_FS_A_DIR;
            else
                p_entry->mode |= BTA_FS_A_RDONLY;

            strcpy(p_entry->p_name, dirent->d_name);
#if 0
            fprintf(stderr, "bta_fs_co_getdirentry(): %s %9d %d\n",
                            dirent->d_name,
                            buf.st_size,
                            p_entry->mode);
#endif
            p_tm = localtime((const time_t*)&buf.st_mtime);
            if (p_tm != NULL)
            {
                sprintf(p_entry->crtime, "%04d%02d%02dT%02d%02d%02dZ",
                        p_tm->tm_year + 1900,   /* Base Year ISO 6201 */
                        p_tm->tm_mon + 1,       /* month starts at 0 */
                        p_tm->tm_mday,
                        p_tm->tm_hour,
                        p_tm->tm_min,
                        p_tm->tm_sec);
            }
            else
                p_entry->crtime[0] = '\0';  /* No valid time */
#if 0
            fprintf(stderr, "bta_fs_co_getdirentry(): %s %9d %d %s\n",
                            dirent->d_name,
                            p_entry->filesize,
                            p_entry->mode,
                            p_entry->crtime);
#endif
            co_status = BTA_FS_CO_OK;
        } else {
            BTIF_TRACE_WARNING("stat() failed! ");
            co_status = BTA_FS_CO_EACCES;
        }
    }
    BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: calling bta_fs_ci_getdirentry");

    bta_fs_ci_direntry(co_status, evt);
}
Пример #23
0
/*******************************************************************************
**
** Function         btif_hf_client_upstreams_evt
**
** Description      Executes HF CLIENT UPSTREAMS events in btif context
**
** Returns          void
**
*******************************************************************************/
static void btif_hf_client_upstreams_evt(UINT16 event, char* p_param)
{
    tBTA_HF_CLIENT *p_data = (tBTA_HF_CLIENT *)p_param;
    bdstr_t bdstr;

    BTIF_TRACE_DEBUG("%s: event=%s (%u)", __FUNCTION__, dump_hf_client_event(event), event);

    switch (event)
    {
        case BTA_HF_CLIENT_ENABLE_EVT:
        case BTA_HF_CLIENT_DISABLE_EVT:
            break;

        case BTA_HF_CLIENT_REGISTER_EVT:
            btif_hf_client_cb.handle = p_data->reg.handle;
            break;

        case BTA_HF_CLIENT_OPEN_EVT:
            if (p_data->open.status == BTA_HF_CLIENT_SUCCESS)
            {
                bdcpy(btif_hf_client_cb.connected_bda.address, p_data->open.bd_addr);
                btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_CONNECTED;
                btif_hf_client_cb.peer_feat = 0;
                btif_hf_client_cb.chld_feat = 0;
                //clear_phone_state();
            }
            else if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING)
            {
                btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
            }
            else
            {
                BTIF_TRACE_WARNING("%s: HF CLient open failed, but another device connected. status=%d state=%d connected device=%s",
                        __FUNCTION__, p_data->open.status, btif_hf_client_cb.state, bdaddr_to_string(&btif_hf_client_cb.connected_bda, bdstr, sizeof(bdstr)));
                break;
            }

            HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state,
                        0, 0, &btif_hf_client_cb.connected_bda);

            if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
                bdsetany(btif_hf_client_cb.connected_bda.address);

            if (p_data->open.status != BTA_HF_CLIENT_SUCCESS)
                btif_queue_advance();
            break;

        case BTA_HF_CLIENT_CONN_EVT:
            btif_hf_client_cb.peer_feat = p_data->conn.peer_feat;
            btif_hf_client_cb.chld_feat = p_data->conn.chld_feat;
            btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED;

            HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state,
                        btif_hf_client_cb.peer_feat, btif_hf_client_cb.chld_feat,
                        &btif_hf_client_cb.connected_bda);

            /* Inform the application about in-band ringtone */
            if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_INBAND)
            {
                HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
            }

            btif_queue_advance();
            break;

        case BTA_HF_CLIENT_CLOSE_EVT:
            btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
            HAL_CBACK(bt_hf_client_callbacks, connection_state_cb,  btif_hf_client_cb.state,
                        0, 0, &btif_hf_client_cb.connected_bda);
            bdsetany(btif_hf_client_cb.connected_bda.address);
            btif_hf_client_cb.peer_feat = 0;
            btif_hf_client_cb.chld_feat = 0;
            btif_queue_advance();
            break;

        case BTA_HF_CLIENT_IND_EVT:
            process_ind_evt(&p_data->ind);
            break;

        case BTA_HF_CLIENT_MIC_EVT:
            HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_MIC, p_data->val.value);
            break;

        case BTA_HF_CLIENT_SPK_EVT:
            HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_SPK, p_data->val.value);
            break;

        case BTA_HF_CLIENT_VOICE_REC_EVT:
            HAL_CBACK(bt_hf_client_callbacks, vr_cmd_cb, p_data->val.value);
            break;

        case BTA_HF_CLIENT_OPERATOR_NAME_EVT:
            HAL_CBACK(bt_hf_client_callbacks, current_operator_cb, p_data->operator.name);
            break;

        case BTA_HF_CLIENT_CLIP_EVT:
            HAL_CBACK(bt_hf_client_callbacks, clip_cb, p_data->number.number);
            break;

        case BTA_HF_CLIENT_BINP_EVT:
            HAL_CBACK(bt_hf_client_callbacks, last_voice_tag_number_callback, p_data->number.number);
            break;

        case BTA_HF_CLIENT_CCWA_EVT:
            HAL_CBACK(bt_hf_client_callbacks, call_waiting_cb, p_data->number.number);
            break;

        case BTA_HF_CLIENT_AT_RESULT_EVT:
            HAL_CBACK(bt_hf_client_callbacks, cmd_complete_cb, p_data->result.type, p_data->result.cme);
            break;

        case BTA_HF_CLIENT_CLCC_EVT:
            HAL_CBACK(bt_hf_client_callbacks, current_calls_cb, p_data->clcc.idx,
                        p_data->clcc.inc ? BTHF_CLIENT_CALL_DIRECTION_INCOMING : BTHF_CLIENT_CALL_DIRECTION_OUTGOING,
                        p_data->clcc.status,
                        p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE,
                        p_data->clcc.number_present ? p_data->clcc.number : NULL);
            break;

        case BTA_HF_CLIENT_CNUM_EVT:
            if (p_data->cnum.service == 4)
            {
                HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_VOICE);
            }
            else if (p_data->cnum.service == 5)
            {
                HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_FAX);
            }
            else
            {
                HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_UNKNOWN);
            }
            break;

        case BTA_HF_CLIENT_BTRH_EVT:
            if (p_data->val.value <= BTRH_CLIENT_RESP_AND_HOLD_REJECT)
            {
                HAL_CBACK(bt_hf_client_callbacks, resp_and_hold_cb, p_data->val.value);
            }
            break;

        case BTA_HF_CLIENT_BSIR_EVT:
            if (p_data->val.value != 0)
            {
                HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
            }
            else
            {
                HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED);
            }
            break;

        case BTA_HF_CLIENT_AUDIO_OPEN_EVT:
            HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED, &btif_hf_client_cb.connected_bda);
            break;

        case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT:
            HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, &btif_hf_client_cb.connected_bda);
            break;

        case BTA_HF_CLIENT_AUDIO_CLOSE_EVT:
            HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_DISCONNECTED, &btif_hf_client_cb.connected_bda);
            break;
        case BTA_HF_CLIENT_RING_INDICATION:
            HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb);
            break;
        default:
            BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
            break;
    }
}