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

📄 pjsua_im.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: pjsua_im.c 1271 2007-05-14 16:37:47Z 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 <pjsua-lib/pjsua.h>#include <pjsua-lib/pjsua_internal.h>#define THIS_FILE   "pjsua_im.h"/* Declare MESSAGE method *//* We put PJSIP_MESSAGE_METHOD as the enum here, so that when * somebody add that method into pjsip_method_e in sip_msg.h we * will get an error here. */enum{    PJSIP_MESSAGE_METHOD = PJSIP_OTHER_METHOD};const pjsip_method pjsip_message_method ={    PJSIP_MESSAGE_METHOD,    { "MESSAGE", 7 }};/* Proto */static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata);/* The module instance. */static pjsip_module mod_pjsua_im = {    NULL, NULL,				/* prev, next.		*/    { "mod-pjsua-im", 12 },		/* Name.		*/    -1,					/* Id			*/    PJSIP_MOD_PRIORITY_APPLICATION,	/* Priority	        */    NULL,				/* load()		*/    NULL,				/* start()		*/    NULL,				/* stop()		*/    NULL,				/* unload()		*/    &im_on_rx_request,			/* on_rx_request()	*/    NULL,				/* on_rx_response()	*/    NULL,				/* on_tx_request.	*/    NULL,				/* on_tx_response()	*/    NULL,				/* on_tsx_state()	*/};/* MIME constants. */static const pj_str_t STR_MIME_APP	   = { "application", 11 };static const pj_str_t STR_MIME_ISCOMPOSING = { "im-iscomposing+xml", 18 };static const pj_str_t STR_MIME_TEXT	   = { "text", 4 };static const pj_str_t STR_MIME_PLAIN	   = { "plain", 5 };/* Check if content type is acceptable */#if 0static pj_bool_t acceptable_message(const pjsip_media_type *mime){    return (pj_stricmp(&mime->type, &STR_MIME_TEXT)==0 &&	    pj_stricmp(&mime->subtype, &STR_MIME_PLAIN)==0)	    ||	   (pj_stricmp(&mime->type, &STR_MIME_APP)==0 &&	    pj_stricmp(&mime->subtype, &STR_MIME_ISCOMPOSING)==0);}#endif/** * Create Accept header for MESSAGE. */pjsip_accept_hdr* pjsua_im_create_accept(pj_pool_t *pool){    /* Create Accept header. */    pjsip_accept_hdr *accept;    accept = pjsip_accept_hdr_create(pool);    accept->values[0] = pj_str("text/plain");    accept->values[1] = pj_str("application/im-iscomposing+xml");    accept->count = 2;    return accept;}/** * Private: check if we can accept the message. */pj_bool_t pjsua_im_accept_pager(pjsip_rx_data *rdata,				pjsip_accept_hdr **p_accept_hdr){    /* Some UA sends text/html, so this check will break */#if 0    pjsip_ctype_hdr *ctype;    pjsip_msg *msg;    msg = rdata->msg_info.msg;    /* Request MUST have message body, with Content-Type equal to     * "text/plain".     */    ctype = pjsip_msg_find_hdr(msg, PJSIP_H_CONTENT_TYPE, NULL);    if (msg->body == NULL || ctype == NULL || 	!acceptable_message(&ctype->media))     {	/* Create Accept header. */	if (p_accept_hdr)	    *p_accept_hdr = pjsua_im_create_accept(rdata->tp_info.pool);	return PJ_FALSE;    }#else    PJ_UNUSED_ARG(rdata);    PJ_UNUSED_ARG(p_accept_hdr);#endif    return PJ_TRUE;}/** * Private: process pager message. *	    This may trigger pjsua_ui_on_pager() or pjsua_ui_on_typing(). */void pjsua_im_process_pager(int call_id, const pj_str_t *from,			    const pj_str_t *to, pjsip_rx_data *rdata){    pjsip_contact_hdr *contact_hdr;    pj_str_t contact;    pjsip_msg_body *body = rdata->msg_info.msg->body;    /* Body MUST have been checked before */    pj_assert(body != NULL);    /* Build remote contact */    contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,				     NULL);    if (contact_hdr) {	contact.ptr = pj_pool_alloc(rdata->tp_info.pool, 				    PJSIP_MAX_URL_SIZE);	contact.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR,				       contact_hdr->uri, contact.ptr,				       PJSIP_MAX_URL_SIZE);    } else {	contact.slen = 0;    }    if (pj_stricmp(&body->content_type.type, &STR_MIME_APP)==0 &&	pj_stricmp(&body->content_type.subtype, &STR_MIME_ISCOMPOSING)==0)    {	/* Expecting typing indication */	pj_status_t status;	pj_bool_t is_typing;	status = pjsip_iscomposing_parse( rdata->tp_info.pool, body->data,					  body->len, &is_typing, NULL, NULL,					  NULL );	if (status != PJ_SUCCESS) {	    pjsua_perror(THIS_FILE, "Invalid MESSAGE body", status);	    return;	}	if (pjsua_var.ua_cfg.cb.on_typing) {	    (*pjsua_var.ua_cfg.cb.on_typing)(call_id, from, to, &contact,					     is_typing);	}    } else {	pj_str_t mime_type;	char buf[256];	pjsip_media_type *m;	pj_str_t text_body;		/* Save text body */	text_body.ptr = rdata->msg_info.msg->body->data;	text_body.slen = rdata->msg_info.msg->body->len;	/* Get mime type */	m = &rdata->msg_info.msg->body->content_type;	mime_type.ptr = buf;	mime_type.slen = pj_ansi_snprintf(buf, sizeof(buf),				          "%.*s/%.*s",				          (int)m->type.slen,					  m->type.ptr,					  (int)m->subtype.slen,					  m->subtype.ptr);	if (mime_type.slen < 1)	    mime_type.slen = 0;	if (pjsua_var.ua_cfg.cb.on_pager) {	    (*pjsua_var.ua_cfg.cb.on_pager)(call_id, from, to, &contact, 					    &mime_type, &text_body);	}    }}/* * Handler to receive incoming MESSAGE */static pj_bool_t im_on_rx_request(pjsip_rx_data *rdata){    pj_str_t from, to;    pjsip_accept_hdr *accept_hdr;    pjsip_msg *msg;    pj_status_t status;    msg = rdata->msg_info.msg;    /* Only want to handle MESSAGE requests. */    if (pjsip_method_cmp(&msg->line.req.method, &pjsip_message_method) != 0) {	return PJ_FALSE;    }    /* Should not have any transaction attached to rdata. */    PJ_ASSERT_RETURN(pjsip_rdata_get_tsx(rdata)==NULL, PJ_FALSE);    /* Should not have any dialog attached to rdata. */    PJ_ASSERT_RETURN(pjsip_rdata_get_dlg(rdata)==NULL, PJ_FALSE);    /* Check if we can accept the message. */    if (!pjsua_im_accept_pager(rdata, &accept_hdr)) {	pjsip_hdr hdr_list;	pj_list_init(&hdr_list);	pj_list_push_back(&hdr_list, accept_hdr);	pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 				      PJSIP_SC_NOT_ACCEPTABLE_HERE, NULL, 				      &hdr_list, NULL);	return PJ_TRUE;    }        /* Respond with 200 first, so that remote doesn't retransmit in case     * the UI takes too long to process the message.      */    status = pjsip_endpt_respond( pjsua_var.endpt, NULL, rdata, 200, NULL,				  NULL, NULL, NULL);    /* For the source URI, we use Contact header if present, since     * Contact header contains the port number information. If this is     * not available, then use From header.     */    from.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);    from.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, 				rdata->msg_info.from->uri,				from.ptr, PJSIP_MAX_URL_SIZE);    if (from.slen < 1)	from = pj_str("<--URI is too long-->");    /* Build the To text. */    to.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);    to.slen = pjsip_uri_print( PJSIP_URI_IN_FROMTO_HDR, 			       rdata->msg_info.to->uri,			       to.ptr, PJSIP_MAX_URL_SIZE);    if (to.slen < 1)	to = pj_str("<--URI is too long-->");    /* Process pager. */    pjsua_im_process_pager(-1, &from, &to, rdata);    /* Done. */    return PJ_TRUE;}/* Outgoing IM callback. */static void im_callback(void *token, pjsip_event *e){    pjsua_im_data *im_data = token;    if (e->type == PJSIP_EVENT_TSX_STATE) {	pjsip_transaction *tsx = e->body.tsx_state.tsx;	/* Ignore provisional response, if any */	if (tsx->status_code < 200)	    return;	/* Handle authentication challenges */	if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG &&	    (tsx->status_code == 401 || tsx->status_code == 407)) 	{	    pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;	    pjsip_tx_data *tdata;	    pjsip_auth_clt_sess auth;	    pj_status_t status;	    PJ_LOG(4,(THIS_FILE, "Resending IM with authentication"));	    /* Create temporary authentication session */	    pjsip_auth_clt_init(&auth,pjsua_var.endpt,rdata->tp_info.pool, 0);    	    pjsip_auth_clt_set_credentials(&auth, 		pjsua_var.acc[im_data->acc_id].cred_cnt,

⌨️ 快捷键说明

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