📄 soa.c
字号:
/** Get local SDP. * * The local SDP is usually result of SDP negotiation. */int soa_get_local_sdp(soa_session_t const *ss, sdp_session_t const **return_sdp, char const **return_sdp_str, int *return_len){ sdp_session_t const *sdp; char const *sdp_str; SU_DEBUG_9(("soa_get_local_sdp(%s::%p, [%p], [%p], [%p]) called\n", ss ? ss->ss_actions->soa_name : "", ss, return_sdp, return_sdp_str, return_len)); if (ss == NULL) return (void)su_seterrno(EFAULT), -1; sdp = ss->ss_local->ssd_sdp; sdp_str = ss->ss_local->ssd_str; if (sdp == NULL) return 0; if (return_sdp) *return_sdp = sdp; if (return_sdp_str) *return_sdp_str = sdp_str; if (return_len) *return_len = strlen(sdp_str); return 1;}/** Initialize offer/answer state machine */int soa_init_offer_answer(soa_session_t *ss){ int complete; SU_DEBUG_9(("soa_init_offer_answer(%s::%p) called\n", ss ? ss->ss_actions->soa_name : "", ss)); if (!ss) return 0; complete = ss->ss_complete; ss->ss_complete = 0; ss->ss_offer_sent = 0; ss->ss_offer_recv = 0; ss->ss_answer_sent = 0; ss->ss_answer_recv = 0; ss->ss_unprocessed_remote = 0; return complete;}char **soa_media_features(soa_session_t *ss, int live, su_home_t *home){ SU_DEBUG_9(("soa_media_features(%s::%p, %u, %p) called\n", ss ? ss->ss_actions->soa_name : "", ss, live, home)); if (ss) return ss->ss_actions->soa_media_features(ss, live, home); else return (void)su_seterrno(EFAULT), NULL;}char **soa_base_media_features(soa_session_t *ss, int live, su_home_t *home){ return su_zalloc(home, 8 * sizeof (char **));}char const * const * soa_sip_require(soa_session_t const *ss){ SU_DEBUG_9(("soa_sip_require(%s::%p) called\n", ss ? ss->ss_actions->soa_name : "", ss)); if (ss) return ss->ss_actions->soa_sip_require(ss); else return (void)su_seterrno(EFAULT), NULL;}char const * const * soa_base_sip_require(soa_session_t const *ss){ static char const *null = NULL; return &null;}char const * const * soa_sip_supported(soa_session_t const *ss){ SU_DEBUG_9(("soa_sip_supported(%s::%p) called\n", ss ? ss->ss_actions->soa_name : "", ss)); if (ss) return ss->ss_actions->soa_sip_supported(ss); else return (void)su_seterrno(EFAULT), NULL;}char const * const * soa_base_sip_supported(soa_session_t const *ss){ static char const *null = NULL; return &null;}int soa_remote_sip_features(soa_session_t *ss, char const * const * supported, char const * const * require){ SU_DEBUG_9(("soa_remote_sip_features(%s::%p, %p, %p) called\n", ss ? ss->ss_actions->soa_name : "", ss, supported, require)); if (ss) return ss->ss_actions->soa_remote_sip_features(ss, supported, require); else return (void)su_seterrno(EFAULT), -1;}int soa_base_remote_sip_features(soa_session_t *ss, char const * const * supported, char const * const * require){ return 0;}/** Run Offer step. * * @param ss pointer to session object * @param always always send offer (even if offer/answer has been completed) * @param completed pointer to callback function which is invoked when * operation is completed * * @retval 1 when operation is successful * @retval 0 when operation is not needed * @retval -1 upon an error * * @ERRORS */int soa_generate_offer(soa_session_t *ss, int always, soa_callback_f *completed){ SU_DEBUG_9(("soa_generate_offer(%s::%p, %u, %p) called\n", ss ? ss->ss_actions->soa_name : "", ss, always, completed)); /** @ERROR EFAULT Bad address. */ if (ss == NULL) return su_seterrno(EFAULT), -1; /** @ERROR 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);}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, 0); ss->ss_offer_sent = 1; ss->ss_answer_recv = 0; return 0;}/* Generate answer */int soa_generate_answer(soa_session_t *ss, soa_callback_f *completed){ SU_DEBUG_9(("soa_generate_answer(%s::%p, %p) called\n", ss ? ss->ss_actions->soa_name : "", ss, completed)); /** @ERROR EFAULT Bad address as @a ss. */ if (ss == NULL) return su_seterrno(EFAULT), -1; /** @ERROR 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);}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, 0); soa_set_activity(ss, r_sdp->sdp_media, 1); 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 */int soa_process_answer(soa_session_t *ss, soa_callback_f *completed){ SU_DEBUG_9(("soa_process_answer(%s::%p, %p) called\n", ss ? ss->ss_actions->soa_name : "", ss, completed)); /** @ERROR EFAULT Bad address as @a ss. */ if (ss == NULL) return su_seterrno(EFAULT), -1; /** @ERROR 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; return ss->ss_actions->soa_process_answer(ss, completed);}/** * Processes answer from remote end. */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, 0); soa_set_activity(ss, r_sdp->sdp_media, 1); ss->ss_answer_recv = 1; ss->ss_complete = 1; ss->ss_unprocessed_remote = 0; return 0;}/** Process rejection of offer */int soa_process_reject(soa_session_t *ss, soa_callback_f *completed){ SU_DEBUG_9(("soa_process_reject(%s::%p, %p) called\n", ss ? ss->ss_actions->soa_name : "", ss, completed)); /** @ERROR EFAULT Bad address as @a ss. */ if (ss == NULL) return su_seterrno(EFAULT), -1; /** @ERROR 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; return ss->ss_actions->soa_process_reject(ss, completed);}/** * Process reject from remote end. */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, 0); ss->ss_offer_sent = 0; return 0;}/** Activate session */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 : "", 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 */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 : "", 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 : "", 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, 0); soa_set_activity(ss, NULL, 1);}int soa_has_received_sdp(soa_session_t const *ss){ return ss && ss->ss_unprocessed_remote;}int soa_is_complete(soa_session_t const *ss){ return ss && ss->ss_complete;}int soa_is_audio_active(soa_session_t const *ss){ return ss ? ss->ss_local_activity->ma_audio : SOA_ACTIVE_DISABLED;}int soa_is_video_active(soa_session_t const *ss){ return ss ? ss->ss_local_activity->ma_video : SOA_ACTIVE_DISABLED;}int soa_is_image_active(soa_session_t const *ss){ return ss ? ss->ss_local_activity->ma_image : SOA_ACTIVE_DISABLED;}int soa_is_chat_active(soa_session_t const *ss){ return ss ? ss->ss_local_activity->ma_chat : SOA_ACTIVE_DISABLED;}int soa_is_remote_audio_active(soa_session_t const *ss){ return ss ? ss->ss_remote_activity->ma_audio : SOA_ACTIVE_DISABLED;}int soa_is_remote_video_active(soa_session_t const *ss){ return ss ? ss->ss_remote_activity->ma_video : SOA_ACTIVE_DISABLED;}int soa_is_remote_image_active(soa_session_t const *ss){ return ss ? ss->ss_remote_activity->ma_image : SOA_ACTIVE_DISABLED;}int soa_is_remote_chat_active(soa_session_t const *ss){ return ss ? ss->ss_remote_activity->ma_chat : SOA_ACTIVE_DISABLED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -