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

📄 sip_xfer.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: sip_xfer.c 974 2007-02-19 01:13:53Z bennylp $ *//*  * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  */#include <pjsip-ua/sip_xfer.h>#include <pjsip-simple/evsub_msg.h>#include <pjsip/sip_dialog.h>#include <pjsip/sip_errno.h>#include <pjsip/sip_endpoint.h>#include <pjsip/sip_module.h>#include <pjsip/sip_transport.h>#include <pj/assert.h>#include <pj/pool.h>#include <pj/string.h>/* * Refer module (mod-refer) */static struct pjsip_module mod_xfer = {    NULL, NULL,				/* prev, next.			*/    { "mod-refer", 9 },			/* Name.			*/    -1,					/* Id				*/    PJSIP_MOD_PRIORITY_DIALOG_USAGE,	/* Priority			*/    NULL,				/* load()			*/    NULL,				/* start()			*/    NULL,				/* stop()			*/    NULL,				/* unload()			*/    NULL,				/* on_rx_request()		*/    NULL,				/* on_rx_response()		*/    NULL,				/* on_tx_request.		*/    NULL,				/* on_tx_response()		*/    NULL,				/* on_tsx_state()		*/};/* Declare PJSIP_REFER_METHOD, so that if somebody declares this in * sip_msg.h we can catch the error here. */enum{    PJSIP_REFER_METHOD = PJSIP_OTHER_METHOD};const pjsip_method pjsip_refer_method = {    PJSIP_REFER_METHOD,    { "REFER", 5}};/* * String constants */const pj_str_t STR_REFER = { "refer", 5 };const pj_str_t STR_MESSAGE = { "message", 7 };const pj_str_t STR_SIPFRAG = { "sipfrag", 7 };const pj_str_t STR_SIPFRAG_VERSION = {";version=2.0", 12 };/* * Transfer struct. */struct pjsip_xfer{    pjsip_evsub		*sub;		/**< Event subscribtion record.	    */    pjsip_dialog	*dlg;		/**< The dialog.		    */    pjsip_evsub_user	 user_cb;	/**< The user callback.		    */    pj_str_t		 refer_to_uri;	/**< The full Refer-To URI.	    */    int			 last_st_code;	/**< st_code sent in last NOTIFY    */    pj_str_t		 last_st_text;	/**< st_text sent in last NOTIFY    */};typedef struct pjsip_xfer pjsip_xfer;/* * Forward decl for evsub callback. */static void xfer_on_evsub_state( pjsip_evsub *sub, pjsip_event *event);static void xfer_on_evsub_tsx_state( pjsip_evsub *sub, pjsip_transaction *tsx,				     pjsip_event *event);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);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);static void xfer_on_evsub_client_refresh(pjsip_evsub *sub);static void xfer_on_evsub_server_timeout(pjsip_evsub *sub);/* * Event subscription callback for xference. */static pjsip_evsub_user xfer_user = {    &xfer_on_evsub_state,    &xfer_on_evsub_tsx_state,    &xfer_on_evsub_rx_refresh,    &xfer_on_evsub_rx_notify,    &xfer_on_evsub_client_refresh,    &xfer_on_evsub_server_timeout,};/* * Initialize the REFER subsystem. */PJ_DEF(pj_status_t) pjsip_xfer_init_module(pjsip_endpoint *endpt){    const pj_str_t accept = { "message/sipfrag;version=2.0", 27 };    pj_status_t status;    PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL);    PJ_ASSERT_RETURN(mod_xfer.id == -1, PJ_EINVALIDOP);    status = pjsip_endpt_register_module(endpt, &mod_xfer);    if (status != PJ_SUCCESS)	return status;    status = pjsip_endpt_add_capability( endpt, &mod_xfer, PJSIP_H_ALLOW, 					 NULL, 1, &pjsip_refer_method.name);    if (status != PJ_SUCCESS)	return status;    status = pjsip_evsub_register_pkg( &mod_xfer, &STR_REFER, 300, 1, &accept);    if (status != PJ_SUCCESS)	return status;    return PJ_SUCCESS;}/* * Create transferer (sender of REFER request). * */PJ_DEF(pj_status_t) pjsip_xfer_create_uac( pjsip_dialog *dlg,					   const pjsip_evsub_user *user_cb,					   pjsip_evsub **p_evsub ){    pj_status_t status;    pjsip_xfer *xfer;    pjsip_evsub *sub;    PJ_ASSERT_RETURN(dlg && p_evsub, PJ_EINVAL);    pjsip_dlg_inc_lock(dlg);    /* Create event subscription */    status = pjsip_evsub_create_uac( dlg,  &xfer_user, &STR_REFER, 				     PJSIP_EVSUB_NO_EVENT_ID, &sub);    if (status != PJ_SUCCESS)	goto on_return;    /* Create xfer session */    xfer = pj_pool_zalloc(dlg->pool, sizeof(pjsip_xfer));    xfer->dlg = dlg;    xfer->sub = sub;    if (user_cb)	pj_memcpy(&xfer->user_cb, user_cb, sizeof(pjsip_evsub_user));    /* Attach to evsub */    pjsip_evsub_set_mod_data(sub, mod_xfer.id, xfer);    *p_evsub = sub;on_return:    pjsip_dlg_dec_lock(dlg);    return status;}/* * Create transferee (receiver of REFER request). * */PJ_DEF(pj_status_t) pjsip_xfer_create_uas( pjsip_dialog *dlg,					   const pjsip_evsub_user *user_cb,					   pjsip_rx_data *rdata,					   pjsip_evsub **p_evsub ){    pjsip_evsub *sub;    pjsip_xfer *xfer;    const pj_str_t STR_EVENT = {"Event", 5 };    pjsip_event_hdr *event_hdr;    pj_status_t status;    /* Check arguments */    PJ_ASSERT_RETURN(dlg && rdata && p_evsub, PJ_EINVAL);    /* Must be request message */    PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,		     PJSIP_ENOTREQUESTMSG);    /* Check that request is REFER */    PJ_ASSERT_RETURN(pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,				      &pjsip_refer_method)==0,		     PJSIP_ENOTREFER);    /* Lock dialog */    pjsip_dlg_inc_lock(dlg);    /* The evsub framework expects an Event header in the request,     * while a REFER request conveniently doesn't have one (pun intended!).     * So create a dummy Event header.     */    if (pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,				   &STR_EVENT, NULL)==NULL)    {	event_hdr = pjsip_event_hdr_create(rdata->tp_info.pool);	event_hdr->event_type = STR_REFER;	pjsip_msg_add_hdr(rdata->msg_info.msg, (pjsip_hdr*)event_hdr);    }    /* Create server subscription */    status = pjsip_evsub_create_uas( dlg, &xfer_user, rdata, 				     PJSIP_EVSUB_NO_EVENT_ID, &sub);    if (status != PJ_SUCCESS)	goto on_return;    /* Create server xfer subscription */    xfer = pj_pool_zalloc(dlg->pool, sizeof(pjsip_xfer));    xfer->dlg = dlg;    xfer->sub = sub;    if (user_cb)	pj_memcpy(&xfer->user_cb, user_cb, sizeof(pjsip_evsub_user));    /* Attach to evsub */    pjsip_evsub_set_mod_data(sub, mod_xfer.id, xfer);    /* Done: */    *p_evsub = sub;on_return:    pjsip_dlg_dec_lock(dlg);    return status;}/* * Call this function to create request to initiate REFER subscription. * */PJ_DEF(pj_status_t) pjsip_xfer_initiate( pjsip_evsub *sub,					 const pj_str_t *refer_to_uri,					 pjsip_tx_data **p_tdata){    pjsip_xfer *xfer;    const pj_str_t refer_to = { "Refer-To", 8};    pjsip_tx_data *tdata;    pjsip_generic_string_hdr *hdr;    pj_status_t status;    /* sub and p_tdata argument must be valid.  */    PJ_ASSERT_RETURN(sub && p_tdata, PJ_EINVAL);    /* Get the xfer object. */    xfer = pjsip_evsub_get_mod_data(sub, mod_xfer.id);    PJ_ASSERT_RETURN(xfer != NULL, PJSIP_ENOREFERSESSION);    /* refer_to_uri argument MAY be NULL for subsequent REFER requests,     * but it MUST be specified in the first REFER.     */    PJ_ASSERT_RETURN((refer_to_uri || xfer->refer_to_uri.slen), PJ_EINVAL);    /* Lock dialog. */    pjsip_dlg_inc_lock(xfer->dlg);    /* Create basic REFER request */    status = pjsip_evsub_initiate(sub, &pjsip_refer_method, -1, 				  &tdata);    if (status != PJ_SUCCESS)	goto on_return;    /* Save Refer-To URI. */    if (refer_to_uri == NULL) {

⌨️ 快捷键说明

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