BtStatus disconnect_profile_int(bt_addr_struct *bd_addr, PROFILE_enum id) { int ret = BT_STATUS_FAILED; ALOGI("%s addr:[0x%lX:0x%X:0x%X], profile[%d]!\n", __FUNCTION__, bd_addr->lap, bd_addr->uap, bd_addr->nap, id); notifyProfileStateChanged(bd_addr, id, PROFILE_STATE_DISCONNECTING); switch(id) { case PROFILE_A2DP: ret = btif_av_disconnect(bd_addr); break; case PROFILE_HFP: ret = btif_hf_disconnect(bd_addr); break; default: ALOGW("ignore request!\n"); return BT_STATUS_FAILED; } setBusy(bd_addr, 1); return ret; }
/* This function is used for handling message send from internal */ void btmtk_a2dp_ext_msg_handler(void *pContext, ilm_struct *ilm) { U8 iResult = A2DP_STATUS_NO_CHANGE; bt_addr_struct addr; iResult = btmtk_a2dp_handle_message(ilm); bt_ext_log("a2dp ext hdl result: %d", iResult); btmtk_a2dp_get_bdaddr(&addr); btmtk_util_convert_bdaddr2array(&(btif_av_cb.peer_bda), &addr); switch(iResult) { case A2DP_STATUS_CHANGE_DISCONNECTED: { //Notify Profile Manager A2DP connection status been changed notifyProfileStateChanged(&addr,PROFILE_A2DP,PROFILE_STATE_DISCONNECTED); //Callback status change to framework HAL_CBACK(bt_av_callbacks, connection_state_cb, BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda)); break; } case A2DP_STATUS_CHANGE_CONNECTING: { HAL_CBACK(bt_av_callbacks, connection_state_cb, BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda)); break; } case A2DP_STATUS_CHANGE_CONNECTED: { notifyProfileStateChanged(&addr,PROFILE_A2DP,PROFILE_STATE_CONNECTED); HAL_CBACK(bt_av_callbacks, connection_state_cb, BTAV_CONNECTION_STATE_CONNECTED, &(btif_av_cb.peer_bda)); break; } case A2DP_STATUS_CHANGE_PLAYING: { HAL_CBACK(bt_av_callbacks, audio_state_cb, BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda)); break; } #ifdef __BTMTK__ #ifdef MTK_BT_FM_OVER_BT_VIA_CONTROLLER case A2DP_STATUS_FM_PLAYING_FAILED: { HAL_CBACK(bt_av_callbacks, audio_state_cb, BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda)); break; } #endif #endif } }
void notifyProfileStateChanged(bt_addr_struct *bd_addr, PROFILE_enum id, ProfileStatus state) { dev_op *devOp = getDeviceOpList(bd_addr); int old_state = getProfileState(bd_addr, id); int new_state = state; profile_op_queue_t *opCur = NULL; profile_op_queue_t *opNext = NULL; if(devOp == NULL) { return; } ALOGI("%s addr:[0x%lX:0x%X:0x%X], profile[%d], old[%d] ==> new[%d]!\n", __FUNCTION__, bd_addr->lap, bd_addr->uap, bd_addr->nap, id, old_state, new_state); setProfileState(bd_addr, id, new_state); if(isCurrentDevice(bd_addr)) { int state = PROFILE_STATE_DISCONNECTED; if(new_state == PROFILE_STATE_CONNECTED || new_state == PROFILE_STATE_DISCONNECTED) { setBusy(bd_addr, 0); if(!isEmpty((btmtk_list_header_struct **)&devOp->op_list)) { opCur = (profile_op_queue_t *)getHeader((btmtk_list_header_struct **)&devOp->op_list); if(opCur->node.op == PROFILE_OP_CONNECT) { state = getProfileState(bd_addr, opCur->node.profile_id); if(state == PROFILE_STATE_DISCONNECTED) connect_profile_int(bd_addr, opCur->node.profile_id); } else if(opCur->node.op == PROFILE_OP_DISCONNECT) { state = getProfileState(bd_addr, opCur->node.profile_id); if(state == PROFILE_STATE_CONNECTED) disconnect_profile_int(bd_addr, opCur->node.profile_id); else if(state == PROFILE_STATE_DISCONNECTED) { PROFILE_enum profile_id = opCur->node.profile_id; ProfileOpType profile_op = opCur->node.op; removeOp(bd_addr, profile_id, profile_op); notifyProfileStateChanged(bd_addr, profile_id, PROFILE_STATE_DISCONNECTED); return; } } removeOp(bd_addr, opCur->node.profile_id, opCur->node.op); } } } else { removeAll((btmtk_list_header_struct **)&devOp->op_list); if(new_state == PROFILE_STATE_CONNECTED || new_state == PROFILE_STATE_DISCONNECTED) { setBusy(bd_addr, 0); } } ProfileStateChangedCB(bd_addr, id, new_state); }