static void cleanup_rfc_slot(rfc_slot_t* rs) { APPL_TRACE_DEBUG4("cleanup slot:%d, fd:%d, scn:%d, sdp_handle:0x%x", rs->id, rs->fd, rs->scn, rs->sdp_handle); if(rs->fd != -1) { shutdown(rs->fd, 2); close(rs->fd); rs->fd = -1; } if(rs->app_fd != -1) { close(rs->app_fd); rs->app_fd = -1; } if(rs->sdp_handle > 0) { del_rfc_sdp_rec(rs->sdp_handle); rs->sdp_handle = 0; } if(rs->rfc_handle && !rs->f.closing && !rs->f.server) { APPL_TRACE_DEBUG1("closing rfcomm connection, rfc_handle:0x%x", rs->rfc_handle); BTA_JvRfcommClose(rs->rfc_handle, (void*)rs->id); rs->rfc_handle = 0; } free_rfc_slot_scn(rs); free_gki_que(&rs->incoming_que); rs->rfc_port_handle = 0; //cleanup the flag memset(&rs->f, 0, sizeof(rs->f)); rs->id = 0; }
static void bta_hf_client_handle_cnum( char *numstr, UINT16 type, UINT16 service) { APPL_TRACE_DEBUG4("%s number: %s type: %u service: %u", __FUNCTION__, numstr, type, service); /* TODO: should number be modified according to type? */ bta_hf_client_cnum(numstr, service); }
static void on_rfc_close(tBTA_JV_RFCOMM_CLOSE * p_close, uint32_t id) { lock_slot(&slot_lock); rfc_slot_t* rs = find_rfc_slot_by_id(id); if(rs) { APPL_TRACE_DEBUG4("on_rfc_close, slot id:%d, fd:%d, rfc scn:%d, server:%d", rs->id, rs->fd, rs->scn, rs->f.server); free_rfc_slot_scn(rs); // rfc_handle already closed when receiving rfcomm close event from stack. rs->f.connected = FALSE; cleanup_rfc_slot(rs); } unlock_slot(&slot_lock); }
/******************************************************************************* ** ** Function bta_gattc_sm_execute ** ** Description State machine event handling function for GATTC ** ** ** Returns void ** *******************************************************************************/ void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data) { tBTA_GATTC_ST_TBL state_table; UINT8 action; int i; #if BTA_GATT_DEBUG == TRUE tBTA_GATTC_STATE in_state = p_clcb->state; UINT16 in_event = event; APPL_TRACE_DEBUG4("bta_gattc_sm_execute: State 0x%02x [%s], Event 0x%x[%s]", in_state, gattc_state_code(in_state), in_event, gattc_evt_code(in_event)); #endif /* look up the state table for the current state */ state_table = bta_gattc_st_tbl[p_clcb->state]; event &= 0x00FF; /* set next state */ p_clcb->state = state_table[event][BTA_GATTC_NEXT_STATE]; /* execute action functions */ for (i = 0; i < BTA_GATTC_ACTIONS; i++) { if ((action = state_table[event][i]) != BTA_GATTC_IGNORE) { (*bta_gattc_action[action])(p_clcb, p_data); } else { break; } } #if BTA_GATT_DEBUG == TRUE if (in_state != p_clcb->state) { APPL_TRACE_DEBUG3("GATTC State Change: [%s] -> [%s] after Event [%s]", gattc_state_code(in_state), gattc_state_code(p_clcb->state), gattc_evt_code(in_event)); } #endif }
static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN *p_open, uint32_t id) { lock_slot(&slot_lock); rfc_slot_t* rs = find_rfc_slot_by_id(id); if(rs && p_open->status == BTA_JV_SUCCESS) { rs->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_open->handle); bd_copy(rs->addr.address, p_open->rem_bda, 0); //notify app rfc is connected APPL_TRACE_DEBUG4("call send_app_connect_signal, slot id:%d, fd:%d, rfc scn:%d, server:%d", rs->id, rs->fd, rs->scn, rs->f.server); if(send_app_connect_signal(rs->fd, &rs->addr, rs->scn, 0, -1)) { //start monitoring the socketpair to get call back when app writing data APPL_TRACE_DEBUG3("on_rfc_connect_ind, connect signal sent, slot id:%d, rfc scn:%d, server:%d", rs->id, rs->scn, rs->f.server); rs->f.connected = TRUE; } else APPL_TRACE_ERROR0("send_app_connect_signal failed"); } else if(rs) cleanup_rfc_slot(rs); unlock_slot(&slot_lock); }
/******************************************************************************* ** ** 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); } }
/******************************************************************************* ** ** 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; }