📄 soa.c
字号:
/** @ERROR EALREADY An operation is already in progress */ if (ss->ss_in_progress) return su_seterrno(EALREADY), -1; /** @ERROR EPROTO We have received offer, now we should send answer */ if (ss->ss_offer_recv && !ss->ss_answer_sent) return su_seterrno(EPROTO), -1; /** @ERROR EPROTO We have received SDP, but it has not been processed */ if (soa_has_received_sdp(ss)) return su_seterrno(EPROTO), -1; /** @ERROR EPROTO We have sent an offer, but have received no answer */ if (ss->ss_offer_sent && !ss->ss_answer_recv) return su_seterrno(EPROTO), -1; /** @ERROR EPROTO We have received offer. */ if (ss->ss_unprocessed_remote) return su_seterrno(EPROTO), -1; /* We should avoid actual operation unless always is true */ (void)always; /* We always regenerate offer */ return ss->ss_actions->soa_generate_offer(ss, completed); /** @sa soa_init_offer_answer(), soa_set_user_sdp(), soa_get_local_sdp(), * soa_set_remote_sdp(), soa_process_answer(), soa_process_reject(), * soa_generate_answer(), soa_set_params(), soa_get_params(), * soa_get_paramlist(), SOATAG_USER_SDP(), SOATAG_USER_SDP_STR(), * SOATAG_REMOTE_SDP(), SOATAG_REMOTE_SDP_STR(). */}int soa_base_generate_offer(soa_session_t *ss, soa_callback_f *completed){ sdp_session_t const *sdp = ss->ss_local->ssd_sdp; (void)completed; if (!sdp) return -1; soa_set_activity(ss, sdp->sdp_media, soa_activity_local); /* Wanted activity */ ss->ss_offer_sent = 1; ss->ss_answer_recv = 0; return 0;}/**Process offer, generate answer. * * When generating the offer the soa session combines remote offer with * <i>user SDP</i>. There are various other parameters directing the * generation of answer, set by soa_set_params(). * * Before calling soa_generate_answer() the remote SDP offer should have * been stored into the soa session @a ss with soa_set_remote_sdp() or with * the soa_set_params() tags SOATAG_REMOTE_SDP() or SOATAG_REMOTE_SDP_STR(). * * Also, the <i>user SDP</i> should have been stored into @a ss with * soa_set_user_sdp() or with the soa_set_params() tags SOATAG_USER_SDP() or * SOATAG_USER_SDP_STR(). * * The resulting SDP is also known as <i>local SDP</i>. It is available with * soa_get_local_sdp() or with the soa_get_params() or soa_get_paramlist() * tags SOATAG_LOCAL_SDP() and SOATAG_LOCAL_SDP_STR(). * * @param ss pointer to session object * @param completed pointer to callback function which is invoked when * operation is completed (currently not in use) * * @retval 1 when operation is successful * @retval 0 when operation was not needed * @retval -1 upon an error * * @ERRORS */int soa_generate_answer(soa_session_t *ss, soa_callback_f *completed){ SU_DEBUG_9(("soa_generate_answer(%s::%p) called\n", ss ? ss->ss_actions->soa_name : "", (void *)ss)); /** @ERROR EFAULT Bad address as @a ss. */ if (ss == NULL) return su_seterrno(EFAULT), -1; /** @ERROR EALREADY An operation is already in progress. */ if (ss->ss_in_progress) return su_seterrno(EALREADY), -1; /** @ERROR EPROTO We have sent an offer, but have received no answer. */ if (ss->ss_offer_sent && !ss->ss_answer_recv) return su_seterrno(EPROTO), -1; /** @ERROR EPROTO We have not received offer. */ if (!ss->ss_unprocessed_remote) return su_seterrno(EPROTO), -1; return ss->ss_actions->soa_generate_answer(ss, completed); /**@sa soa_init_offer_answer(), soa_set_user_sdp(), soa_set_remote_sdp(), * soa_get_local_sdp(), soa_process_reject(), soa_generate_offer(), * soa_set_params(), soa_get_params(), soa_get_paramlist(), * SOATAG_USER_SDP(), SOATAG_USER_SDP_STR(), SOATAG_REMOTE_SDP(), * SOATAG_REMOTE_SDP_STR(). */}/** Base method for processing offer, generating answer. */int soa_base_generate_answer(soa_session_t *ss, soa_callback_f *completed){ sdp_session_t const *l_sdp = ss->ss_local->ssd_sdp; sdp_session_t const *r_sdp = ss->ss_remote->ssd_sdp; sdp_session_t *rsession; (void)completed; if (!l_sdp || !r_sdp) return -1; rsession = sdp_session_dup(ss->ss_home, r_sdp); if (!rsession) return -1; if (ss->ss_rsession) su_free(ss->ss_home, ss->ss_rsession); ss->ss_rsession = rsession; soa_set_activity(ss, l_sdp->sdp_media, soa_activity_session); ss->ss_offer_recv = 1; ss->ss_answer_sent = 1; ss->ss_complete = 1; ss->ss_unprocessed_remote = 0; return 0;}/** Complete offer-answer after receiving answer. * * The SDP offer/answer negotiation is completed after receiving answer from * remote end. The answer is combined with the offer, and the application * should activate the media and codecs according to the negotiation result, * available as <i>local SDP</i>. * * @param ss pointer to session object * @param completed pointer to callback function which is invoked when * operation is completed (currently not in use) * * @retval 1 when operation is successful * @retval 0 when operation was not needed * @retval -1 upon an error * * @ERRORS */int soa_process_answer(soa_session_t *ss, soa_callback_f *completed){ SU_DEBUG_9(("soa_process_answer(%s::%p) called\n", ss ? ss->ss_actions->soa_name : "", (void *)ss)); /** @ERROR EFAULT Bad address as @a ss. */ if (ss == NULL) return su_seterrno(EFAULT), -1; /** @ERROR EALREADY An operation is already in progress. */ if (ss->ss_in_progress) return su_seterrno(EALREADY), -1; /** @ERROR EPROTO We have not sent an offer or already have received answer. */ if (!ss->ss_offer_sent || ss->ss_answer_recv) return su_seterrno(EPROTO), -1; /** @ERROR EPROTO We have not received answer. */ if (!ss->ss_unprocessed_remote) return su_seterrno(EPROTO), -1; /**@sa soa_init_offer_answer(), soa_set_user_sdp(), soa_set_remote_sdp(), * soa_get_local_sdp(), soa_generate_offer(), soa_generate_answer(), * soa_process_reject(), soa_set_params(), soa_get_params(), * soa_get_paramlist(), SOATAG_USER_SDP(), SOATAG_USER_SDP_STR(), * SOATAG_REMOTE_SDP(), SOATAG_REMOTE_SDP_STR(). */ return ss->ss_actions->soa_process_answer(ss, completed);}/** Base method for completing offer-answer after receiving answer. */int soa_base_process_answer(soa_session_t *ss, soa_callback_f *completed){ sdp_session_t const *l_sdp = ss->ss_local->ssd_sdp; sdp_session_t const *r_sdp = ss->ss_remote->ssd_sdp; sdp_session_t *rsession; (void)completed; if (!l_sdp || !r_sdp) return -1; rsession = sdp_session_dup(ss->ss_home, r_sdp); if (!rsession) return -1; if (ss->ss_rsession) su_free(ss->ss_home, ss->ss_rsession); ss->ss_rsession = rsession; soa_set_activity(ss, l_sdp->sdp_media, soa_activity_session); ss->ss_answer_recv = 1; ss->ss_complete = 1; ss->ss_unprocessed_remote = 0; return 0;}/** Process rejection of offer. * * If the SDP offer was rejected (e.g., an offer in re-INVITE asked remote * end to add video to the session but the request was rejected), the * session should be restored to the state it was before last offer-answer * negotation round with soa_process_reject(). * * @param ss pointer to session object * @param completed pointer to callback function which is invoked when * operation is completed (currently not in use) * * @retval 1 when operation is successful * @retval 0 when operation was not needed * @retval -1 upon an error * * @ERRORS */int soa_process_reject(soa_session_t *ss, soa_callback_f *completed){ SU_DEBUG_9(("soa_process_reject(%s::%p) called\n", ss ? ss->ss_actions->soa_name : "", (void *)ss)); /** @ERROR EFAULT Bad address as @a ss. */ if (ss == NULL) return su_seterrno(EFAULT), -1; /** @ERROR EALREADY An operation is already in progress. */ if (ss->ss_in_progress) return su_seterrno(EALREADY), -1; /** @ERROR EPROTO We have not sent an offer or already have received answer. */ if (!ss->ss_offer_sent || ss->ss_answer_recv) return su_seterrno(EPROTO), -1; /**@sa soa_init_offer_answer(), soa_set_user_sdp(), soa_set_remote_sdp(), * soa_get_local_sdp(), soa_generate_offer(), soa_generate_answer(), * soa_process_answer(), soa_set_params(), soa_get_params(), * soa_get_paramlist(), SOATAG_USER_SDP(), SOATAG_USER_SDP_STR(), * SOATAG_REMOTE_SDP(), SOATAG_REMOTE_SDP_STR(). */ return ss->ss_actions->soa_process_reject(ss, completed);}/** Base method for processing rejection of offer. */int soa_base_process_reject(soa_session_t *ss, soa_callback_f *completed){ sdp_session_t const *l_sdp = ss->ss_local->ssd_sdp; (void)completed; if (!l_sdp) return -1; soa_set_activity(ss, l_sdp->sdp_media, soa_activity_session); ss->ss_offer_sent = 0; return 0;}/** Activate session. * * Mark soa session as active. * * @retval 0 when operation was successful * @retval -1 upon an error * * @ERRORS */int soa_activate(soa_session_t *ss, char const *option){ SU_DEBUG_9(("soa_activate(%s::%p, %s%s%s) called\n", ss ? ss->ss_actions->soa_name : "", (void *)ss, NICE(option))); /** @ERROR EFAULT Bad address as @a ss. */ if (ss == NULL) return -1; ss->ss_active = 1; return ss->ss_actions->soa_activate_session(ss, option);}int soa_base_activate(soa_session_t *ss, char const *option){ (void)ss; (void)option; return 0;}/** Deactivate session. * * Mark soa session as inactive. * * @retval 0 when operation was successful * @retval -1 upon an error * * @ERRORS */int soa_deactivate(soa_session_t *ss, char const *option){ SU_DEBUG_9(("soa_deactivate(%s::%p, %s%s%s) called\n", ss ? ss->ss_actions->soa_name : "", (void *)ss, NICE(option))); /** @ERROR EFAULT Bad address as @a ss. */ if (ss == NULL) return -1; ss->ss_active = 0; return ss->ss_actions->soa_deactivate_session(ss, option);}int soa_base_deactivate(soa_session_t *ss, char const *option){ (void)ss; (void)option; return 0;}/** Terminate session. */void soa_terminate(soa_session_t *ss, char const *option){ SU_DEBUG_9(("soa_terminate(%s::%p) called\n", ss ? ss->ss_actions->soa_name : "", (void *)ss)); /** @ERROR EFAULT Bad address as @a ss. */ if (ss == NULL) return; ss->ss_active = 0; ss->ss_terminated++; ss->ss_actions->soa_terminate_session(ss, option);}void soa_base_terminate(soa_session_t *ss, char const *option){ (void)option; soa_init_offer_answer(ss); ss->ss_oa_rounds = 0; soa_description_free(ss, ss->ss_remote); soa_set_activity(ss, NULL, soa_activity_session);}/** Return true if the SDP Offer/Answer negotation is complete. * * The soa_init_offer_answer() clears the completion flag. */int soa_is_complete(soa_session_t const *ss){ return ss && ss->ss_complete;}/** Return true if audio has been activated. */int soa_is_audio_active(soa_session_t const *ss){ int ma = ss ? ss->ss_local_activity->ma_audio : SOA_ACTIVE_DISABLED; if (ma >= 4) ma |= -8; return ma;}/** Return true if video has been activated. */int soa_is_video_active(soa_session_t const *ss){ int ma = ss ? ss->ss_local_activity->ma_video : SOA_ACTIVE_DISABLED; if (ma >= 4) ma |= -8; return ma;}/** Return true if image sharing has been activated. */int soa_is_image_active(soa_session_t const *ss){ int ma = ss ? ss->ss_local_activity->ma_image : SOA_ACTIVE_DISABLED; if (ma >= 4) ma |= -8; return ma;}/** Return true if messaging session has been activated. */int soa_is_chat_active(soa_session_t const *ss){ int ma = ss ? ss->ss_local_activity->ma_chat : SOA_ACTIVE_DISABLED; if (ma >= 4) ma |= -8; return ma;}/** Return true if remote audio is active (not on hold). */int soa_is_remote_audio_active(soa_session_t const *ss){ int ma = ss ? ss->ss_remote_activity->ma_audio : SOA_ACTIVE_DISABLED; if (ma >= 4) ma |= -8; return ma;}/** Return true if remote video is active (not on hold). */int soa_is_remote_video_active(soa_session_t const *ss){ int ma = ss ? ss->ss_remote_activity->ma_video : SOA_ACTIVE_DISABLED; if (ma >= 4) ma |= -8; return ma;}/** Return true if image sharing is active (not on hold). */int soa_is_remote_image_active(soa_session_t const *ss){ int ma = ss ? ss->ss_remote_activity->ma_image : SOA_ACTIVE_DISABLED; if (ma >= 4) ma |= -8; return ma;}/** Return true if chat session is active (not on hold). */int soa_is_remote_chat_active(soa_session_t const *ss){ int ma = ss ? ss->ss_remote_activity->ma_chat : SOA_ACTIVE_DISABLED; if (ma >= 4) ma |= -8; return ma;}/* ======================================================================== *//* Methods used by soa instances */int soa_set_status(soa_session_t *ss, int status, char const *phrase){ if (ss) { ss->ss_status = status, ss->ss_phrase = phrase; ss->ss_wcode = 0, ss->ss_warning = NULL; } return -1;}int soa_set_warning(soa_session_t *ss, int code, char const *text){ if (ss) ss->ss_wcode = code, ss->ss_warning = text; return -1;}su_inlineint soa_media_is_ready(soa_session_t const *ss){ XXX; return 0; /* return ss && ss->ss_session != NULL; */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -