/******************************************************************************* ** ** Function bta_dm_search_sm_execute ** ** Description State machine event handling function for DM ** ** ** Returns void ** *******************************************************************************/ BOOLEAN bta_dm_search_sm_execute(BT_HDR *p_msg) { tBTA_DM_ST_TBL state_table; UINT8 action; int i; APPL_TRACE_EVENT2("bta_dm_search_sm_execute state:%d, event:0x%x", bta_dm_search_cb.state, p_msg->event); /* look up the state table for the current state */ state_table = bta_dm_search_st_tbl[bta_dm_search_cb.state]; bta_dm_search_cb.state = state_table[p_msg->event & 0x00ff][BTA_DM_SEARCH_NEXT_STATE]; /* execute action functions */ for (i = 0; i < BTA_DM_SEARCH_ACTIONS; i++) { if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_DM_SEARCH_IGNORE) { (*bta_dm_search_action[action])( (tBTA_DM_MSG*) p_msg); } else { break; } } return TRUE; }
/******************************************************************************* ** ** Function bta_av_sm_execute ** ** Description State machine event handling function for AV ** ** ** Returns void ** *******************************************************************************/ void bta_av_sm_execute(tBTA_AV_CB *p_cb, UINT16 event, tBTA_AV_DATA *p_data) { tBTA_AV_ST_TBL state_table; UINT8 action; #if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE) APPL_TRACE_EVENT4("AV event=0x%x(%s) state=%d(%s)", event, bta_av_evt_code(event), p_cb->state, bta_av_st_code(p_cb->state)); #else APPL_TRACE_EVENT2("AV event=0x%x state=%d", event, p_cb->state); #endif /* look up the state table for the current state */ state_table = bta_av_st_tbl[p_cb->state]; event &= 0x00FF; /* set next state */ p_cb->state = state_table[event][BTA_AV_NEXT_STATE]; APPL_TRACE_EVENT1("next state=%d", p_cb->state); /* execute action functions */ if ((action = state_table[event][BTA_AV_ACTION_COL]) != BTA_AV_IGNORE) { (*bta_av_action[action])(p_cb, p_data); } }
/******************************************************************************* ** ** Function bta_av_co_audio_codec_build_config ** ** Description Build the codec configuration ** ** Returns TRUE if the codec was built successfully, FALSE otherwise ** *******************************************************************************/ static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UINT8 *p_codec_cfg) { FUNC_TRACE(); memset(p_codec_cfg, 0, AVDT_CODEC_SIZE); switch (bta_av_co_cb.codec_cfg.id) { case BTIF_AV_CODEC_SBC: /* only copy the relevant portions for this codec to avoid issues when comparing codec configs covering larger codec sets than SBC (7 bytes) */ memcpy(p_codec_cfg, bta_av_co_cb.codec_cfg.info, BTA_AV_CO_SBC_MAX_BITPOOL_OFF+1); /* Update the bit pool boundaries with the codec capabilities */ p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF]; p_codec_cfg[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] = p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]; APPL_TRACE_EVENT2("bta_av_co_audio_codec_build_config : bitpool min %d, max %d", p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]); break; default: APPL_TRACE_ERROR1("bta_av_co_audio_codec_build_config: unsupported codec id %d", bta_av_co_cb.codec_cfg.id); return FALSE; break; } return TRUE; }
/******************************************************************************* ** ** Function bta_av_co_audio_get_sbc_config ** ** Description Retrieves the SBC codec configuration. If the codec in use ** is not SBC, return the default SBC codec configuration. ** ** Returns TRUE if codec is SBC, FALSE otherwise ** *******************************************************************************/ BOOLEAN bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, UINT16 *p_minmtu) { BOOLEAN result = FALSE; UINT8 index, jndex; tBTA_AV_CO_PEER *p_peer; tBTA_AV_CO_SINK *p_sink; APPL_TRACE_EVENT1("bta_av_co_cb.codec_cfg.id : codec 0x%x", bta_av_co_cb.codec_cfg.id); /* Minimum MTU is by default very large */ *p_minmtu = 0xFFFF; GKI_disable(); if (bta_av_co_cb.codec_cfg.id == BTIF_AV_CODEC_SBC) { if (A2D_ParsSbcInfo(p_sbc_config, bta_av_co_cb.codec_cfg.info, FALSE) == A2D_SUCCESS) { 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 (p_peer->mtu < *p_minmtu) { *p_minmtu = p_peer->mtu; } for (jndex = 0; jndex < p_peer->num_sup_snks; jndex++) { p_sink = &p_peer->snks[jndex]; if (p_sink->codec_type == A2D_MEDIA_CT_SBC) { /* Update the bitpool boundaries of the current config */ p_sbc_config->min_bitpool = BTA_AV_CO_MAX(p_sink->codec_caps[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], p_sbc_config->min_bitpool); p_sbc_config->max_bitpool = BTA_AV_CO_MIN(p_sink->codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF], p_sbc_config->max_bitpool); APPL_TRACE_EVENT2("bta_av_co_audio_get_sbc_config : sink bitpool min %d, max %d", p_sbc_config->min_bitpool, p_sbc_config->max_bitpool); break; } } } } result = TRUE; } } if (!result) { /* Not SBC, still return the default values */ *p_sbc_config = btif_av_sbc_default_config; } GKI_enable(); return result; }
/******************************************************************************* ** ** Function bta_hh_di_sdp_cback ** ** Description SDP DI callback function. ** ** Returns void ** *******************************************************************************/ static void bta_hh_di_sdp_cback(UINT16 result) { tBTA_HH_DEV_CB *p_cb = bta_hh_cb.p_cur; tBTA_HH_STATUS status = BTA_HH_ERR_SDP; tSDP_DI_GET_RECORD di_rec; tHID_STATUS ret; #if BTA_HH_DEBUG APPL_TRACE_EVENT2("bta_hh_di_sdp_cback: p_cb: %d result 0x%02x", p_cb, result); #endif /* if DI record does not exist on remote device, vendor_id in tBTA_HH_DEV_DSCP_INFO will be * set to 0xffff and we will allow the connection to go through. Spec mandates that DI * record be set, but many HID devices do not set this. So for IOP purposes, we allow the * connection to go through and update the DI record to invalid DI entry.*/ if (((result == SDP_SUCCESS) || (result == SDP_NO_RECS_MATCH)) && (p_cb != NULL)) { if(result == SDP_SUCCESS && SDP_GetNumDiRecords(bta_hh_cb.p_disc_db) != 0) { /* always update information with primary DI record */ if (SDP_GetDiRecord(1, &di_rec, bta_hh_cb.p_disc_db) == SDP_SUCCESS) { bta_hh_update_di_info(p_cb, di_rec.rec.vendor, di_rec.rec.product, di_rec.rec.version, 0); } } else /* no DI recrod available */ { bta_hh_update_di_info(p_cb, BTA_HH_VENDOR_ID_INVALID, 0, 0, 0); } if ((ret = HID_HostGetSDPRecord(p_cb->addr, bta_hh_cb.p_disc_db, p_bta_hh_cfg->sdp_db_size, bta_hh_sdp_cback)) == HID_SUCCESS) { status = BTA_HH_OK; } else { #if BTA_HH_DEBUG APPL_TRACE_DEBUG1 ("bta_hh_di_sdp_cback: HID_HostGetSDPRecord failed: Status 0x%2x", ret); #endif } } if (status != BTA_HH_OK) { utl_freebuf((void **)&bta_hh_cb.p_disc_db); /* send SDP_CMPL_EVT into state machine */ bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, (tBTA_HH_DATA *)&status); } return; }
/****************************************************************************** ** ** Function bte_main_enable_lpm ** ** Description BTE MAIN API - Enable/Disable low power mode operation ** ** Returns None ** ******************************************************************************/ void bte_main_enable_lpm(BOOLEAN enable) { int result = -1; if (bt_hc_if) result = bt_hc_if->lpm( \ (enable == TRUE) ? BT_HC_LPM_ENABLE : BT_HC_LPM_DISABLE \ ); APPL_TRACE_EVENT2("HC lib lpm enable=%d return %d", enable, result); }
/******************************************************************************* ** ** Function bta_av_co_audio_setconfig ** ** Description This callout function is executed by AV to set the codec and ** content protection configuration of the audio stream. ** ** ** Returns void ** *******************************************************************************/ BTA_API void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr, UINT8 num_protect, UINT8 *p_protect_info) { tBTA_AV_CO_PEER *p_peer; UINT8 status = A2D_SUCCESS; UINT8 category = A2D_SUCCESS; BOOLEAN recfg_needed = FALSE; FUNC_TRACE(); APPL_TRACE_DEBUG6("bta_av_co_audio_setconfig p_codec_info[%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]); APPL_TRACE_DEBUG4("num_protect:0x%02x protect_info:0x%02x%02x%02x", 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_setconfig could not find peer entry"); /* Call call-in rejecting the configuration */ bta_av_ci_setconfig(hndl, A2D_BUSY, AVDT_ASC_CODEC, 0, NULL, FALSE); return; } /* Sanity check: should not be opened at this point */ if (p_peer->opened) { APPL_TRACE_ERROR0("bta_av_co_audio_setconfig peer already in use"); } #if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE) if (num_protect != 0) { /* If CP is supported */ if ((num_protect != 1) || (bta_av_co_cp_is_scmst(p_protect_info) == FALSE)) { APPL_TRACE_ERROR0("bta_av_co_audio_setconfig wrong CP configuration"); status = A2D_BAD_CP_TYPE; category = AVDT_ASC_PROTECT; } } #else /* Do not support content protection for the time being */ if (num_protect != 0) { APPL_TRACE_ERROR0("bta_av_co_audio_setconfig wrong CP configuration"); status = A2D_BAD_CP_TYPE; category = AVDT_ASC_PROTECT; } #endif if (status == A2D_SUCCESS) { /* Check if codec configuration is supported */ if (bta_av_co_audio_media_supports_config(codec_type, p_codec_info)) { /* Protect access to bta_av_co_cb.codec_cfg */ GKI_disable(); /* Check if the configuration matches the current codec config */ switch (bta_av_co_cb.codec_cfg.id) { case BTIF_AV_CODEC_SBC: if ((codec_type != BTA_AV_CODEC_SBC) || memcmp(p_codec_info, bta_av_co_cb.codec_cfg.info, 5)) { recfg_needed = TRUE; } else if ((num_protect == 1) && (!bta_av_co_cb.cp.active)) { recfg_needed = TRUE; } /* if remote side requests a restricted notify sinks preferred bitpool range as all other params are already checked for validify */ APPL_TRACE_EVENT2("remote peer setconfig bitpool range [%d:%d]", p_codec_info[BTA_AV_CO_SBC_MIN_BITPOOL_OFF], p_codec_info[BTA_AV_CO_SBC_MAX_BITPOOL_OFF] ); bta_av_co_cb.codec_cfg_setconfig.id = BTIF_AV_CODEC_SBC; memcpy(bta_av_co_cb.codec_cfg_setconfig.info, p_codec_info, AVDT_CODEC_SIZE); break; default: APPL_TRACE_ERROR1("bta_av_co_audio_setconfig unsupported cid %d", bta_av_co_cb.codec_cfg.id); recfg_needed = TRUE; break; } /* Protect access to bta_av_co_cb.codec_cfg */ GKI_enable(); } else { category = AVDT_ASC_CODEC; status = A2D_WRONG_CODEC; } } if (status != A2D_SUCCESS) { APPL_TRACE_DEBUG2("bta_av_co_audio_setconfig reject s=%d c=%d", status, category); /* Call call-in rejecting the configuration */ bta_av_ci_setconfig(hndl, status, category, 0, NULL, FALSE); } else { /* Mark that this is an acceptor peer */ p_peer->acp = TRUE; p_peer->recfg_needed = recfg_needed; APPL_TRACE_DEBUG1("bta_av_co_audio_setconfig accept reconf=%d", recfg_needed); /* Call call-in accepting the configuration */ bta_av_ci_setconfig(hndl, A2D_SUCCESS, A2D_SUCCESS, 0, NULL, recfg_needed); } }