static void *rfcomm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
{
    int rc;
    void* new_user_data = NULL;
    APPL_TRACE_DEBUG1("event=%s", jv_evt[event]);

    switch (event)
    {
    case BTA_JV_RFCOMM_START_EVT:
        on_srv_rfc_listen_started(&p_data->rfc_start, (uint32_t)user_data);
        break;

    case BTA_JV_RFCOMM_CL_INIT_EVT:
        on_cl_rfc_init(&p_data->rfc_cl_init, (uint32_t)user_data);
        break;

    case BTA_JV_RFCOMM_OPEN_EVT:
        BTA_JvSetPmProfile(p_data->rfc_open.handle,BTA_JV_PM_ID_1,BTA_JV_CONN_OPEN);
        on_cli_rfc_connect(&p_data->rfc_open, (uint32_t)user_data);
        break;
    case BTA_JV_RFCOMM_SRV_OPEN_EVT:
        BTA_JvSetPmProfile(p_data->rfc_srv_open.handle,BTA_JV_PM_ALL,BTA_JV_CONN_OPEN);
        new_user_data = (void*)on_srv_rfc_connect(&p_data->rfc_srv_open, (uint32_t)user_data);
        break;

    case BTA_JV_RFCOMM_CLOSE_EVT:
        APPL_TRACE_DEBUG1("BTA_JV_RFCOMM_CLOSE_EVT: user_data:%d", (uint32_t)user_data);
        on_rfc_close(&p_data->rfc_close, (uint32_t)user_data);
        break;

    case BTA_JV_RFCOMM_READ_EVT:
        APPL_TRACE_DEBUG0("BTA_JV_RFCOMM_READ_EVT not used");
        break;

    case BTA_JV_RFCOMM_WRITE_EVT:
        on_rfc_write_done(&p_data->rfc_write, (uint32_t)user_data);
        break;

    case BTA_JV_RFCOMM_DATA_IND_EVT:
        APPL_TRACE_DEBUG0("BTA_JV_RFCOMM_DATA_IND_EVT not used");
        break;

    case BTA_JV_RFCOMM_CONG_EVT:
        //on_rfc_cong(&p_data->rfc_cong);
        on_rfc_outgoing_congest(&p_data->rfc_cong, (uint32_t)user_data);
        break;
    default:
        APPL_TRACE_ERROR2("unhandled event %d, slot id:%d", event, (uint32_t)user_data);
        break;
    }
    return new_user_data;
}
Пример #2
0
int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id)
{
    if(h < 0 || h >= MAX_THREAD)
    {
        APPL_TRACE_ERROR1("invalid bt thread handle:%d", h);
        return FALSE;
    }
    if(ts[h].cmd_fdw == -1)
    {
        APPL_TRACE_ERROR0("cmd socket is not created. socket thread may not initialized");
        return FALSE;
    }
    if(flags & SOCK_THREAD_ADD_FD_SYNC)
    {
        //must executed in socket poll thread
        if(ts[h].thread_id == pthread_self())
        {
            //cleanup one-time flags
            flags &= ~SOCK_THREAD_ADD_FD_SYNC;
            add_poll(h, fd, type, flags, user_id);
            return TRUE;
        }
        APPL_TRACE_DEBUG0("THREAD_ADD_FD_SYNC is not called in poll thread, fallback to async");
    }
    sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id};
    APPL_TRACE_DEBUG2("adding fd:%d, flags:0x%x", fd, flags);
    return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
}
Пример #3
0
void bta_hf_client_send_at_bia(void)
{
    char buf[BTA_HF_CLIENT_AT_MAX_LEN];
    int at_len;
    int i;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);
    if (bta_hf_client_cb.scb.peer_version < HFP_VERSION_1_6)
    {
        APPL_TRACE_DEBUG0("Remote does not Support AT+BIA");
        return;
    }

    at_len = snprintf(buf, sizeof(buf), "AT+BIA=");

    for(i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++)
    {
        int sup = bta_hf_client_cb.scb.at_cb.indicator_lookup[i] == -1 ? 0 : 1;

        at_len += snprintf(buf + at_len, sizeof(buf) - at_len, "%u,", sup);
    }

    buf[at_len - 1] = '\r';

    if (at_len < 0)
    {
        APPL_TRACE_ERROR0("HFPClient: AT command Framing error");
        return;
    }
    bta_hf_client_send_at(BTA_HF_CLIENT_AT_BIA, buf, at_len);
}
Пример #4
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_start
 **
 ** Description      This function is called by AV when the audio streaming data
 **                  transfer is started.
 **
 **
 ** Returns          void
 **
 *******************************************************************************/
BTA_API void bta_av_co_audio_start(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
        UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr)
{
    FUNC_TRACE();

    APPL_TRACE_DEBUG0("bta_av_co_audio_start");

}
/*******************************************************************************
**
** Function         bta_hl_find_sink_or_src_srv_class_in_db
**
** Description      This function queries an SDP database for either a HDP Sink or
**                  Source service class ID.
**                  If the p_start_rec pointer is NULL, it looks from the beginning
**                  of the database, else it continues from the next record after
**                  p_start_rec.
**
** Returns          Pointer to record containing service class, or NULL
**
*******************************************************************************/
tSDP_DISC_REC *bta_hl_find_sink_or_src_srv_class_in_db (const tSDP_DISCOVERY_DB *p_db,
                                                        const tSDP_DISC_REC *p_start_rec)
{
#if SDP_CLIENT_ENABLED == TRUE
    tSDP_DISC_REC   *p_rec;
    tSDP_DISC_ATTR  *p_attr, *p_sattr;

    /* Must have a valid database */
    if (p_db == NULL)
        return(NULL);


    if (!p_start_rec)
    {

        p_rec = p_db->p_first_rec;
    }
    else
    {
        p_rec = p_start_rec->p_next_rec;
    }

    while (p_rec)
    {
        p_attr = p_rec->p_first_attr;
        while (p_attr)
        {
            if ((p_attr->attr_id == ATTR_ID_SERVICE_CLASS_ID_LIST)
                && (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == DATA_ELE_SEQ_DESC_TYPE))
            {
                for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr; p_sattr = p_sattr->p_next_attr)
                {
                    if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UUID_DESC_TYPE)
                        && (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 2)
                        && ( (p_sattr->attr_value.v.u16 == UUID_SERVCLASS_HDP_SINK) ||
                             (p_sattr->attr_value.v.u16 == UUID_SERVCLASS_HDP_SOURCE)) )
                    {
                        return(p_rec);
                    }
                }
                break;
            }

            p_attr = p_attr->p_next_attr;
        }

        p_rec = p_rec->p_next_rec;
    }
#endif
    /* If here, no matching UUID found */

#if BTA_HL_DEBUG == TRUE
    APPL_TRACE_DEBUG0("bta_hl_find_sink_or_src_srv_class_in_db failed");
#endif

    return(NULL);
}
static inline rfc_slot_t* find_rfc_slot_requesting_sdp()
{
    int i;
    for(i = 0; i < MAX_RFC_CHANNEL; i++)
    {
        if(rfc_slots[i].id && rfc_slots[i].f.doing_sdp_request)
                return &rfc_slots[i];
    }
    APPL_TRACE_DEBUG0("can not find any slot is requesting sdp");
    return NULL;
}
Пример #7
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_sink_supports_cp
 **
 ** Description      Check if a sink supports the current content protection
 **
 ** Returns          TRUE if the sink supports this CP, FALSE otherwise
 **
 *******************************************************************************/
static BOOLEAN bta_av_co_audio_sink_supports_cp(const tBTA_AV_CO_SINK *p_sink)
{
    FUNC_TRACE();

    /* Check if content protection is enabled for this stream */
    if (bta_av_co_cp_get_flag() != BTA_AV_CP_SCMS_COPY_FREE)
    {
        return bta_av_co_audio_sink_has_scmst(p_sink);
    }
    else
    {
        APPL_TRACE_DEBUG0("bta_av_co_audio_sink_supports_cp: not required");
        return TRUE;
    }
}
Пример #8
0
void bta_hf_client_send_at_cnum(void)
{
    char *buf;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (!service_availability)
    {
        APPL_TRACE_DEBUG0("Skip AT+CNUM no Service");
        return;
    }
    buf = "AT+CNUM\r";

    bta_hf_client_send_at(BTA_HF_CLIENT_AT_CNUM, buf, strlen(buf));
}
/*******************************************************************************
**
** Function         bta_av_hdl_event
**
** Description      Advanced audio/video main event handling function.
**
**
** Returns          BOOLEAN
**
*******************************************************************************/
BOOLEAN bta_av_hdl_event(BT_HDR *p_msg)
{
    UINT16 event = p_msg->event;
    UINT16 first_event = BTA_AV_FIRST_NSM_EVT;

    if (event > BTA_AV_LAST_EVT)
    {
        return TRUE; /* to free p_msg */
    }

    if(event >= first_event)
    {
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
        APPL_TRACE_VERBOSE2("AV nsm event=0x%x(%s)", event, bta_av_evt_code(event));
#else
        APPL_TRACE_VERBOSE1("AV nsm event=0x%x", event);
#endif
        /* non state machine events */
        (*bta_av_nsm_act[event - BTA_AV_FIRST_NSM_EVT]) ((tBTA_AV_DATA *) p_msg);
#ifdef A2DP_SINK
        if (event == BTA_AV_CI_SNK_DATA_READY_EVT)
        {
            APPL_TRACE_DEBUG0("not to free p_msg, media task uses it directly to avoid memory copy");
            return FALSE;
        }
#endif
    }
    else if (event >= BTA_AV_FIRST_SM_EVT && event <= BTA_AV_LAST_SM_EVT)
    {
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
        APPL_TRACE_VERBOSE2("AV sm event=0x%x(%s)", event, bta_av_evt_code(event));
#else
        APPL_TRACE_VERBOSE1("AV sm event=0x%x", event);
#endif
        /* state machine events */
        bta_av_sm_execute(&bta_av_cb, p_msg->event, (tBTA_AV_DATA *) p_msg);
    }
    else
    {
        APPL_TRACE_VERBOSE1("handle=0x%x", p_msg->layer_specific);
        /* stream state machine events */
        bta_av_ssm_execute( bta_av_hndl_to_scb(p_msg->layer_specific),
                                p_msg->event, (tBTA_AV_DATA *) p_msg);
    }
    return TRUE;
}
Пример #10
0
/*******************************************************************************
**
** Function         bta_ag_get_other_idle_scb
**
** Description      Return other scb if it is in INIT st.
**
**
** Returns          Pointer to other scb if INIT st, NULL otherwise.
**
*******************************************************************************/
tBTA_AG_SCB *bta_ag_get_other_idle_scb (tBTA_AG_SCB *p_curr_scb)
{
    tBTA_AG_SCB     *p_scb = &bta_ag_cb.scb[0];
    UINT8   xx;

    for (xx = 0; xx < BTA_AG_NUM_SCB; xx++, p_scb++)
    {
        if (p_scb->in_use && (p_scb != p_curr_scb) && (p_scb->state == BTA_AG_INIT_ST))
        {
            return p_scb;
        }
    }

    /* no other scb found */
    APPL_TRACE_DEBUG0("bta_ag_get_other_idle_scb: No idle AG scb");
    return NULL;
}
Пример #11
0
/*******************************************************************************
**
** Function         bta_ag_other_scb_open
**
** Description      Check whether any other scb is in open state.
**
**
** Returns          TRUE if another scb is in open state, FALSE otherwise.
**
*******************************************************************************/
BOOLEAN bta_ag_other_scb_open(tBTA_AG_SCB *p_curr_scb)
{
    tBTA_AG_SCB     *p_scb = &bta_ag_cb.scb[0];
    int             i;

    for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++)
    {
        if (p_scb->in_use && p_scb != p_curr_scb && p_scb->state == BTA_AG_OPEN_ST)
        {
            return TRUE;
        }
    }

    /* no other scb found */
    APPL_TRACE_DEBUG0("No other ag scb open");
    return FALSE;
}
Пример #12
0
void bta_hf_client_send_at_cops(BOOLEAN query)
{
    char *buf;

    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    if (!service_availability)
    {
        APPL_TRACE_DEBUG0("Skip AT+COPS no service");
        return;
    }
    if (query)
        buf = "AT+COPS?\r";
    else
        buf = "AT+COPS=3,0\r";

    bta_hf_client_send_at(BTA_HF_CLIENT_AT_COPS, buf, strlen(buf));
}
Пример #13
0
/*******************************************************************************
 **
 ** Function         bta_av_co_cp_is_scmst
 **
 ** Description      Check if a content protection service is SCMS-T
 **
 ** Returns          TRUE if this CP is SCMS-T, FALSE otherwise
 **
 *******************************************************************************/
static BOOLEAN bta_av_co_cp_is_scmst(const UINT8 *p_protectinfo)
{
    UINT16 cp_id;
    FUNC_TRACE();

    if (*p_protectinfo >= BTA_AV_CP_LOSC)
    {
        p_protectinfo++;
        STREAM_TO_UINT16(cp_id, p_protectinfo);
        if (cp_id == BTA_AV_CP_SCMS_T_ID)
        {
            APPL_TRACE_DEBUG0("bta_av_co_cp_is_scmst: SCMS-T found");
            return TRUE;
        }
    }

    return FALSE;
}
Пример #14
0
/*******************************************************************************
**
** Function         bta_ag_colli_timer_cback
**
** Description      AG connection collision timer callback
**
**
** Returns          void
**
*******************************************************************************/
static void bta_ag_colli_timer_cback (TIMER_LIST_ENT *p_tle)
{
    tBTA_AG_SCB *p_scb;

    APPL_TRACE_DEBUG0 ("bta_ag_colli_timer_cback");

    if (p_tle)
    {
        p_scb = (tBTA_AG_SCB *)p_tle->param;

        if (p_scb)
        {
            p_scb->colli_tmr_on = FALSE;

            /* If the peer haven't opened AG connection     */
            /* we will restart opening process.             */
            bta_ag_resume_open (p_scb);
        }
    }
}
Пример #15
0
/*******************************************************************************
**
** Function     bta_mce_get_remote_mas_instances
**
** Description  Discovers MAS instances on remote device
**
** Returns      void
**
*******************************************************************************/
void bta_mce_get_remote_mas_instances(tBTA_MCE_MSG *p_data)
{
    if(p_data == NULL)
    {
    APPL_TRACE_DEBUG0("MCE control block handle is null");
    return;
    }
    tBTA_MCE_STATUS status = BTA_MCE_FAILURE;

    APPL_TRACE_DEBUG2("%s in, sdp_active:%d", __FUNCTION__, bta_mce_cb.sdp_active);

    if (bta_mce_cb.sdp_active != BTA_MCE_SDP_ACT_NONE)
    {
        /* SDP is still in progress */
        status = BTA_MCE_BUSY;
        if(bta_mce_cb.p_dm_cback)
            bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, (tBTA_MCE *)&status, NULL);

        return;
    }

    bta_mce_cb.sdp_active = BTA_MCE_SDP_ACT_YES;
    bdcpy(bta_mce_cb.remote_addr, p_data->get_rmt_mas.bd_addr);

    SDP_InitDiscoveryDb (p_bta_mce_cfg->p_sdp_db, p_bta_mce_cfg->sdp_db_size, 1,
                                (tBT_UUID*) &bta_mce_mas_uuid, 0, NULL);

    if (!SDP_ServiceSearchAttributeRequest2(p_data->get_rmt_mas.bd_addr, p_bta_mce_cfg->p_sdp_db,
                                                bta_mce_search_cback, NULL))
    {
        bta_mce_cb.sdp_active = BTA_MCE_SDP_ACT_NONE;

        /* failed to start SDP. report the failure right away */
        if (bta_mce_cb.p_dm_cback)
            bta_mce_cb.p_dm_cback(BTA_MCE_MAS_DISCOVERY_COMP_EVT, (tBTA_MCE *)&status, NULL);
    }
    /*
    else report the result when the cback is called
    */
}
Пример #16
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_close
 **
 ** Description      This function is called by AV when the audio stream connection
 **                  is closed.
 **
 **
 ** Returns          void
 **
 *******************************************************************************/
BTA_API void bta_av_co_audio_close(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT16 mtu)

{
    tBTA_AV_CO_PEER *p_peer;

    FUNC_TRACE();

    APPL_TRACE_DEBUG0("bta_av_co_audio_close");

    /* Retrieve the peer info */
    p_peer = bta_av_co_get_peer(hndl);
    if (p_peer)
    {
        /* Mark the peer closed and clean the peer info */
        memset(p_peer, 0, sizeof(*p_peer));
    }
    else
    {
        APPL_TRACE_ERROR0("bta_av_co_audio_close could not find peer entry");
    }

    /* reset remote preference through setconfig */
    bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_NONE;
}
int bta_ma_co_open(const char *p_path, int oflags) {
    struct stat file_stat;
    int fd;
    /* Convert BTA oflags into MFS */
    oflags = bta_fs_convert_bta_oflags(oflags);


    if ((fd = open (p_path, oflags | O_NONBLOCK, 0666)) < 0)
    {
      APPL_TRACE_ERROR2("%s: Error opening file: error code %d", __FUNCTION__, fd);
      return BTA_FS_INVALID_FD;
    }
    else
    {
      if(fstat(fd, &file_stat) == 0)
	{
	  if (oflags & O_CREAT) {
	    fchown(fd, BT_UID, BT_GID);
	    APPL_TRACE_DEBUG0("\n ******CHANGED OWNERSHIP SUCCESSFULLY**********");
	  }
	}
      return fd;
    }
}
Пример #18
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_sink_has_scmst
 **
 ** Description      Check if a sink supports SCMS-T
 **
 ** Returns          TRUE if the sink supports this CP, FALSE otherwise
 **
 *******************************************************************************/
static BOOLEAN bta_av_co_audio_sink_has_scmst(const tBTA_AV_CO_SINK *p_sink)
{
    UINT8 index;
    const UINT8 *p;
    FUNC_TRACE();

    /* Check if sink supports SCMS-T */
    index = p_sink->num_protect;
    p = &p_sink->protect_info[0];

    while (index)
    {
        if (bta_av_co_cp_is_scmst(p))
        {
            return TRUE;
        }
        /* Move to the next SC */
        p += *p + 1;
        /* Decrement the SC counter */
        index--;
    }
    APPL_TRACE_DEBUG0("bta_av_co_audio_sink_has_scmst: SCMS-T not found");
    return FALSE;
}
static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
{
    uint32_t id = (uint32_t)user_data;
    APPL_TRACE_DEBUG2("jv_dm_cback: event:%d, slot id:%d", event, id);
    switch(event)
    {
        case BTA_JV_CREATE_RECORD_EVT:
            {
                lock_slot(&slot_lock);
                rfc_slot_t* rs = find_rfc_slot_by_id(id);
                if(rs && create_server_sdp_record(rs))
                {
                    //now start the rfcomm server after sdp & channel # assigned
                    BTA_JvRfcommStartServer(rs->security, rs->role, rs->scn, MAX_RFC_SESSION, rfcomm_cback,
                                            (void*)rs->id);
                }
                else if(rs)
                {
                    APPL_TRACE_ERROR1("jv_dm_cback: cannot start server, slot found:%p", rs);
                    cleanup_rfc_slot(rs);
                }
                unlock_slot(&slot_lock);
                break;
            }
        case BTA_JV_DISCOVERY_COMP_EVT:
            {
                rfc_slot_t* rs = NULL;
                lock_slot(&slot_lock);
                if(p_data->disc_comp.status == BTA_JV_SUCCESS && p_data->disc_comp.scn)
                {
                    APPL_TRACE_DEBUG3("BTA_JV_DISCOVERY_COMP_EVT, slot id:%d, status:%d, scn:%d",
                                      id, p_data->disc_comp.status, p_data->disc_comp.scn);

                    rs = find_rfc_slot_by_id(id);
                    if(rs && rs->f.doing_sdp_request)
                    {
                        if(BTA_JvRfcommConnect(rs->security, rs->role, p_data->disc_comp.scn, rs->addr.address,
                                    rfcomm_cback, (void*)rs->id) == BTA_JV_SUCCESS)
                        {
                            rs->scn = p_data->disc_comp.scn;
                            rs->f.doing_sdp_request = FALSE;
                            if(!send_app_scn(rs))
                                cleanup_rfc_slot(rs);
                        }
                        else cleanup_rfc_slot(rs);
                    }
                    else if(rs)
                    {
                        APPL_TRACE_ERROR3("DISCOVERY_COMP_EVT no pending sdp request, slot id:%d, \
                                flag sdp pending:%d, flag sdp doing:%d",
                                id, rs->f.pending_sdp_request, rs->f.doing_sdp_request);
                    }
                }
                else
                {
                    APPL_TRACE_ERROR3("DISCOVERY_COMP_EVT slot id:%d, failed to find channle, \
                                      status:%d, scn:%d", id, p_data->disc_comp.status,
                                      p_data->disc_comp.scn);
                    rs = find_rfc_slot_by_id(id);
                    if(rs)
                        cleanup_rfc_slot(rs);
                }
                rs = find_rfc_slot_by_pending_sdp();
                if(rs)
                {
                    APPL_TRACE_DEBUG0("BTA_JV_DISCOVERY_COMP_EVT, start another pending scn sdp request");
                    tSDP_UUID sdp_uuid;
                    sdp_uuid.len = 16;
                    memcpy(sdp_uuid.uu.uuid128, rs->service_uuid, sizeof(sdp_uuid.uu.uuid128));
                    BTA_JvStartDiscovery((UINT8*)rs->addr.address, 1, &sdp_uuid, (void*)rs->id);
                    rs->f.pending_sdp_request = FALSE;
                    rs->f.doing_sdp_request = TRUE;
                }
                unlock_slot(&slot_lock);
                break;
            }
/*******************************************************************************
**
** Function         bta_hh_hdl_event
**
** Description      HID host main event handling function.
**
**
** Returns          void
**
*******************************************************************************/
BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
{
    UINT8           index = BTA_HH_IDX_INVALID;
    tBTA_HH_DEV_CB *p_cb = NULL;
	APPL_TRACE_DEBUG1("RTKDBG:p_msg->event:(%d)", p_msg->event);
    switch (p_msg->event)
    {
        case BTA_HH_API_ENABLE_EVT:
            bta_hh_api_enable((tBTA_HH_DATA *) p_msg);
            break;

        case BTA_HH_API_DISABLE_EVT:
            bta_hh_api_disable();
            break;

        case BTA_HH_DISC_CMPL_EVT:          /* disable complete */
            bta_hh_disc_cmpl();
            break;

#ifdef BLUETOOTH_RTK
        case BTA_HH_API_RM_DEV_EVT:
            APPL_TRACE_DEBUG0("BTA_HH_API_RM_DEV_EVT");
            index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
             if (index != BTA_HH_IDX_INVALID)
                p_cb = &bta_hh_cb.kdev[index];
            if (p_cb != NULL && p_cb->is_le_device)
            {
                bta_hh_le_remove_dev_bg_conn(p_cb);
                bta_hh_sm_execute(p_cb, BTA_HH_API_CLOSE_EVT, NULL);
                bta_hh_clean_up_kdev(p_cb);
            }
            break;
#endif
        default:
            /* all events processed in state machine need to find corresponding
                CB before proceed */
            if (p_msg->event == BTA_HH_API_OPEN_EVT)
            {
                index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
            }
            else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT)
            {
                /* if add device */
                if (((tBTA_HH_MAINT_DEV *)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT)
                {
                    index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV *)p_msg)->bda);
                }
                else /* else remove device by handle */
                {
                    index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
// btla-specific ++
                    /* If BT disable is done while the HID device is connected and Link_Key uses unauthenticated combination
                      * then we can get into a situation where remove_bonding is called with the index set to 0 (without getting
                      * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the index and make it MAX_KNOWN.
                      * So if REMOVE_DEVICE is called and in_use is FALSE then we should treat this as a NULL p_cb. Hence we
                      * force the index to be IDX_INVALID
                      */
                    if ((index != BTA_HH_IDX_INVALID) &&
                        (bta_hh_cb.kdev[index].in_use == FALSE)) {
                        index = BTA_HH_IDX_INVALID;
                    }
// btla-specific --
                }
            }
            else if (p_msg->event == BTA_HH_INT_OPEN_EVT)
            {
                index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
            }
            else
                index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);

            if (index != BTA_HH_IDX_INVALID)
                p_cb = &bta_hh_cb.kdev[index];

#if BTA_HH_DEBUG
            APPL_TRACE_DEBUG2("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", p_msg->layer_specific, index);
#endif
            bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA *) p_msg);
    }
    return (TRUE);
}
Пример #21
0
/*******************************************************************************
**
** Function         bta_hh_start_sdp
**
** Description      Start SDP service search, and obtain necessary SDP records.
**                  Only one SDP service search request is allowed at the same
**                  time. For every BTA_HhOpen API call, do SDP first unless SDP
**                  has been done previously.
**
** Returns          void
**
*******************************************************************************/
void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
{
    tBTA_HH_STATUS          status = BTA_HH_ERR_SDP;
    UINT8                   hdl;

    p_cb->sec_mask  = p_data->api_conn.sec_mask;
    p_cb->mode      = p_data->api_conn.mode;
    bta_hh_cb.p_cur = p_cb;

    /* if previously virtually cabled device, skip SDP */
    if (p_cb->app_id)
    {
        status = BTA_HH_OK;
#if BTA_HH_DEBUG
        APPL_TRACE_DEBUG0("bta_hh_start_sdp:: skip SDP for known devices");
#endif
        if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE)
        {
            if ((HID_HostAddDev (p_cb->addr, p_cb->attr_mask, &hdl)) \
                == HID_SUCCESS)
            {
                /* update device CB with newly register device handle */
                bta_hh_add_device_to_list(p_cb,  hdl, p_cb->attr_mask, NULL,
                                          p_cb->sub_class,
                                          p_cb->dscp_info.ssr_max_latency,
                                          p_cb->dscp_info.ssr_min_tout,
                                          p_cb->app_id);
                /* update cb_index[] map */
                bta_hh_cb.cb_index[hdl] = p_cb->index;
            }
            else
                status = BTA_HH_ERR_NO_RES;
        }
        bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status);

        return;
    }
    /* GetSDPRecord. at one time only one SDP precedure can be active */
    else if (!bta_hh_cb.p_disc_db)
    {
        bta_hh_cb.p_disc_db = (tSDP_DISCOVERY_DB *) GKI_getbuf(p_bta_hh_cfg->sdp_db_size);

        if (bta_hh_cb.p_disc_db == NULL)
        {
            status = BTA_HH_ERR_NO_RES;
        }
        else
        {
            bta_hh_cb.p_cur = p_cb;
            /* do DI discovery first */
            if (SDP_DiDiscover(p_data->api_conn.bd_addr,
                                         bta_hh_cb.p_disc_db,
                                         p_bta_hh_cfg->sdp_db_size,
                                         bta_hh_di_sdp_cback) != SDP_SUCCESS)
            {
#if BTA_HH_DEBUG
                APPL_TRACE_DEBUG1 ("bta_hh_start_sdp:  SDP_DiDiscover failed: \
                    Status 0x%2X",status);
#endif
                status = BTA_HH_ERR_SDP;
                utl_freebuf((void **)&bta_hh_cb.p_disc_db);
            }
            else
Пример #22
0
/*******************************************************************************
**
** Function         GKI_run
**
** Description      This function runs a task
**
** Parameters:      p_task_id  - (input) pointer to task id
**
** Returns          void
**
** NOTE             This function is only needed for operating systems where
**                  starting a task is a 2-step process. Most OS's do it in
**                  one step, If your OS does it in one step, this function
**                  should be empty.
*********************************************************************************/
void GKI_run (void *p_task_id)
{
    GKI_TRACE_1("%s enter", __func__);
    struct timespec delay;
    int err = 0;
    volatile int * p_run_cond = &gki_cb.os.no_timer_suspend;

#ifndef GKI_NO_TICK_STOP
    /* register start stop function which disable timer loop in GKI_run() when no timers are
     * in any GKI/BTA/BTU this should save power when BTLD is idle! */
    GKI_timer_queue_register_callback( gki_system_tick_start_stop_cback );
    APPL_TRACE_DEBUG0( "GKI_run(): Start/Stop GKI_timer_update_registered!" );
#endif

#ifdef NO_GKI_RUN_RETURN
    GKI_TRACE_0("GKI_run == NO_GKI_RUN_RETURN");
    pthread_attr_t timer_attr;

    shutdown_timer = 0;

    pthread_attr_init(&timer_attr);
    pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
    if (pthread_create( &timer_thread_id,
              &timer_attr,
              timer_thread,
              NULL) != 0 )
    {
        GKI_TRACE_0("GKI_run: pthread_create failed to create timer_thread!");
        return GKI_FAILURE;
    }
#else
    GKI_TRACE_2("GKI_run, run_cond(%x)=%d ", p_run_cond, *p_run_cond);
    for (;GKI_TIMER_TICK_EXIT_COND != *p_run_cond;)
    {
        do
        {
            /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this formula works only for
             * 1-1000ms heart beat units! */
            delay.tv_sec = LINUX_SEC / 1000;
            delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);

            /* [u]sleep can't be used because it uses SIGALRM */
            do
            {
                err = nanosleep(&delay, &delay);
            } while (err < 0 && errno == EINTR);

            /* the unit should be alsways 1 (1 tick). only if you vary for some reason heart beat tick
             * e.g. power saving you may want to provide more ticks
             */
            GKI_timer_update( 1 );
            /* BT_TRACE_2( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "update: tv_sec: %d, tv_nsec: %d", delay.tv_sec, delay.tv_nsec ); */
        } while ( GKI_TIMER_TICK_RUN_COND == *p_run_cond);

        /* currently on reason to exit above loop is no_timer_suspend == GKI_TIMER_TICK_STOP_COND
         * block timer main thread till re-armed by  */
#ifdef GKI_TICK_TIMER_DEBUG
        BT_TRACE_0( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> SUSPENDED GKI_timer_update()" );
#endif
        if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) {
            GKI_TRACE_1("%s waiting timer mutex", __func__);
            pthread_mutex_lock( &gki_cb.os.gki_timer_mutex );
            pthread_cond_wait( &gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex );
            pthread_mutex_unlock( &gki_cb.os.gki_timer_mutex );
            GKI_TRACE_1("%s exited timer mutex", __func__);
        }
        /* potentially we need to adjust os gki_cb.com.OSTicks */

#ifdef GKI_TICK_TIMER_DEBUG
        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> RESTARTED GKI_timer_update(): run_cond: %d",
                    *p_run_cond );
#endif
    } /* for */
#endif
    GKI_TRACE_1("%s exit", __func__);
    return(0);
}
Пример #23
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_stop
 **
 ** Description      This function is called by AV when the audio streaming data
 **                  transfer is stopped.
 **
 **
 ** Returns          void
 **
 *******************************************************************************/
BTA_API extern void bta_av_co_audio_stop(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type)
{
    FUNC_TRACE();

    APPL_TRACE_DEBUG0("bta_av_co_audio_stop");
}
Пример #24
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_codec_supported
 **
 ** Description      Check if all opened connections are compatible with a codec
 **                  configuration and content protection
 **
 ** Returns          TRUE if all opened devices support this codec, FALSE otherwise
 **
 *******************************************************************************/
BOOLEAN bta_av_co_audio_codec_supported(tBTIF_STATUS *p_status)
{
    UINT8 index;
    UINT8 snk_index;
    tBTA_AV_CO_PEER *p_peer;
    tBTA_AV_CO_SINK *p_sink;
    UINT8 codec_cfg[AVDT_CODEC_SIZE];
    UINT8 num_protect = 0;
#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
    BOOLEAN cp_active;
#endif

    FUNC_TRACE();

    APPL_TRACE_DEBUG0("bta_av_co_audio_codec_supported");

    /* Check AV feeding is supported */
    *p_status = BTIF_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED;

    for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++)
    {
        p_peer = &bta_av_co_cb.peers[index];
        if (p_peer->opened)
        {
            if (bta_av_co_audio_peer_supports_codec(p_peer, &snk_index))
            {
                p_sink = &p_peer->snks[snk_index];

                /* Check that this sink is compatible with the CP */
                if (!bta_av_co_audio_sink_supports_cp(p_sink))
                {
                    APPL_TRACE_DEBUG2("bta_av_co_audio_codec_supported sink %d of peer %d doesn't support cp",
                            snk_index, index);
                    *p_status = BTIF_ERROR_SRV_AV_CP_NOT_SUPPORTED;
                    return FALSE;
                }

                /* Build the codec configuration for this sink */
                if (bta_av_co_audio_codec_build_config(p_sink->codec_caps, codec_cfg))
                {
#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
                    /* Check if this sink supports SCMS */
                    cp_active = bta_av_co_audio_sink_has_scmst(p_sink);
#endif
                    /* Check if this is a new configuration (new sink or new config) */
                    if ((p_sink != p_peer->p_snk) ||
                        (memcmp(codec_cfg, p_peer->codec_cfg, AVDT_CODEC_SIZE))
#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
                        || (p_peer->cp_active != cp_active)
#endif
                        )
                    {
                        /* Save the new configuration */
                        p_peer->p_snk = p_sink;
                        memcpy(p_peer->codec_cfg, codec_cfg, AVDT_CODEC_SIZE);
#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
                        p_peer->cp_active = cp_active;
                        if (p_peer->cp_active)
                        {
                            bta_av_co_cb.cp.active = TRUE;
                            num_protect = BTA_AV_CP_INFO_LEN;
                        }
                        else
                        {
                            bta_av_co_cb.cp.active = FALSE;
                        }
#endif
                        APPL_TRACE_DEBUG1("bta_av_co_audio_codec_supported call BTA_AvReconfig(x%x)", BTA_AV_CO_AUDIO_INDX_TO_HNDL(index));
                        BTA_AvReconfig(BTA_AV_CO_AUDIO_INDX_TO_HNDL(index), TRUE, p_sink->sep_info_idx,
                                p_peer->codec_cfg, num_protect, (UINT8 *)bta_av_co_cp_scmst);
                    }
                }
            }
            else
            {
                APPL_TRACE_DEBUG1("bta_av_co_audio_codec_supported index %d doesn't support codec", index);
                return FALSE;
            }
        }
    }

    *p_status = BTIF_SUCCESS;
    return TRUE;
}
Пример #25
0
/*******************************************************************************
 **
 ** Function         bta_av_co_audio_getconfig
 **
 ** Description      This callout function is executed by AV to retrieve the
 **                  desired codec and content protection configuration for the
 **                  audio stream.
 **
 **
 ** Returns          Stream codec and content protection configuration info.
 **
 *******************************************************************************/
BTA_API UINT8 bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
        UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid, UINT8 *p_num_protect,
        UINT8 *p_protect_info)

{
    UINT8 result = A2D_FAIL;
    BOOLEAN supported;
    tBTA_AV_CO_PEER *p_peer;
    tBTA_AV_CO_SINK *p_sink;
    UINT8 codec_cfg[AVDT_CODEC_SIZE];
    UINT8 index;

    FUNC_TRACE();

    APPL_TRACE_DEBUG3("bta_av_co_audio_getconfig handle:0x%x codec_type:%d seid:%d", hndl, codec_type, seid);
    APPL_TRACE_DEBUG4("num_protect:0x%02x protect_info:0x%02x%02x%02x",
        *p_num_protect, p_protect_info[0], p_protect_info[1], p_protect_info[2]);

    /* Retrieve the peer info */
    p_peer = bta_av_co_get_peer(hndl);
    if (p_peer == NULL)
    {
        APPL_TRACE_ERROR0("bta_av_co_audio_getconfig could not find peer entry");
        return A2D_FAIL;
    }

    APPL_TRACE_DEBUG4("bta_av_co_audio_getconfig peer(o=%d,n_snks=%d,n_rx_snks=%d,n_sup_snks=%d)",
            p_peer->opened, p_peer->num_snks, p_peer->num_rx_snks, p_peer->num_sup_snks);

    /* Increment the number of received sinks capabilities */
    p_peer->num_rx_snks++;

    /* Check if this is a supported configuration */
    supported = FALSE;
    switch (codec_type)
    {
    case BTA_AV_CODEC_SBC:
        supported = TRUE;
        break;

    default:
        break;
    }

    if (supported)
    {
        /* If there is room for a new one */
        if (p_peer->num_sup_snks < BTA_AV_CO_NUM_ELEMENTS(p_peer->snks))
        {
            p_sink = &p_peer->snks[p_peer->num_sup_snks++];

            APPL_TRACE_DEBUG6("bta_av_co_audio_getconfig saved caps[%x:%x:%x:%x:%x:%x]",
                    p_codec_info[1], p_codec_info[2], p_codec_info[3],
                    p_codec_info[4], p_codec_info[5], p_codec_info[6]);

            memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE);
            p_sink->codec_type = codec_type;
            p_sink->sep_info_idx = *p_sep_info_idx;
            p_sink->seid = seid;
            p_sink->num_protect = *p_num_protect;
            memcpy(p_sink->protect_info, p_protect_info, BTA_AV_CP_INFO_LEN);
        }
        else
        {
            APPL_TRACE_ERROR0("bta_av_co_audio_getconfig no more room for SNK info");
        }
    }

    /* If last SNK get capabilities or all supported codec capa retrieved */
    if ((p_peer->num_rx_snks == p_peer->num_snks) ||
        (p_peer->num_sup_snks == BTA_AV_CO_NUM_ELEMENTS(p_peer->snks)))
    {
        APPL_TRACE_DEBUG0("bta_av_co_audio_getconfig last sink reached");

        /* Protect access to bta_av_co_cb.codec_cfg */
        GKI_disable();

        /* Find a sink that matches the codec config */
        if (bta_av_co_audio_peer_supports_codec(p_peer, &index))
        {
            /* stop fetching caps once we retrieved a supported codec */
            if (p_peer->acp)
            {
                *p_sep_info_idx = p_peer->num_seps;
                APPL_TRACE_EVENT0("no need to fetch more SEPs");
            }

            p_sink = &p_peer->snks[index];

            /* Build the codec configuration for this sink */
            if (bta_av_co_audio_codec_build_config(p_sink->codec_caps, codec_cfg))
            {
                APPL_TRACE_DEBUG6("bta_av_co_audio_getconfig reconfig p_codec_info[%x:%x:%x:%x:%x:%x]",
                        codec_cfg[1], codec_cfg[2], codec_cfg[3],
                        codec_cfg[4], codec_cfg[5], codec_cfg[6]);

                /* Save the new configuration */
                p_peer->p_snk = p_sink;
                memcpy(p_peer->codec_cfg, codec_cfg, AVDT_CODEC_SIZE);

                /* By default, no content protection */
                *p_num_protect = 0;

#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
                /* Check if this sink supports SCMS */
                if (bta_av_co_audio_sink_has_scmst(p_sink))
                {
                    p_peer->cp_active = TRUE;
                    bta_av_co_cb.cp.active = TRUE;
                    *p_num_protect = BTA_AV_CP_INFO_LEN;
                    memcpy(p_protect_info, bta_av_co_cp_scmst, BTA_AV_CP_INFO_LEN);
                }
                else
                {
                    p_peer->cp_active = FALSE;
                    bta_av_co_cb.cp.active = FALSE;
                }
#endif

                /* If acceptor -> reconfig otherwise reply for configuration */
                if (p_peer->acp)
                {
                    if (p_peer->recfg_needed)
                    {
                        APPL_TRACE_DEBUG1("bta_av_co_audio_getconfig call BTA_AvReconfig(x%x)", hndl);
                        BTA_AvReconfig(hndl, TRUE, p_sink->sep_info_idx, p_peer->codec_cfg, *p_num_protect, (UINT8 *)bta_av_co_cp_scmst);
                    }
                }
                else
                {
                    *p_sep_info_idx = p_sink->sep_info_idx;
                    memcpy(p_codec_info, p_peer->codec_cfg, AVDT_CODEC_SIZE);
                }
                result =  A2D_SUCCESS;
            }
        }
        /* Protect access to bta_av_co_cb.codec_cfg */
        GKI_enable();
    }
    return result;
}