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

📄 sms_funcs.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: sms_funcs.c,v 1.62 2004/08/24 09:00:39 janakj Exp $ * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser 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 * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser 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 *//* * History: * -------- * 2003-01-23: switched from t_uac to t_uac_dlg, adapted to new way of *              parsing for Content-Type (bogdan) * 2003-02-28: protocolization of t_uac_dlg completed (jiri) * 2003-08-05: adapted to the new parse_content_type_hdr function (bogdan) * 2003-09-11: updated to new build_lump_rpl() interface (bogdan) * 2003-09-11: force parsing to hdr when extracting destination user (bogdan) */#include <unistd.h>#include <errno.h>#include <stdlib.h>#include "../../dprint.h"#include "../../ut.h"#include "../../config.h"#include "../../globals.h"#include "../../mem/mem.h"#include "../../mem/shm_mem.h"#include "../../parser/parse_uri.h"#include "../../parser/parse_content.h"#include "../../parser/parse_from.h"#include "../../data_lump_rpl.h"#include "../tm/t_hooks.h"#include "../tm/uac.h"#include "sms_funcs.h"#include "sms_report.h"#include "libsms_modem.h"#include "libsms_sms.h"struct modem modems[MAX_MODEMS];struct network networks[MAX_NETWORKS];int net_pipes_in[MAX_NETWORKS];int nr_of_networks;int nr_of_modems;int max_sms_parts;int *queued_msgs;int use_contact;int sms_report_type;struct tm_binds tmb;#define ERR_NUMBER_TEXT " is an invalid number! Please resend your SMS "\	"using a number in +(country code)(area code)(local number) format. Thanks"\	" for using our service!"#define ERR_NUMBER_TEXT_LEN (sizeof(ERR_NUMBER_TEXT)-1)#define ERR_TRUNCATE_TEXT "We are sorry, but your message exceeded our "\	"maximum allowed length. The following part of the message wasn't sent"\	" : "#define ERR_TRUNCATE_TEXT_LEN (sizeof(ERR_TRUNCATE_TEXT)-1)#define ERR_MODEM_TEXT "Due to our modem temporary indisponibility, "\	"the following message couldn't be sent : "#define ERR_MODEM_TEXT_LEN (sizeof(ERR_MODEM_TEXT)-1)#define STORED_NOTE "NOTE: Your SMS received provisional confirmation"\	" 48 \"Delivery is not yet possible\". The SMS was store on the "\	"SMSCenter for further delivery. Our gateway cannot guarantee "\	"further information regarding your SMS delivery! Your message was: "#define STORED_NOTE_LEN  (sizeof(STORED_NOTE)-1)#define OK_MSG "Your SMS was finally successfully delivered!"\	" Your message was: "#define OK_MSG_LEN  (sizeof(OK_MSG)-1)#define CONTENT_TYPE_HDR     "Content-Type: text/plain"#define CONTENT_TYPE_HDR_LEN (sizeof(CONTENT_TYPE_HDR)-1)#define append_str(_p,_s,_l) \	{memcpy((_p),(_s),(_l));\	(_p) += (_l);}#define is_in_sip_addr(_p) \	((_p)!=' ' && (_p)!='\t' && (_p)!='(' && (_p)!='[' && (_p)!='<' \	&& (_p)!='>' && (_p)!=']' && (_p)!=')' && (_p)!='?' && (_p)!='!' \	&& (_p)!=';' && (_p)!=',' && (_p)!='\n' && (_p)!='\r' && (_p)!='=')#define no_sip_addr_begin(_p) \	( (_p)!=' ' && (_p)!='\t' && (_p)!='-' && (_p)!='=' && (_p)!='\r'\	&& (_p)!='\n' && (_p)!=';' && (_p)!=',' && (_p)!='.' && (_p)!=':')#if 0inline int add_contact(struct sip_msg* msg , str* user){	struct lump_rpl *lump;	char *buf, *p;	int len;	len = 9 /*"Contact: "*/ + user->len/*user*/ + 1 /*"@"*/		+ domain.len/*host*/ + 6/*"<sip:>"*/ + CRLF_LEN;	buf = pkg_malloc( len );	if(!buf) {		LOG(L_ERR,"ERROR:sms_add_contact: out of memory! \n");		return -1;	}	p = buf;	append_str( p, "Contact: " , 9);	append_str( p, "<sip:" , 5);	append_str( p, user->s, user->len);	*(p++) = '@';	append_str( p, domain.s, domain.len);	*(p++) = '>';	append_str( p, CRLF, CRLF_LEN);	lump = build_lump_rpl( buf , len , LUMP_RPL_HDR);	if(!lump) {		LOG(L_ERR,"ERROR:sms_add_contact: unable to build lump_rpl! \n");		pkg_free( buf );		return -1;	}	add_lump_rpl( msg , lump );	pkg_free(buf);	return 1;}#endifint push_on_network(struct sip_msg *msg, int net){	str    body;	struct sip_uri  uri;	struct sms_msg  *sms_messg;	struct to_body  *from;	char   *p;	int    len;	int    mime;	/* get the message's body	 * anyhow we have to call this function, so let's do it at the beginning	 * to force the parsing of all the headers - like this we avoid separate	 * calls of parse_headers function for FROM, CONTENT_LENGTH, TO hdrs  */	body.s = get_body( msg );	if (body.s==0) {		LOG(L_ERR,"ERROR:sms_push_on_net: cannot extract body from msg!\n");		goto error;	}	/* content-length (if present) must be already parsed */	if (!msg->content_length) {		LOG(L_ERR,"ERROR:sms_push_on_net: no Content-Length header found!\n");		goto error;	}	body.len = get_content_length( msg );	/* parse the content-type header */	if ( (mime=parse_content_type_hdr(msg))<1 ) {		LOG(L_ERR,"ERROR:sms_push_on_net:cannot parse Content-Type header\n");		goto error;	}	/* check the content-type value */	if ( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN	&& mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM ) {		LOG(L_ERR,"ERROR:sms_push_on_net: invalid content-type for a "			"message request! type found=%d\n",mime);		goto error;	}	/* we try to get the user name (phone number) first from the RURI 	   (in our case means from new_uri or from first_line.u.request.uri);	   if it's missing there (like in requests generated by MSN MESSENGER),	   we go for "to" header	*/	DBG("DEBUG:sms_push_on_net: string to get user from new_uri\n");	if ( !msg->new_uri.s||parse_uri( msg->new_uri.s,msg->new_uri.len,&uri)	|| !uri.user.len )	{		DBG("DEBUG:sms_push_on_net: string to get user from R_uri\n");		if ( parse_uri( msg->first_line.u.request.uri.s,		msg->first_line.u.request.uri.len ,&uri)||!uri.user.len )		{			DBG("DEBUG:sms_push_on_net: string to get user from To\n");			if ( (!msg->to&&((parse_headers(msg,HDR_TO,0)==-1) || !msg->to)) ||			parse_uri( get_to(msg)->uri.s, get_to(msg)->uri.len, &uri)==-1			|| !uri.user.len)			{				LOG(L_ERR,"ERROR:sms_push_on_net: unable to extract user"					" name from RURI and To header!\n");				goto error;			}		}	}	/* check the uri.user format = '+(inter code)(number)' */	if (uri.user.len<2 || uri.user.s[0]!='+' || uri.user.s[1]<'1'	|| uri.user.s[1]>'9') {		LOG(L_ERR,"ERROR:sms_push_on_net: user tel number [%.*s] does not"			"respect international format\n",uri.user.len,uri.user.s);		goto error;	}	/* parsing from header */	if ( parse_from_header( msg )==-1 ) {		LOG(L_ERR,"ERROR:sms_push_on_net: cannot get FROM header\n");		goto error;	}	from = (struct to_body*)msg->from->parsed;#if 0	/* adds contact header into reply */	if (add_contact(msg,&(uri.user))==-1) {		LOG(L_ERR,"ERROR:sms_push_on_net:can't build contact for reply\n");		goto error;	}#endif	/*-------------BUILD AND FILL THE SMS_MSG STRUCTURE --------------------*/	/* computes the amount of memory needed */	len = SMS_HDR_BF_ADDR_LEN + from->uri.len		+ SMS_HDR_AF_ADDR_LEN + body.len + SMS_FOOTER_LEN /*text to send*/		+ from->uri.len /* from */		+ uri.user.len-1 /* to user (without '+') */		+ sizeof(struct sms_msg) ; /* the sms_msg structure */	/* allocs a new sms_msg structure in shared memory */	sms_messg = (struct sms_msg*)shm_malloc(len);	if (!sms_messg) {		LOG(L_ERR,"ERROR:sms_push_on_net: cannot get shm memory!\n");		goto error;	}	p = (char*)sms_messg + sizeof(struct sms_msg);	/* copy "from" into sms struct */	sms_messg->from.len = from->uri.len;	sms_messg->from.s = p;	append_str(p,from->uri.s,from->uri.len);	/* copy "to.user" - we have to strip out the '+' */	sms_messg->to.len = uri.user.len-1;	sms_messg->to.s = p;	append_str(p,uri.user.s+1,sms_messg->to.len);	/* copy (and composing) sms body */	sms_messg->text.len = SMS_HDR_BF_ADDR_LEN + sms_messg->from.len		+ SMS_HDR_AF_ADDR_LEN + body.len+SMS_FOOTER_LEN;	sms_messg->text.s = p;	append_str(p, SMS_HDR_BF_ADDR, SMS_HDR_BF_ADDR_LEN);	append_str(p, sms_messg->from.s, sms_messg->from.len);	append_str(p, SMS_HDR_AF_ADDR, SMS_HDR_AF_ADDR_LEN);	append_str(p, body.s, body.len);	append_str(p, SMS_FOOTER, SMS_FOOTER_LEN);	if (*queued_msgs>MAX_QUEUED_MESSAGES)		goto error;	(*queued_msgs)++;	if (write(net_pipes_in[net], &sms_messg, sizeof(sms_messg))!=	sizeof(sms_messg) )	{		LOG(L_ERR,"ERROR:sms_push_on_net: error when writing for net %d "			"to pipe [%d] : %s\n",net,net_pipes_in[net],strerror(errno) );		shm_free(sms_messg);		(*queued_msgs)--;		goto error;	}	return 1; error:	return -1;}int send_sip_msg_request(str *to, str *from_user, str *body){	str msg_type = { "MESSAGE", 7};	str from;	str hdrs;	int foo;	char *p;	from.s = hdrs.s = 0;	from.len = hdrs.len = 0;	/* From header */	from.len = 6 /*"<sip:+"*/ +  from_user->len/*user*/ + 1/*"@"*/		+ domain.len /*host*/ + 1 /*">"*/ ;	from.s = (char*)pkg_malloc(from.len);	if (!from.s)		goto error;	p=from.s;	append_str(p,"<sip:+",6);	append_str(p,from_user->s,from_user->len);	*(p++)='@';	append_str(p,domain.s,domain.len);	*(p++)='>';	/* hdrs = Contact header + Content-type */	/* length */	hdrs.len = CONTENT_TYPE_HDR_LEN + CRLF_LEN;	if (use_contact)		hdrs.len += 15 /*"Contact: <sip:+"*/ + from_user->len/*user*/ +			1/*"@"*/ + domain.len/*host*/ + 1 /*">"*/ + CRLF_LEN;	hdrs.s = (char*)pkg_malloc(hdrs.len);	if (!hdrs.s)		goto error;	p=hdrs.s;	append_str(p,CONTENT_TYPE_HDR,CONTENT_TYPE_HDR_LEN);	append_str(p,CRLF,CRLF_LEN);	if (use_contact) {		append_str(p,"Contact: <sip:+",15);		append_str(p,from_user->s,from_user->len);		*(p++)='@';		append_str(p,domain.s,domain.len);		append_str(p,">"CRLF,1+CRLF_LEN);	}	/* sending the request */	foo = tmb.t_request( &msg_type,   /* request type */			0,                        /* Request-URI */			to,                       /* To */			&from,                    /* From */			&hdrs,                    /* Additional headers including CRLF */			body,                     /* Message body */			0,                        /* Callback function */			0                         /* Callback parameter */		);	if (from.s) pkg_free(from.s);	if (hdrs.s) pkg_free(hdrs.s);	return foo;error:	LOG(L_ERR,"ERROR:sms_build_and_send_sip: no free pkg memory!\n");	if (from.s) pkg_free(from.s);	if (hdrs.s) pkg_free(hdrs.s);	return -1;}inline int send_error(struct sms_msg *sms_messg, char *msg1_s, int msg1_len,													char *msg2_s, int msg2_len){	str  body;	char *p;	int  foo;	/* body */	body.len = msg1_len + msg2_len;	body.s = (char*)pkg_malloc(body.len);	if (!body.s)		goto error;	p=body.s;	append_str(p, msg1_s, msg1_len );	append_str(p, msg2_s, msg2_len);	/* sending */	foo = send_sip_msg_request( &(sms_messg->from), &(sms_messg->to), &body);	pkg_free( body.s );	return foo;error:	LOG(L_ERR,"ERROR:sms_send_error: no free pkg memory!\n");	return -1;}inline unsigned int split_text(str *text, unsigned char *lens,int nice){	int  nr_chunks;	int  k,k1,len;	char c;	nr_chunks = 0;	len = 0;	do{		k = MAX_SMS_LENGTH-(nice&&nr_chunks?SMS_EDGE_PART_LEN:0);		if ( len+k<text->len ) {			/* is not the last piece :-( */			if (nice && !nr_chunks) k -= SMS_EDGE_PART_LEN;			if (text->len-len-k<=SMS_FOOTER_LEN+4)				k = (text->len-len)/2;			/* ->looks for a point to split */			k1 = k;			while( k>0 && (c=text->s[len+k-1])!='.' && c!=' ' && c!=';'			&& c!='\r' && c!='\n' && c!='-' && c!='!' && c!='?' && c!='+'			&& c!='=' && c!='\t' && c!='\'')				k--;			if (k<k1/2)				/* wast of space !!!!*/				k=k1;			len += k;			lens[nr_chunks] = k;		}else {			/*last chunk*/			lens[nr_chunks] = text->len-len;			len = text->len;

⌨️ 快捷键说明

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