From 63b16591b8c4a60d06cb13cb069103eb2619fe12 Mon Sep 17 00:00:00 2001 From: short <> Date: Sun, 31 Oct 1999 15:47:20 +0000 Subject: [PATCH] Initial untested implementation of --ring-send. --- mdsms.1.in | 5 +++ mdsms.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 141 insertions(+), 14 deletions(-) diff --git a/mdsms.1.in b/mdsms.1.in index 43f2226..a6cca96 100644 --- a/mdsms.1.in +++ b/mdsms.1.in @@ -22,6 +22,11 @@ mdsms \- Mobile Device SMS tool .BR "" .RB [ "" ] .br +.BR "mdsms --ring-send" +.RB options... +.BR "" +.BR "" +.br options: .RB [ "-c " ] .RB [ "-d " ] diff --git a/mdsms.c b/mdsms.c index 845c629..849035d 100644 --- a/mdsms.c +++ b/mdsms.c @@ -101,6 +101,8 @@ static size_t bodylen; static char *body; /* --logo-send specific */ static char *logoname,*gsmnet; +/* --ring-send specific */ +static char *ringname; static enum modenum { MODE_UNKNOWN=0, @@ -109,7 +111,8 @@ static enum modenum { MODE_SEND =MODE_FIRST+0, /* --send / --send-mobildock */ MODE_SEND_MOBILDOCK=MODE_FIRST+1, /* --send-mobildock in before readtimen is set */ MODE_RECEIVE =MODE_FIRST+2, /* --receive */ - MODE_LOGO_SEND =MODE_FIRST+3 /* --logo-send */ + MODE_LOGO_SEND =MODE_FIRST+3, /* --logo-send */ + MODE_RING_SEND =MODE_FIRST+4 /* --ring-send */ } mode=MODE_UNKNOWN; #define MODE_ORDER(x) ((x)-MODE_FIRST) #define MODE_NAME(x) (longopts[MODE_ORDER((x))].name) @@ -240,6 +243,8 @@ Usage: " PACKAGE " [-c|--config ] [-d|--device ]\n\ \n\ --logo-send:\n\ []\n\ + --ring-send:\n\ + \n\ \n\ -c, --config\tRead this additional config file\n\ \t\t(def. \"" CONFIG_MAIN "\" and \"$HOME" CONFIG_HOME "\")\n\ @@ -284,10 +289,13 @@ static const struct option longopts[]={ {"send-mobildock",0,0,MODE_SEND_MOBILDOCK}, {"receive" ,0,0,MODE_RECEIVE}, {"logo-send" ,0,0,MODE_LOGO_SEND}, +{"ring-send" ,0,0,MODE_RING_SEND}, /* Mode aliases may follow in no particular order * * as long as no non-mode options is between them */ {"send-md" ,0,0,MODE_SEND_MOBILDOCK}, {"recv" ,0,0,MODE_RECEIVE}, +{"logo" ,0,0,MODE_LOGO_SEND}, +{"ring" ,0,0,MODE_RING_SEND}, {"config" ,1,0,'c'}, {"device" ,1,0,'d'}, {"log" ,1,0,'L'}, @@ -314,6 +322,18 @@ static void chkfclose(FILE *f,const char *fname) error("^Error closing \"%s\"",fname); } +static long getfilesize(FILE *f,const char *fname) +{ +long size; + + if (fseek(f,0,SEEK_END)) + error("^Error seeking to end of \"%s\"",fname); + if ((size=ftell(f))<0) + size=-1,error("^Error measuring \"%s\"",fname); + rewind(f); + return(size); +} + static void readfile(const char *fname,char quiet) { FILE *f; @@ -334,14 +354,10 @@ static unsigned tot=0; } if (verbose>=2) error(".Reading config file \"%s\"",fname); - if (fseek(f,0,SEEK_END)) - error("^Error seeking to end of \"%s\"",fname); - if ((size=ftell(f))<0) - size=0,error("^Error measuring \"%s\"",fname); + if ((size=getfilesize(f,fname))==-1) size=0; if (size>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); if (size && got!=size) error("File \"%s\" read error, got only %u bytes of %ld",fname,got,size); @@ -534,6 +550,7 @@ int i; case MODE_SEND_MOBILDOCK: case MODE_RECEIVE: case MODE_LOGO_SEND: + case MODE_RING_SEND: if (mode_stamp && mode_stamp!=seq) break; mode=optc; mode_stamp=seq; @@ -572,6 +589,7 @@ static const struct nullcheck { {&phone,MODE_BIT(MODE_SEND)|MODE_BIT(MODE_SEND_MOBILDOCK)|MODE_BIT(MODE_LOGO_SEND), "destination phone number"}, {&logoname,MODE_BIT(MODE_LOGO_SEND),"logo filename"}, + {&ringname,MODE_BIT(MODE_RING_SEND),"ring filename"}, {&body,MODE_BIT(MODE_RECEIVE),"body text"}, /* we allow empty bodies for SENDs */ #if 0 {&gsmnet,"GSM operator network code",MODE_LOGO_SEND}, @@ -689,6 +707,12 @@ either \"" WORD_NET "\" or \"" WORD_GROUP "\", but found length %d: %s", } } +static inline void cmdline_ring_send(void) +{ + cmdline_phone(); + if (!ringname) ringname=nextargstack(); +} + static void lockclose(int fd) { if (close(fd)) @@ -946,7 +970,7 @@ skipread: buf[bufl2]='\0'; s=buf+bufl; while (buf+bufl2>s && (s=memchr(s,'\0',buf+bufl2-s))) *s++=REPL_NULLCHAR; - if (verbose>=2) + if (verbose>=3) error("\nGot chunk of data from device: %s",reform(buf+bufl,0)); if (convcr) { s=buf+bufl; @@ -1084,7 +1108,22 @@ static inline unsigned char charconv(char c,size_t offs) */ static char *pdudata; -static char hexdata[140*2+1]; +static struct hexdata { + struct hexdata *next; + char data[140*2+1]; + } *hexdata,**hexdatatail=&hexdata; + +static void nokiaprep(unsigned char *bin,size_t w) +{ +struct hexdata *hd; + assert(w<=140); + chk(hd=malloc(sizeof(*hd))); + *hexdatatail=hd; + hd->next=NULL; + hexdatatail=&hd->next; + textconv(hd->data,bin,w); + if (verbose>=2) error("\nWill send hexdata: %s",hd->data); +} static inline void logoread(void) { @@ -1107,6 +1146,7 @@ int sizex,sizey,bit; if (!(f=fopen(logoname,"rb"))) error("^!Cannot open logo file \"%s\" for r/o",logoname); got=fread(buf,1,sizeof(buf),f); + chkfclose(f,logoname); if (got>=20 && !memcmp(buf,"NOL",4)) { VARPRINTF2(gsmnetf,"%03.3u%02.2u",WORD(6),WORD(8)); assert(strlen(gsmnetf)==5); @@ -1165,9 +1205,79 @@ int sizex,sizey,bit; } w++; } - assert(chars==-1); assert(bits==0); assert(w==got); assert(w<=140); - textconv(hexdata,bin,w); - if (verbose>=2) error("\nWill send hexdata: %s",hexdata); + assert(chars==-1); assert(bits==0); assert(w==got); + nokiaprep(bin,w); +#undef WORD +} + +static inline void ringread(void) +{ +FILE *f; +unsigned char bin1[140]={ + 6, /* UDH length */ + 0x05, /* IEI */ + 0x04, /* IEDL */ + 0x15, 0x81, /* dest port (ring tones) */ + 0x15, 0x81 /* src port (unused) */ +#define BIN1_PAYLOAD (140-7) + }; +unsigned char binn[140]={ + 11, /* UDH length */ + 0x05, /* IEI */ + 0x04, /* IEDL */ + 0x15, 0x81, /* dest port (ring tones) */ + 0x15, 0x81, /* src port (unused) */ + 0x00, 0x03, /* multipart */ + /* 0x??, unique serial ID */ + /* 0x??, total messages */ + /* 0x??, message number (# from 1) */ +#define BINN_PAYLOAD (140-12) + }; +size_t got,want; +int totn,fragn; +long size; + +#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); + if ((size=getfilesize(f,logoname))==-1) + error("!File size is essential to continue operation"); + if (size<0x103) + error("!File \"%s\" size %ld too small (must >=0x103)! Is it .000 file?", + logoname,size); + if (fseek(f,0x100,SEEK_SET)) + error("^Seeking error on \"%s\", ignoring",logoname); + size-=0x100; + if (size<=BIN1_PAYLOAD) { + if ((got=fread(bin1+7,1,size,f))!=size) + error("^Read error on \"%s\", wanted %ld, got %d",logoname,size,got); + error("\nSending ring tone \"%s\" as single SMS (size %ld, max %d)", + ringname,size,BIN1_PAYLOAD); + nokiaprep(bin1,7+size); + } + else { + totn=(size+BINN_PAYLOAD-1)/BINN_PAYLOAD; + if (totn>0xFF) + error("!File size %ld too large for multi-SMS ring upload (max=%d)", + size,BINN_PAYLOAD*0xFF); + binn[10]=totn; + if (verbose>=1) + error("\nSending ring tone \"%s\" as %d multi-SMSes (size %ld, max %d, frag %d)", + ringname,totn,size,BIN1_PAYLOAD,BINN_PAYLOAD); + binn[9]=time(NULL)&0x100; /* rand() would be better but it is a compatibility pain */ + if (verbose>=1) + error("\nUsing unique multi-SMS ID 0x%02X",(unsigned)binn[9]); + for (fragn=1;fragn<=totn;fragn++) { + binn[11]=fragn; + want=MIN(size,BINN_PAYLOAD); + if ((got=fread(binn+12,1,want,f))!=want) + error("^Read error on \"%s\", wanted %d, got %d",logoname,want,got); + nokiaprep(binn,12+want); + size-=want; + } + } + chkfclose(f,logoname); #undef WORD } @@ -1513,7 +1623,7 @@ enum modenum argsmode; for (i=0;i ",NULL,"\r\nAT+CMGS=\"%s\"",phone); - s=devcmd(NULL,"\n+CMGS:","!~%s\032",hexdata); - break; + while ((hd=hexdata)) { + if (!(s=devcmd(NULL,"\n+CMGS:","!~%s\032",hd->data))) break; + hexdata=hd->next; + free(hd); + } + } break; case MODE_RECEIVE: devcmd(NULL,NULL,"\r\nAT+CMGF=1"); restore="\r\nAT+CNMI=,0"; + devcmd(NULL,NULL,"\r\nAT+CSDH=0"); devcmd(NULL,NULL,"\r\nAT+CNMI=,2"); unlockdevice(0); /* Never bail-out when we got up to this point */ -- 1.8.3.1