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

📄 libsms_getsms.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/*SMS Server ToolsCopyright (C) 2000-2002 Stefan FringsThis program is free software unless you got it under another license directlyfrom the author. You can redistribute it and/or modify it under the terms ofthe GNU General Public License as published by the Free Software Foundation.Either version 2 of the License, or (at your option) any later version.http://www.isis.de/members/~s.fringsmailto:s.frings@mail.isis.de */#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <termios.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <syslog.h>#include "../../ut.h"#include "libsms_charset.h"#include "libsms_modem.h"#include "libsms_sms.h"#include "sms_funcs.h"#define set_date(_date,_Pointer) {\	(_date)[0] = (_Pointer)[3];\	(_date)[1] = (_Pointer)[2];\	(_date)[2] = '-';\	(_date)[3] = (_Pointer)[5];\	(_date)[4] = (_Pointer)[4];\	(_date)[5] = '-';\	(_date)[6] = (_Pointer)[1];\	(_date)[7] = (_Pointer)[0];}#define set_time( _time , _Pointer) {\	(_time)[0] = (_Pointer)[1];\	(_time)[1] = (_Pointer)[0];\	(_time)[2] = ':';\	(_time)[3] = (_Pointer)[3];\	(_time)[4] = (_Pointer)[2];\	(_time)[5] = ':';\	(_time)[6] = (_Pointer)[5];\	(_time)[7] = (_Pointer)[4];}/* converts an octet to a 8-Bit value */int octet2bin(char* octet){	int result=0;	if (octet[0]>57)		result=octet[0]-55;	else		result=octet[0]-48;	result=result<<4;	if (octet[1]>57)		result+=octet[1]-55;	else		result+=octet[1]-48;	return result;}/* converts a PDU-String to Ascii; the first octet is the length   return the length of ascii */int pdu2ascii(char* pdu, char* ascii){	int bitposition=0;	int byteposition;	int byteoffset;	int charcounter;	int bitcounter;	int count;	int octetcounter;	char c;	char binary[500];	/* First convert all octets to bytes */	count=octet2bin(pdu);	for (octetcounter=0; octetcounter<count; octetcounter++)		binary[octetcounter]=octet2bin(pdu+(octetcounter<<1)+2);	/* Then convert from 8-Bit to 7-Bit encapsulated in 8 bit */	for (charcounter=0; charcounter<count; charcounter++) {		c=0;		for (bitcounter=0; bitcounter<7; bitcounter++) {			byteposition=bitposition/8;			byteoffset=bitposition%8;			if (binary[byteposition]&(1<<byteoffset))				c=c|128;			bitposition++;			c=(c>>1)&127; /* The shift fills with 1, but I want 0 */		}		if (/*cs_convert*/1)			ascii[charcounter]=sms2ascii(c);		else if (c==0)			ascii[charcounter]=183;		else			ascii[charcounter]=c;	}	ascii[count]=0;	return count;}int pdu2binary(char* pdu, char* binary){	int count;	int octetcounter;	count=octet2bin(pdu);	for (octetcounter=0; octetcounter<count; octetcounter++)		binary[octetcounter]=octet2bin(pdu+(octetcounter<<1)+2);	binary[count]=0;	return count;}/* reads a SMS from the SIM-memory 1-10 *//* returns number of SIM memory if successful *//* on digicom the return value can be != sim */int fetchsms(struct modem *mdm, int sim, char* pdu){	char command[16];	char answer[512];	char* position;	char* beginning;	char* end;	int  foo,err;	int  clen;	// Digicom reports date+time only with AT+CMGL	if (mdm->mode==MODE_DIGICOM) {		put_command(mdm,"AT+CMGL=\"ALL\"\r",14,answer,			sizeof(answer),200,0);		/* search for beginning of the answer */		position=strstr(answer,"+CMGL: ");		if (position) {			end=position+7;			while (*end<'9' && *end>'0') end++;			if (end==position+7) {				foo = str2s(position+7,end-position-7,&err);				if (!err) {					DBG("DEBUG:fetchsms:Found a message at memory %i\n",foo);					sim=foo;				}				position = 0;			}			position = 0;		}	} else {		DBG("DEBUG:fetchsms:Trying to get stored message %i\n",sim);		clen=sprintf(command,"AT+CMGR=%i\r",sim);		put_command(mdm,command,clen,answer,sizeof(answer),50,0);		/* search for beginning of the answer */		position=strstr(answer,"+CMGR:");	}	/* keine SMS empfangen, weil Modem nicht mit +CMGR 	oder +CMGL geantwortet hat */	if (position==0)		return 0;	beginning=position+7;	/* keine SMS, weil Modem mit +CMGR: 0,,0 geantwortet hat */	if (strstr(answer,",,0\r"))		return 0;	/* After that we have the PDU or ASCII string */	for( end=beginning ; *end && *end!='\r' ; end++ );	if ( !*end || end-beginning<4)		return 0;	for( end=end+1 ; *end && *end!='\r' ; end++ );	if ( !*end || end-beginning<4)		return 0;	/* Now we have the end of the PDU or ASCII string */	*end=0;	strcpy(pdu,beginning);	return sim;}/* deletes the selected sms from the sim card */void deletesms(struct modem *mdm, int sim) {	char command[32];	char answer[128];	int  clen;	DBG("DEBUG:deletesms: Deleting message %i !\n",sim);	clen = sprintf(command,"AT+CMGD=%i\r",sim);	put_command(mdm, command, clen, answer, sizeof(answer), 50, 0);}// checks the size of the SIM memoryint check_memory(struct modem *mdm, int flag){	char  answer[500];	char* posi;	int   laenge;	int   err,foo;	int   j, out;	for(out=0,j=0;!out && j<10; j++) 	{		if (put_command(mdm,"AT+CPMS?\r",9,answer,sizeof(answer),50,0)		&& (posi=strstr(answer,"+CPMS:"))!=0 )		{			// Modem supports CPMS command. Read memory size			if ( (posi=strchr(posi,','))!=0 ) {				posi++;				if ( (laenge=strcspn(posi,",\r"))!=0 ) {					if (flag==USED_MEM ) {						foo = str2s(posi,laenge,&err);						if (err) {							LOG(L_ERR,"ERROR:sms_check_memory: unable to "								"convert into integer used_memory from CPMS"								" response\n");						} else {							return foo;						}					}					posi+=laenge+1;					if ( (laenge=strcspn(posi,",\r"))!=0 ) {						foo = str2s(posi,laenge,&err);						if (err) {							LOG(L_ERR,"ERROR:sms_check_memory: unable to"								"convert into integer max_memory from CPMS"								" response\n");						} else {							return foo;						}					}				}			} /* if(strstr) */		} /* if(put_command) */		/* if we are here ->  some error happend */		if (checkmodem(mdm)!=0) {			LOG(L_WARN,"WARNING:sms_check_memory: something happend with the"				" modem -> was reinit -> let's retry\n");		} else {			LOG(L_ERR,"ERROR:sms_check_memory: modem seems to be ok, but we"				"had an error? I give up!\n");			out = 1;		}	} /* for */	if (out==0)		LOG(L_ERR,"ERROR:sms_check_memory: modem does not respond after 10"			"reties! I give up :-(\n");	return -1;}/* splits an ASCII string into the parts *//* returns length of ascii */int splitascii(struct modem *mdm, char *source, struct incame_sms *sms){	char* start;	char* end;	/* the text is after the \r */	for( start=source ; *start && *start!='\r' ; start++ );	if (!*start)		return 1;	start++;	strcpy(sms->ascii,start);	/* get the senders MSISDN */	start=strstr(source,"\",\"");	if (start==0) {		sms->userdatalength=strlen(sms->ascii);		return 1;	}	start+=3;	end=strstr(start,"\",");	if (end==0) {		sms->userdatalength=strlen(sms->ascii);		return 1;	}	*end=0;	strcpy(sms->sender,start);	/* Siemens M20 inserts the senders name between MSISDN and date */	start=end+3;	// Workaround for Thomas Stoeckel //	if (start[0]=='\"')		start++;	if (start[2]!='/')  { // if next is not a date is must be the name		end=strstr(start,"\",");		if (end==0) {			sms->userdatalength=strlen(sms->ascii);			return 1;		}		*end=0;		strcpy(sms->name,start);	}	/* Get the date */	start=end+3;	sprintf(sms->date,"%c%c-%c%c-%c%c",start[3],start[4],start[0],start[1],		start[6],start[7]);	/* Get the time */	start+=9;	sprintf(sms->time,"%c%c:%c%c:%c%c",start[0],start[1],start[3],start[4],		start[7],start[7]);	sms->userdatalength=strlen(sms->ascii);	return 1;}/* Subroutine for splitpdu() for messages type 0 (SMS-Deliver)   Returns the length of the ascii string   In binary mode ascii contains the binary SMS */int split_type_0( char* Pointer,struct incame_sms *sms){	int Length;	int padding;	int is_binary;	Length=octet2bin(Pointer);	padding=Length%2;	Pointer+=4;	memcpy(sms->sender,Pointer,Length+padding);	swapchars(sms->sender,Length+padding);	/* remove Padding characters after swapping */	sms->sender[Length]=0;	Pointer=Pointer+Length+padding+3;	is_binary = ((Pointer[0] & 4)==4);	Pointer++;	set_date(sms->date,Pointer);	Pointer=Pointer+6;	set_time(sms->time,Pointer);	Pointer=Pointer+8;	if (is_binary)		sms->userdatalength = pdu2binary(Pointer,sms->ascii);	else		sms->userdatalength = pdu2ascii(Pointer,sms->ascii);	return 1;}/* Subroutine for splitpdu() for messages type 2 (Staus Report)   Returns the length of the ascii string. In binary mode ascii    contains the binary SMS */int split_type_2( char* position, struct incame_sms *sms){	int  length;	int  padding;	char *p;	/* get from report the sms id */	sms->sms_id = octet2bin(position);	position+=2;	/* get recipient address */	length=octet2bin(position);	padding=length%2;	position+=4;	memcpy(sms->sender,position,length+padding);	sms->sender[length]=0;	swapchars(sms->sender,length);	// get SMSC timestamp	position+=length+padding;	set_date(sms->date,position);	set_time(sms->time,position+6);	// get Discharge timestamp	position+=14;	p = sms->ascii + 2;	set_date(p,position);	*(p+DATE_LEN) = ' ';	set_time(p+DATE_LEN+1,position+6);	// get Status	position+=14;	sms->ascii[0] = (unsigned char)octet2bin(position);	sms->ascii[1] = ' ';	sms->ascii[2+DATE_LEN+1+TIME_LEN] = 0;	sms->userdatalength=2+DATE_LEN+1+TIME_LEN;	return 1;}/* Splits a PDU string into the parts *//* Returns the length of the ascii string. In binary mode ascii contains the binary SMS */int splitpdu(struct modem *mdm, char* pdu, struct incame_sms *sms){	int Length;	int Type;	char* Pointer;	char* start;	char* end;	/* Get the senders Name if given. Depends on the modem. */	start=strstr(pdu,"\",\"");	if (start!=0) {		start+=3;		end=strstr(start,"\",");		if (end!=0) {			memcpy(sms->name,start,end-start);			sms->name[end-start]=0;		}	} else		end=pdu;	/* the pdu is after the first \r */	for( start=end+1 ; *start && *start!='\r' ; start++ );	if (!*start)		return 0;	pdu=++start;	/* removes unwanted ctrl chars at the beginning */	while ( *pdu && (*pdu<=' '))		pdu++;	Pointer=pdu;	if (mdm->mode!=MODE_OLD) {		/* get senders smsc */		Length=octet2bin(pdu)*2-2;		if (Length>0) {			Pointer=pdu+4;			memcpy(sms->smsc,Pointer,Length);			swapchars(sms->smsc,Length);			/* remove Padding characters after swapping */			if (sms->smsc[Length-1]=='F')				sms->smsc[Length-1]=0;			else				sms->smsc[Length] = 0;		}		Pointer=pdu+Length+4;	}	/* is UDH bit set? udh=(octet2bin(Pointer)&4) */	Type=octet2bin(Pointer) & 3;	Pointer+=2;	if (Type==0) {		sms->is_statusreport = 0; /*SMS Deliver*/		return split_type_0( Pointer, sms);	} else if (Type==2) {		sms->is_statusreport = 1; /*Status Report*/		return split_type_2( Pointer, sms);	}	/*Unsupported type*/	return -1;}inline int decode_pdu( struct modem *mdm, char *pdu, struct incame_sms *sms){	int ret;	memset( sms, 0, sizeof(struct incame_sms) );	/* Ok, now we split the PDU string into parts and show it */	if (mdm->mode==MODE_ASCII || mdm->mode==MODE_DIGICOM)		ret = splitascii(mdm, pdu, sms);	else		ret = splitpdu(mdm, pdu, sms);	if (ret==-1) {		LOG(L_ERR,"ERROR:decode_pdu: unable split pdu/ascii!\n");		return -1;	}	return 1;}int getsms( struct incame_sms *sms, struct modem *mdm, int sim){	char   pdu[500];	int    found;	int    ret;	found = fetchsms(mdm,sim,pdu);	if ( !found ) {		LOG(L_ERR,"ERROR:getsms: unable to fetch sms %d!\n",sim);		return -1;	}	/* decode the pdu */	ret = decode_pdu(mdm,pdu,sms);	/* delete the sms*/	deletesms(mdm,found);	return ret;}int cds2sms(struct incame_sms *sms, struct modem *mdm, char *s, int s_len){	char *data;	char *ptr;	char tmp;	int  n;	/* pdu starts after 2 "\r\n" */	ptr = s;	for ( n=0 ; n<2 && (ptr=strstr(ptr,"\r\n")) ; n++,ptr+=2 );	if (n<2) {		LOG(L_ERR,"ERROR:cds2sms: cannot find pdu begining in CDS!\n");		goto error;	}	data = ptr;	/* pdu end with "\r\n" */	if (!(ptr=strstr(data,"\r\n"))) {		LOG(L_ERR,"ERROR:cds2sms: cannot find pdu end in CDS!\n");		goto error;		}	tmp = ptr[0];	ptr[0] = 0;	/* decode the pdu */	n = decode_pdu(mdm,data-3,sms);	ptr[0] = tmp;	if (n==-1)		goto error;	return 1;error:	return -1;}

⌨️ 快捷键说明

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