/** * @brief Hangup active call. * * @param av Handler. * @return int * @retval 0 Success. * @retval ToxAvError On error. */ int toxav_hangup ( ToxAv *av, int32_t call_index ) { if ( cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) { return ErrorNoCall; } if ( av->msi_session->calls[call_index]->state != call_active ) { return ErrorInvalidState; } return msi_hangup(av->msi_session, call_index); }
/** * @brief Hangup active call. * * @param av Handler. * @return int * @retval 0 Success. * @retval ToxAvError On error. */ int toxav_hangup ( ToxAv *av ) { if ( !av->msi_session->call ) { return ErrorNoCall; } if ( av->msi_session->call->state != call_active ) { return ErrorInvalidState; } return msi_hangup(av->msi_session); }
bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error) { pthread_mutex_lock(av->mutex); TOXAV_ERR_CALL_CONTROL rc = TOXAV_ERR_CALL_CONTROL_OK; if (m_friend_exists(av->m, friend_number) == 0) { rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND; goto END; } ToxAVCall *call = call_get(av, friend_number); if (call == NULL || (!call->active && control != TOXAV_CALL_CONTROL_CANCEL)) { rc = TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_IN_CALL; goto END; } switch (control) { case TOXAV_CALL_CONTROL_RESUME: { /* Only act if paused and had media transfer active before */ if (call->msi_call->self_capabilities == 0 && call->previous_self_capabilities) { if (msi_change_capabilities(call->msi_call, call->previous_self_capabilities) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; goto END; } rtp_allow_receiving(call->audio.first); rtp_allow_receiving(call->video.first); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; goto END; } } break; case TOXAV_CALL_CONTROL_PAUSE: { /* Only act if not already paused */ if (call->msi_call->self_capabilities) { call->previous_self_capabilities = call->msi_call->self_capabilities; if (msi_change_capabilities(call->msi_call, 0) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; goto END; } rtp_stop_receiving(call->audio.first); rtp_stop_receiving(call->video.first); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; goto END; } } break; case TOXAV_CALL_CONTROL_CANCEL: { /* Hang up */ pthread_mutex_lock(call->mutex); if (msi_hangup(call->msi_call) != 0) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; pthread_mutex_unlock(call->mutex); goto END; } call->msi_call = NULL; pthread_mutex_unlock(call->mutex); /* No mather the case, terminate the call */ call_kill_transmission(call); call_remove(call); } break; case TOXAV_CALL_CONTROL_MUTE_AUDIO: { if (call->msi_call->self_capabilities & msi_CapRAudio) { if (msi_change_capabilities(call->msi_call, call-> msi_call->self_capabilities ^ msi_CapRAudio) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; goto END; } rtp_stop_receiving(call->audio.first); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; goto END; } } break; case TOXAV_CALL_CONTROL_UNMUTE_AUDIO: { if (call->msi_call->self_capabilities ^ msi_CapRAudio) { if (msi_change_capabilities(call->msi_call, call-> msi_call->self_capabilities | msi_CapRAudio) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; goto END; } rtp_allow_receiving(call->audio.first); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; goto END; } } break; case TOXAV_CALL_CONTROL_HIDE_VIDEO: { if (call->msi_call->self_capabilities & msi_CapRVideo) { if (msi_change_capabilities(call->msi_call, call-> msi_call->self_capabilities ^ msi_CapRVideo) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; goto END; } rtp_stop_receiving(call->video.first); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; goto END; } } break; case TOXAV_CALL_CONTROL_SHOW_VIDEO: { if (call->msi_call->self_capabilities ^ msi_CapRVideo) { if (msi_change_capabilities(call->msi_call, call-> msi_call->self_capabilities | msi_CapRVideo) == -1) { rc = TOXAV_ERR_CALL_CONTROL_SYNC; goto END; } rtp_allow_receiving(call->audio.first); } else { rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; goto END; } } break; } END: pthread_mutex_unlock(av->mutex); if (error) *error = rc; return rc == TOXAV_ERR_CALL_CONTROL_OK; }