X-Git-Url: http://git.jankratochvil.net/?p=mdsms.git;a=blobdiff_plain;f=mdsms.c;h=69cc8c309dfde46c9f6ccf94b593453012cadb2e;hp=48eb8f5df8b523d6260d23d1ee7b5ed339c4b147;hb=dd88e90f890966720ad6d393f17bfb81782a6e93;hpb=25f8b04f0bb7af6a2bb1b73d50762de53b87663c diff --git a/mdsms.c b/mdsms.c index 48eb8f5..69cc8c3 100644 --- a/mdsms.c +++ b/mdsms.c @@ -3,19 +3,6 @@ static char rcsid[] ATTR_UNUSED = "$Id$"; #endif -/* - * $Log$ - * Revision 1.3 1999/06/03 11:46:41 short - * Logging (--log) implemented. - * - * Revision 1.2 1999/06/03 10:38:52 short - * Implemented remaining communication timeouts and maximum retry count. - * - * Revision 1.1.1.1 1999/05/26 13:06:26 short - * First alpha release. - * - */ - #include "setup.h" #include @@ -42,14 +29,6 @@ static char rcsid[] ATTR_UNUSED = "$Id$"; #include "getopt.h" #endif -#if 0 -char *strdup(const char *s); -int kill(pid_t pid,int sig); -int snprintf(char *str,size_t n,const char *format,...); -int vsnprintf(char *str,size_t n,const char *format,va_list ap); -void usleep(unsigned long usec); -#endif - #define NELEM(x) (sizeof((x))/sizeof(*(x))) #ifndef DEBUG @@ -66,7 +45,7 @@ void usleep(unsigned long usec); #define d3(n1,n2,n3) dB((dO,n1,n2,n3 )) #define d4(n1,n2,n3,n4) dB((dO,n1,n2,n3,n4)) -static const char version[]="This is MobilDock SMS sender (" PACKAGE " " VERSION ")\n"; +static const char version[]="This is Nokia 9110 logo SMS sender (" PACKAGE " " VERSION ")\n"; static int verbose #ifdef DEBUG @@ -76,23 +55,18 @@ static int verbose static char *pname; static int dis_cleanup=0,devfd=-1; -static char *phone,*body,*device,*logname,*lockfile,*smsc,*maxretry,*readtime,*chartime,*cmdtime; -static int readbody; -static long maxretryn=DEF_MAXRETRY,readtimen=DEF_READTIME,chartimen=DEF_CHARTIME,cmdtimen=DEF_CMDTIME; -static size_t bodylen; +static char *phone,*logoname,*device,*logname,*lockfile,*smsc,*maxretry,*readtime,*chartime,*cmdtime,*baud,*gsmnet; +static long maxretryn=DEF_MAXRETRY,readtimen=DEF_READTIME,chartimen=DEF_CHARTIME,cmdtimen=DEF_CMDTIME,baudn=DEF_BAUD; static char *devicename; /* path stripped */ static char lockreal[512],locked; -static struct termios restios; +static struct termios restios,tios; static char restios_yes; static FILE *logf; -static void vlogmsg( -#ifndef PRINTF_WORKS_PM - char outerr, -#endif - const char *fmt,va_list ap) +static void vlogmsg(char outerr, const char *fmt,va_list ap) ATTR_PRINTFORMAT(2,0); +static void vlogmsg(char outerr, const char *fmt,va_list ap) { time_t stamp; char *ctm,*s; @@ -109,68 +83,37 @@ char host[LINE_MAX]; if ((s=strchr(ctm,'\n'))) *s='\0'; fprintf(logf,"%s %s %s[%d]: ",ctm,host,pname,mypid); vfprintf(logf,fmt,ap); -#ifndef PRINTF_WORKS_PM if (outerr) fputs(strerror(errno),logf); -#endif fputc('\n',logf); fflush(logf); } +static void logmsg(const char *fmt,...) ATTR_PRINTFORMAT(1,2); static void logmsg(const char *fmt,...) { va_list ap; va_start(ap,fmt); - vlogmsg( -#ifndef PRINTF_WORKS_PM - 0, -#endif - fmt,ap); + vlogmsg(0,fmt,ap); va_end(ap); } +static void error(const char *fmt,...) ATTR_PRINTFORMAT(1,2); static void error(const char *fmt,...) { va_list ap; -char fatal=*fmt; -#ifndef PRINTF_WORKS_PM -char pm,*nfmt; -size_t fmtl; -#endif +char fatal,pm; + if ((pm=(*fmt=='^'))) fmt++; + fatal=*fmt; if (fatal=='!' || fatal=='.' || fatal=='\n') fmt++; else fatal=0; -#ifndef PRINTF_WORKS_PM - if (!(nfmt=strdup(fmt))) return; - fmtl=strlen(fmt); - if ((pm=(fmtl>=2 && !strcmp(fmt+fmtl-2,"%m")))) nfmt[fmtl-2]='\0'; -#endif - fprintf(stderr,"%s: ",pname); va_start(ap,fmt); - vfprintf(stderr, -#ifdef PRINTF_WORKS_PM - fmt -#else - nfmt -#endif - ,ap); - if (fatal=='!') vlogmsg( -#ifdef PRINTF_WORKS_PM - fmt -#else - pm,nfmt -#endif - ,ap); + vfprintf(stderr,fmt,ap); + if (fatal=='!') vlogmsg(pm,fmt,ap); va_end(ap); - -#ifndef PRINTF_WORKS_PM - if (pm) { - fputs(strerror(errno),stderr); - free(nfmt); - } -#endif - + if (pm) { fputs(": ",stderr); fputs(strerror(errno),stderr); } if (fatal!='\n') fputc((fatal=='.'?'.':'!'),stderr); fputc('\n',stderr); if (fatal=='!') exit(EXIT_FAILURE); @@ -188,13 +131,13 @@ static void cleanup(void) if (dis_cleanup) return; if (restios_yes) { if (tcsetattr(devfd,TCSANOW,&restios)) - error("Error restoring termios for device: %m"); + error("^Error restoring termios for device"); restios_yes=0; } if (locked && *lockreal) { d2("Removing lockfile \"%s\"\n",lockreal); if (unlink(lockreal)) - error("Error removing my device lockfile \"%s\": %m",lockreal); + error("^Error removing my device lockfile \"%s\"",lockreal); locked=0; } dis_cleanup=1; @@ -208,42 +151,45 @@ static void usage(void) %s\ \n\ Usage: " PACKAGE " [-c|--config ] [-d|--device ]\n\ - [-L|--log ]\n\ + [-L|--log ] [-b|--baud ]\n\ [-l|--lockfile ] [-s|--smsc ] [-m|--maxretry <#>]\n\ [-r|--readtime ] [-t|--chartime ] [-T|--cmdtime ]\n\ - [-f|--file] [-v|--verbose] [-h|--help] [-V|--version]\n\ - \n\ + [-v|--verbose] [-h|--help] [-V|--version]\n\ + []\n\ \n\ -c, --config\tRead this additional config file\n\ \t\t(def. \"" CONFIG_MAIN "\" and \"$HOME" CONFIG_HOME "\")\n\ - -d, --device\tMobilDock on this serial device (def. \"" DEF_DEVICE "\")\n\ + -d, --device\tNokia on this serial device (def. \"" DEF_DEVICE "\")\n\ -L, --log\tLog all important messages to this file (def. \"" DEF_LOGNAME "\")\n\ + -b, --baud\tSet baudrate, 2400-57600 supported (def. %d)\n\ -l, --lockfile\tLock serial port by this file, \"%%s\" is basename of device\n\ \t\t(def. \"%s\")\n\ - -s, --smsc\tUse this SMS Center number (def. query from Siemens A1)\n\ + -s, --smsc\tUse this SMS Center number (def. query from Nokia 9110)\n\ -m, --maxretry\tMaximum retries of any command before giving up (def. %d)\n\ -r, --readtime\tSeconds for maximum wait time for response (def. %ds)\n\ - -t, --chartime\tMilliseconds between each char on baud 19200 (def. %dms)\n\ + -t, --chartime\tMilliseconds between each char (def. %dms)\n\ -T, --cmdtime\tMilliseconds before each whole AT command (def. %dms)\n\ - -f, --file\tRead contents of message from file instead\n\ -v, --verbose\tIncrease verbosity level, more \"-v\"s give more messages\n\ -h, --help\tPrint a summary of the options\n\ -V, --version\tPrint the version number\n\ -\n",version,DEF_LOCKFILE,DEF_MAXRETRY,DEF_READTIME,DEF_CHARTIME,DEF_CMDTIME); + \t* Oper. logo: Enter custom network code MccMnc, e.g. 23002\n\ +\t\t* Oper. logo: Specify \"" WORD_NET "\" to read network code from NOL file\n\ +\t\t* Group gfx : Specify \"" WORD_GROUP "\" to send logo as group graphics\n\ +\n",version,DEF_BAUD,DEF_LOCKFILE,DEF_MAXRETRY,DEF_READTIME,DEF_CHARTIME,DEF_CMDTIME); exit(EXIT_FAILURE); } static const struct option longopts[]={ {"config" ,1,0,'c'}, {"device" ,1,0,'d'}, -{"log" ,1,0,'l'}, +{"log" ,1,0,'L'}, +{"baud" ,1,0,'b'}, {"lockfile",1,0,'l'}, {"smsc" ,1,0,'s'}, {"maxretry",1,0,'m'}, {"readtime",1,0,'r'}, {"chartime",1,0,'t'}, {"cmdtime" ,1,0,'T'}, -{"file" ,0,0,'f'}, {"verbose" ,0,0,'v'}, {"help" ,0,0,'h'}, {"version" ,0,0,'V'}}; @@ -256,7 +202,7 @@ static unsigned cfgstacki=0; static void chkfclose(FILE *f,const char *fname) { if (fclose(f)) - error("Error closing \"%s\": %m",fname); + error("^Error closing \"%s\"",fname); } static void readfile(const char *fname,char quiet) @@ -274,16 +220,16 @@ static unsigned tot=0; return; } if (!(f=fopen(fname,"rt"))) { - if (!quiet) error("Can't open config file \"%s\" for r/o: %m",fname); + if (!quiet) error("^Can't open config file \"%s\" for r/o",fname); return; } if (verbose>=2) error(".Reading config file \"%s\"",fname); if (fseek(f,0,SEEK_END)) - error("Error seeking to end of \"s\": %m",fname); + error("^Error seeking to end of \"%s\"",fname); if ((size=ftell(f))<0) - size=0,error("Error measuring \"%s\": %m",fname); + size=0,error("^Error measuring \"%s\"",fname); if (size>MAXCONFIG) - error("File \"%s\" is too long, read only %ld bytes",fname,MAXCONFIG); + error("File \"%s\" is too long, read only %d bytes",fname,MAXCONFIG); chk(buf=malloc((size?size:MAXCONFIG)+1)); rewind(f); got=fread(buf,1,(size?size:MAXCONFIG),f); @@ -332,6 +278,7 @@ static struct { } optset[]={ { 'd',&device }, { 'L',&logname }, + { 'b',&baud }, { 'l',&lockfile }, { 's',&smsc }, { 'm',&maxretry }, @@ -348,15 +295,15 @@ int i; seq++; optarg=NULL; optind=0; /* FIXME: Possible portability problem. */ - while ((optc=getopt_long(argp,args,"c:d:L:l:s:m:r:t:T:fvhV",longopts,NULL))!=EOF) switch (optc) { + while ((optc=getopt_long(argp,args,"c:d:L:b:l:s:m:r:t:T:fvhV",longopts,NULL))!=EOF) switch (optc) { case 'c': if (cfgstacki>=NELEM(cfgstack)) { - error("Looping (%d) during attempt to read config file \"%s\", break-out",NELEM(cfgstack),optind); + error("Looping (%d) during attempt to read config file \"%s\", break-out",NELEM(cfgstack),from); break; } chk(cfgstack[cfgstacki++]=strdup(optarg)); break; - case 'd': case 'L': case 'l': case 's': case 'm': case 'r': case 't': case 'T': + case 'd': case 'L': case 'b': case 'l': case 's': case 'm': case 'r': case 't': case 'T': for (i=0;i=1) error("Timed out"); } @@ -498,7 +477,7 @@ static void blocking(char yes) static char state=-1; if (state==yes) return; if (fcntl(devfd,F_SETFL,(yes?0:O_NONBLOCK))) - error("!fcntl() on device for %sblocking mode: %m",(yes?"":"non-")); + error("^!fcntl() on device for %sblocking mode",(yes?"":"non-")); state=yes; } @@ -528,10 +507,11 @@ void *p; static int retrycnt=0; static void retrying(void) { - if (++retrycnt>maxretryn) error("!Maximum command retry count (%d) exceeded",maxretryn); - if (verbose>=2) error(".Retrying phase, %d out of %d..",retrycnt,maxretryn); + if (++retrycnt>maxretryn) error("!Maximum command retry count (%ld) exceeded",maxretryn); + if (verbose>=2) error(".Retrying phase, %d out of %ld..",retrycnt,maxretryn); } +static char *devcmd(const char *term,const char *catch,const char *send,...) ATTR_PRINTFORMAT(3,4); static char *devcmd(const char *term,const char *catch,const char *send,...) { size_t l,bufl,terml,catchl,fragl,offs; @@ -560,15 +540,15 @@ err: alarm(MAXSENDTIME); usleep((offs?chartimen:cmdtimen)*1000); if (!offs && tcflush(devfd,TCIOFLUSH)) - error("Error flushing I/O queue of device: %m"); + error("^Error flushing I/O queue of device"); if (write(devfd,buf+offs,1)!=1) break; got++; if (tcdrain(devfd)) - error("Error forcing output of char %d of cmd \"%s\": %m",offs,buf); + error("^Error forcing output of char %d of cmd \"%s\"",offs,buf); } alarm(0); if (got!=bufl) { - error("Wrote only %d of %d bytes of command: %m",got,bufl); + error("^Wrote only %d of %d bytes of command",got,bufl); goto err; } @@ -596,8 +576,8 @@ err: got=read(devfd,buf+bufl,1); } if (got<=0) { - if (wasalarm) error("!Maximum response timeout (%ds) exceeded",readtimen); - error("Couldn't read device data (ret=%d): %m",got); + if (wasalarm) error("Maximum response timeout (%lds) exceeded",readtimen); + else error("^Couldn't read device data (ret=%d)",got); goto err; } s=buf+bufl; @@ -638,29 +618,6 @@ err: return(catchdata); } -static int prepaddr(unsigned char *d,const char *addr) -{ -int tot=0; -char flip=0,plus; -unsigned char n; - - if ((plus=(*addr=='+'))) addr++; - *++d=(plus?ADDR_INT:ADDR_NAT); - while (*addr) { - if (*addr<'0' || *addr>'9') - error("!Error during conversion of number at: %s",addr); - tot++; - n=(*addr++)-'0'; - if ((flip=!flip)) *++d=0xF0|n; - else *d=(*d&0x0F)|(n<<4U); - } - return(tot); -} - -static char *finalsmsc; -#define SMSCBINSIZE (1+1+(MAXNUMLEN+1)/2) -static char pdusmsc[SMSCBINSIZE*2+1]; - static inline char tohex(unsigned char x) { x&=0x0F; @@ -668,7 +625,7 @@ static inline char tohex(unsigned char x) return(x-10+'A'); } -static void textconv(char *d,unsigned char *s,size_t len) +static inline void textconv(char *d,unsigned char *s,size_t len) { while (len--) { *d++=tohex(*s>>4U); @@ -682,14 +639,13 @@ static inline void smscset(void) { char *s,*t,*e,*serr; long l; -unsigned char bin[2+(MAXNUMLEN+1)/2]; if (smsc) devcmd(NULL,NULL,"\r\nAT+CSCA=\"%s\"",smsc); s=devcmd(NULL,"\n+CSCA:","\r\nAT+CSCA?"); while (isspace(*s)) s++; if (!*s || !strcmp(s,"EMPTY")) - error("!No SMS set in A1 found"); - if (verbose>=1) error("\nFound default SMSC in A1: %s",s); + error("!No SMS set in Nokia found"); + if (verbose>=1) error("\nFound default SMSC in Nokia: %s",s); if (*s!='"') error("!No left-quote found in: %s",s); if (!(t=strrchr(s+1,'"'))) error("!No right-quote found in: %s",s); e=t++; @@ -702,72 +658,101 @@ unsigned char bin[2+(MAXNUMLEN+1)/2]; if (l==ADDR_NAT || s[1]=='+') s++; else *s='+'; *e='\0'; - chk(finalsmsc=strdup(s)); - if (verbose>=2) error("\nDecoded SMSC address: %s",finalsmsc); - bin[0]=1+(prepaddr(bin,finalsmsc)+1)/2; - textconv(pdusmsc,bin,bin[0]+1); + if (verbose>=2) error("\nDecoded SMSC address: %s",s); } -static char *pdudata; +/* Logo format shamelessly stolen from GNokii-0.3.0: http://www.gnokii.org/ + * Beware - Nokia Smart Messaging specification 1.0.0 and 2.0.0 is incompatible + * with Nokia current product line implementation + * http://www.forum.nokia.com/developers/smartmsg/download/ssm2_0_0.pdf + */ -static inline unsigned char charconv(char c,size_t offs) -{ - if ((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9')) return(c); - switch (c) { - case '@': return(0); - case '$': return(2); - case '"': return(96); - case ' ': - return(c); - case 0: assert(0); - } - error("Can't convert character '%c' (0x%02X) at offs %d (0-based), substituted '?'", - c,(unsigned char)c,offs); - return('?'); -} +static char hexdata[140*2+1]; -static inline void genpdu(void) +static inline void logoread(void) { -static unsigned char pdu[64+MAXNUMLEN/2+(MAXBODYLEN*7)/8]; -unsigned char *d=pdu; -int i; -char inb=0,outb=0,xb; -unsigned char inreg; -size_t offs=0; - - *d++=PDU_TYPE; - *d++=PDU_MR; - i=prepaddr(d,phone); - *d=i; d+=1+1+(i+1)/2; - *d++=PDU_PID; - *d++=PDU_DCS; - *d++=PDU_VP; - if (bodylen>MAXBODYLEN) { - error("Body too large (%d>%d), cut",bodylen,MAXBODYLEN); - bodylen=MAXBODYLEN; - } - *d=bodylen; - assert(d0); assert(!!*body); - inreg=charconv(*body++,offs++); - bodylen--; - inb=7; - } - if (!outb) { - *++d=0x00; - outb=8; +FILE *f; +char buf[32+140*8+1]; +unsigned char bin[140]={ + 0x06, /* UDH length */ + 0x05, /* IEI */ + 0x04, /* IEDL */ + 0x15, 0x83, /* dest port (group gfx) */ + 0x00, 0x00 /* src port (unused) */ + }; +size_t got,r,w; +ssize_t chars,bits; +char gsmnetf[10]; +int sizex,sizey,bit; + +#define WORD(n) (((unsigned char)buf[(n)])|(((unsigned char)buf[(n)+1])<<8)) + + if (!(f=fopen(logoname,"rb"))) + error("^!Cannot open logo file \"%s\" for r/o",logoname); + got=fread(buf,1,sizeof(buf),f); + if (got>=20 && !memcmp(buf,"NOL",4)) { + VARPRINTF2(gsmnetf,"%03.3u%02.2u",WORD(6),WORD(8)); + assert(strlen(gsmnetf)==5); + r=10; + if (verbose>=1) error(".Reading NOL file \"%s\", GSMnet \"%s\", word@4=%d..", + logoname,gsmnetf,WORD(4)); + } + else if (got>=16 && !memcmp(buf,"NGG",4)) { + r=6; + if (verbose>=1) error(".Reading NGG file \"%s\", word@4=%d..", + logoname,WORD(4)); + } + else error("!Unknown file format of logo file \"%s\"",logoname); + if (!strcasecmp(gsmnet,WORD_NET)) { + if (!*gsmnetf) error("!NOL network code detection requested but NOL file not loaded, please specify network code"); + gsmnet=gsmnetf; + } + if (!strcasecmp(gsmnet,WORD_GROUP) || !*gsmnet) { + error("\nSending logo as: group graphics"); + gsmnet=NULL; + } + else { + error("\nSending logo as: operator logo for \"%s\"",gsmnet); + bin[4]=0x82; /* dest port 0x1582 */ + } + + sizex=WORD(r); sizey=WORD(r+2); + if (verbose>=2) error(".Magic words: @+4=%d, @+6=%d, @+8=%d", + WORD(r+4),WORD(r+6),WORD(r+8)); + r+=10; + if (sizex<1 || sizex>255 + || sizey<1 || sizey>255) error("!Invalid size: %dx%d",sizex,sizey); + chars=((bits=sizex*sizey)+7)/8; + if (r+bits>got) error("!Logo file \"%s\" too short - actual=%d, need(%dx%d)=%d", + logoname,got,sizex,sizey,r+chars); + else if (r+bits=1) error("Ignoring trailing garbage in \"%s\", used only %d bytes",logoname,r+bits); + if ((got=(7+(gsmnet?3:0)+4+chars))>140) + error("!SMS size would be %d bytes but 140 is maximum",got); + w=7; + if (gsmnet) { + bin[w++]=((gsmnet[1]&0x0F)<<4)|(gsmnet[0]&0x0F); + bin[w++]=0xF0 |(gsmnet[2]&0x0F); + bin[w++]=((gsmnet[4]&0x0F)<<4)|(gsmnet[3]&0x0F); + } + bin[w++]=0x00; /* RFU by Nokia */ + bin[w++]=sizex; bin[w++]=sizey; + bin[w++]=0x01; /* one B/W plane */ + while (chars--) { + bin[w]=0; + for (bit=0x80;(bits>0) && (bit>0);bits--,bit>>=1) { + if (buf[r]!='0' && buf[r]!='1') + error("!Invalid character (neither '0' nor '1')in logo file \"%s\" at offset 0x%X", + logoname,r); + if (buf[r++]=='1') bin[w]|=bit; } - xb=MIN(inb,outb); - d4("inb=%d,outb=%d,xb=%d\n",inb,outb,xb); - *d|=((inreg>>(unsigned)(7-inb))&((1<=2) error("\nWill send hexdata: %s",hexdata); + +#undef WORD } static struct { @@ -779,15 +764,15 @@ static struct { { &readtime,&readtimen,"readtime" }, { &chartime,&chartimen,"chartime" }, { &cmdtime ,&cmdtimen ,"cmdtime" }, + { &baud ,&baudn ,"baud" }, }; int main(int argc,char **argv) { -char *s,*finame; -FILE *fin; +char *s; int i; unsigned fatal=0; -struct termios tios; +speed_t portbaud; if ((s=strrchr((pname=*argv),'/'))) pname=s+1; atexit(cleanup); @@ -821,24 +806,7 @@ char *buf=malloc(l+50); if (!logname) logname=DEF_LOGNAME; if (!lockfile) lockfile=DEF_LOCKFILE; if (!device) device=DEF_DEVICE; - if (body && readbody) { - finame=body; - body=NULL; - } - else fin=stdin; - if (!body) { - readbody=0; - if (verbose>=1) - error("\nPlease enter the SMS text body, end with EOF (ctrl-D):"); - chk(body=malloc(BODYLOAD)); - bodylen=fread(body,1,BODYLOAD,fin); - if (bodylen==-1) - error("!Error reading stream \"%s\": %m",(finame?finame:"")); - } - if (fin!=stdin) { - chkfclose(fin,finame); - free(finame); - } + logoread(); for (i=0;i=2) error(".Will use baudrate %ld with hexval 0x%X",baudn,portbaud); if (lockfile && *lockfile && VARPRINTF(lockreal,lockfile,devicename)>0) { time_t start,end; @@ -883,39 +861,47 @@ time_t start,end; lockdevice(); time(&end); if ((end-=start)>LOCKREPORT) - logmsg("Device lock succeeded after %d seconds",end); + logmsg("Device lock succeeded after %ld seconds",(long)end); } if (verbose>=1) error(".Opening device \"%s\"..",device); if ((devfd=open(device,O_RDWR|O_NDELAY))<0) - error("!Cannot open device \"%s\" for rw-access: %m",device); + error("^!Cannot open device \"%s\" for rw-access",device); if (tcgetattr(devfd,&restios)) - error("Unable to get termios settings: %m"); + error("^Unable to get termios settings"); else { restios.c_cflag=(restios.c_cflag&~(CBAUD|CBAUDEX))|B0|HUPCL; restios_yes=1; } tios.c_iflag=IGNBRK|IGNPAR|IXON|IXOFF; tios.c_oflag=0; - tios.c_cflag=CS8|CREAD|CLOCAL|B19200|HUPCL; + tios.c_cflag=CS8|CREAD|CLOCAL|HUPCL|portbaud; tios.c_lflag=IEXTEN|NOFLSH; memset(tios.c_cc,_POSIX_VDISABLE,sizeof(tios.c_cc)); tios.c_cc[VTIME]=0; tios.c_cc[VMIN ]=1; + cfsetispeed(&tios,portbaud); + if (cfsetospeed(&tios,portbaud)|cfsetispeed(&tios,portbaud)) + error("^Error setting termios baudrate on device"); if (tcflush(devfd,TCIOFLUSH)) - error("Error flushing termios (TCIOFLUSH) on device: %m"); + error("^Error flushing termios (TCIOFLUSH) on device"); if (tcsetattr(devfd,TCSANOW,&tios)) - error("!Unable to set initial termios device settings"); + error("^!Unable to set initial termios device settings"); - signal(SIGALRM,(RETSIGTYPE (*)(int))sigalarm); + setalarm(); do { - devcmd("",NULL,"\r\nAT\x1A"); + devcmd("",NULL,"\r\nAT\033"); devcmd(NULL,NULL,"\r\nAT"); smscset(); - devcmd(NULL,NULL,"\r\nAT+CMGF=0"); - devcmd("\n> ",NULL,"\r\nAT+CMGS=%d",(strlen(pdusmsc)+strlen(pdudata))/2); - if (!(s=devcmd(NULL,"\n+CMGS:","!%s%s\x1A",pdusmsc,pdudata))) retrying(); - } while (!s); + devcmd(NULL,NULL,"\r\nAT+CSMP=81,,0,245"); + devcmd("\n> ",NULL,"\r\nAT+CMGS=\"%s\"",phone); + if (!(s=devcmd(NULL,"\n+CMGS:","!%s\032",hexdata))) { + retrying(); + continue; + } + devcmd(NULL,NULL,"\r\nAT+CSMP=17,,0,0"); + devcmd(NULL,NULL,"\r\nAT"); + } while (0); while (isspace(*s)) s++; if (verbose>=1) error("\nMessage successfuly sent with MR: %s",s); devcmd(NULL,NULL,"\r\nAT");