📄 sms_funcs.c
字号:
/* * $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 + -