⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sip_xfer.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	refer_to_uri = &xfer->refer_to_uri;    } else {	pj_strdup(xfer->dlg->pool, &xfer->refer_to_uri, refer_to_uri);    }    /* Create and add Refer-To header. */    hdr = pjsip_generic_string_hdr_create(tdata->pool, &refer_to,					  refer_to_uri);    if (!hdr) {	pjsip_tx_data_dec_ref(tdata);	status = PJ_ENOMEM;	goto on_return;    }    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);    /* Done. */    *p_tdata = tdata;    status = PJ_SUCCESS;on_return:    pjsip_dlg_dec_lock(xfer->dlg);    return status;}/* * Accept the incoming REFER request by sending 2xx response. * */PJ_DEF(pj_status_t) pjsip_xfer_accept( pjsip_evsub *sub,				       pjsip_rx_data *rdata,				       int st_code,				       const pjsip_hdr *hdr_list ){    /*     * Don't need to add custom headers, so just call basic     * evsub response.     */    return pjsip_evsub_accept( sub, rdata, st_code, hdr_list );}/* * For notifier, create NOTIFY request to subscriber, and set the state  * of the subscription.  */PJ_DEF(pj_status_t) pjsip_xfer_notify( pjsip_evsub *sub,				       pjsip_evsub_state state,				       int xfer_st_code,				       const pj_str_t *xfer_st_text,				       pjsip_tx_data **p_tdata){    pjsip_tx_data *tdata;    pjsip_xfer *xfer;    const pj_str_t reason = { "noresource", 10 };    char *body;    int bodylen;    pjsip_msg_body *msg_body;    pj_status_t status;        /* Check arguments. */    PJ_ASSERT_RETURN(sub, PJ_EINVAL);    /* Get the xfer object. */    xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id);    PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION);    /* Lock object. */    pjsip_dlg_inc_lock(xfer->dlg);    /* Create the NOTIFY request.      * Note that reason is only used when state is TERMINATED, and     * the defined termination reason for REFER is "noresource".     */    status = pjsip_evsub_notify( sub, state, NULL, &reason, &tdata);    if (status != PJ_SUCCESS)	goto on_return;    /* Check status text */    if (xfer_st_text==NULL || xfer_st_text->slen==0)	xfer_st_text = pjsip_get_status_text(xfer_st_code);    /* Save st_code and st_text, for current_notify() */    xfer->last_st_code = xfer_st_code;    pj_strdup(xfer->dlg->pool, &xfer->last_st_text, xfer_st_text);    /* Create sipfrag content. */    body = pj_pool_alloc(tdata->pool, 128);    bodylen = pj_ansi_snprintf(body, 128, "SIP/2.0 %u %.*s",			       xfer_st_code,			       (int)xfer_st_text->slen,			       xfer_st_text->ptr);    PJ_ASSERT_ON_FAIL(bodylen > 0 && bodylen < 128, 			{status=PJ_EBUG; pjsip_tx_data_dec_ref(tdata); 			 goto on_return; });    /* Create SIP message body. */    msg_body = pj_pool_zalloc(tdata->pool, sizeof(pjsip_msg_body));    msg_body->content_type.type = STR_MESSAGE;    msg_body->content_type.subtype = STR_SIPFRAG;    msg_body->content_type.param = STR_SIPFRAG_VERSION;    msg_body->data = body;    msg_body->len = bodylen;    msg_body->print_body = &pjsip_print_text_body;    msg_body->clone_data = &pjsip_clone_text_data;    /* Attach sipfrag body. */    tdata->msg->body = msg_body;    /* Done. */    *p_tdata = tdata;on_return:    pjsip_dlg_dec_lock(xfer->dlg);    return status;}/* * Send current state and the last sipfrag body. */PJ_DEF(pj_status_t) pjsip_xfer_current_notify( pjsip_evsub *sub,					       pjsip_tx_data **p_tdata ){    pjsip_xfer *xfer;    pj_status_t status;        /* Check arguments. */    PJ_ASSERT_RETURN(sub, PJ_EINVAL);    /* Get the xfer object. */    xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id);    PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION);    pjsip_dlg_inc_lock(xfer->dlg);    status = pjsip_xfer_notify(sub, pjsip_evsub_get_state(sub),			       xfer->last_st_code, &xfer->last_st_text,			       p_tdata);    pjsip_dlg_dec_lock(xfer->dlg);    return status;}/* * Send request message.  */PJ_DEF(pj_status_t) pjsip_xfer_send_request( pjsip_evsub *sub,					     pjsip_tx_data *tdata){    return pjsip_evsub_send_request(sub, tdata);}/* * This callback is called by event subscription when subscription * state has changed. */static void xfer_on_evsub_state( pjsip_evsub *sub, pjsip_event *event){    pjsip_xfer *xfer;    xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id);    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});    if (xfer->user_cb.on_evsub_state)	(*xfer->user_cb.on_evsub_state)(sub, event);}/* * Called when transaction state has changed. */static void xfer_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,				     pjsip_event *event){    pjsip_xfer *xfer;    xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id);    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});    if (xfer->user_cb.on_tsx_state)	(*xfer->user_cb.on_tsx_state)(sub, tsx, event);}/* * Called when REFER is received to refresh subscription. */static void xfer_on_evsub_rx_refresh( pjsip_evsub *sub, 				      pjsip_rx_data *rdata,				      int *p_st_code,				      pj_str_t **p_st_text,				      pjsip_hdr *res_hdr,				      pjsip_msg_body **p_body){    pjsip_xfer *xfer;    xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id);    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});    if (xfer->user_cb.on_rx_refresh) {	(*xfer->user_cb.on_rx_refresh)(sub, rdata, p_st_code, p_st_text,				       res_hdr, p_body);    } else {	/* Implementors MUST send NOTIFY if it implements on_rx_refresh	 * (implementor == "us" from evsub point of view.	 */	pjsip_tx_data *tdata;	pj_status_t status;	if (pjsip_evsub_get_state(sub)==PJSIP_EVSUB_STATE_TERMINATED) {	    status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_TERMINATED,					xfer->last_st_code,					&xfer->last_st_text, 					&tdata);	} else {	    status = pjsip_xfer_current_notify(sub, &tdata);	}	if (status == PJ_SUCCESS)	    pjsip_xfer_send_request(sub, tdata);    }}/* * Called when NOTIFY is received. */static void xfer_on_evsub_rx_notify( pjsip_evsub *sub, 				     pjsip_rx_data *rdata,				     int *p_st_code,				     pj_str_t **p_st_text,				     pjsip_hdr *res_hdr,				     pjsip_msg_body **p_body){    pjsip_xfer *xfer;    xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id);    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});    if (xfer->user_cb.on_rx_notify)	(*xfer->user_cb.on_rx_notify)(sub, rdata, p_st_code, p_st_text,				      res_hdr, p_body);}/* * Called when it's time to send SUBSCRIBE. */static void xfer_on_evsub_client_refresh(pjsip_evsub *sub){    pjsip_xfer *xfer;    xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id);    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});    if (xfer->user_cb.on_client_refresh) {	(*xfer->user_cb.on_client_refresh)(sub);    } else {	pj_status_t status;	pjsip_tx_data *tdata;	status = pjsip_xfer_initiate(sub, NULL, &tdata);	if (status == PJ_SUCCESS)	    pjsip_xfer_send_request(sub, tdata);    }}/* * Called when no refresh is received after the interval. */static void xfer_on_evsub_server_timeout(pjsip_evsub *sub){    pjsip_xfer *xfer;    xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id);    PJ_ASSERT_ON_FAIL(xfer!=NULL, {return;});    if (xfer->user_cb.on_server_timeout) {	(*xfer->user_cb.on_server_timeout)(sub);    } else {	pj_status_t status;	pjsip_tx_data *tdata;	status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,				   xfer->last_st_code, 				   &xfer->last_st_text, &tdata);	if (status == PJ_SUCCESS)	    pjsip_xfer_send_request(sub, tdata);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -