From a91863ee834a9b2ebe5cf5da1b0af0cb2bae342d Mon Sep 17 00:00:00 2001 From: short <> Date: Sun, 16 Dec 2001 07:26:34 +0000 Subject: [PATCH 1/1] --picture-send implemented (upon request from jpruett@airlib.com) - currently it has hardcoded size of 72x28=252 bytes (of Nokia 3210) --- mdsms.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 114 insertions(+), 9 deletions(-) diff --git a/mdsms.c b/mdsms.c index bf307b5..686e402 100644 --- a/mdsms.c +++ b/mdsms.c @@ -137,6 +137,8 @@ static char *body; static char *logoname,*gsmnet; /* --ring-send specific */ static char *ringname; +/* --picture-send specific */ +static char *picturename; static enum modenum { MODE_UNKNOWN=0, @@ -146,7 +148,8 @@ static enum modenum { 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_RING_SEND =MODE_FIRST+4 /* --ring-send */ + MODE_RING_SEND =MODE_FIRST+4, /* --ring-send */ + MODE_PICTURE_SEND =MODE_FIRST+5 /* --picture-send */ } mode=MODE_UNKNOWN; #define MODE_ORDER(x) ((x)-MODE_FIRST) #define MODE_NAME(x) (longopts[MODE_ORDER((x))].name) @@ -281,6 +284,8 @@ Usage: %s [-c|--config ] [-d|--device ]\n\ []\n\ --ring-send:\n\ \n\ + --picture-send:\n\ + \n\ \n\ -c, --config\tRead this additional config file\n\ \t\t(def. \"%s\" and \"$HOME%s\")\n\ @@ -339,12 +344,14 @@ static const struct option longopts[]={ {"receive" ,0,0,MODE_RECEIVE}, {"logo-send" ,0,0,MODE_LOGO_SEND}, {"ring-send" ,0,0,MODE_RING_SEND}, +{"picture-send" ,0,0,MODE_PICTURE_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}, +{"picture" ,0,0,MODE_PICTURE_SEND}, {"config" ,1,0,'c'}, {"device" ,1,0,'d'}, {"log" ,1,0,'L'}, @@ -617,6 +624,7 @@ int i; case MODE_RECEIVE: case MODE_LOGO_SEND: case MODE_RING_SEND: + case MODE_PICTURE_SEND: if (mode_stamp && mode_stamp!=seq) break; mode=optc; mode_stamp=seq; @@ -656,8 +664,9 @@ static const struct nullcheck { } nullcheck[]={ {&phone,MODE_BIT(MODE_SEND)|MODE_BIT(MODE_SEND_MOBILDOCK)|MODE_BIT(MODE_LOGO_SEND), N_("destination phone number")}, - {&logoname,MODE_BIT(MODE_LOGO_SEND),N_("logo filename")}, - {&ringname,MODE_BIT(MODE_RING_SEND),N_("ring filename")}, + {& logoname,MODE_BIT( MODE_LOGO_SEND),N_( "logo filename")}, + {& ringname,MODE_BIT( MODE_RING_SEND),N_( "ring filename")}, + {&picturename,MODE_BIT(MODE_PICTURE_SEND),N_("picture filename")}, {&body,MODE_BIT(MODE_RECEIVE),N_("body text")}, /* we allow empty bodies for SENDs */ #if 0 {&gsmnet,MODE_BIT(MODE_LOGO_SEND),N_("GSM operator network code")}, @@ -781,6 +790,12 @@ static inline void cmdline_ring_send(void) if (!ringname) ringname=nextargstack(); } +static inline void cmdline_picture_send(void) +{ + cmdline_phone(); + if (!picturename) picturename=nextargstack(); +} + static void lockclose(int fd) { if (close(fd)) @@ -1239,7 +1254,7 @@ unsigned char bin[140]={ 0x05, /* IEI */ 0x04, /* IEDL */ 0x15, 0x83, /* dest port (group gfx) */ - 0x00, 0x00 /* src port (unused) */ + 0x15, 0x83 /* src port (unused) */ }; size_t got,r=0 /* GCC happiness */,w; ssize_t chars,bits; @@ -1386,6 +1401,91 @@ long size; #undef WORD } +#define PICTURE_WIDTH (72) +#define PICTURE_HEIGHT (28) + +static inline void pictureread(void) +{ +FILE *f; +unsigned char bin1[140]={ + 6, /* UDH length */ + 0x05, /* IEI */ + 0x04, /* IEDL */ + 0x15, 0x8A, /* dest port (ring tones) */ + 0x15, 0x8A /* src port (unused) */ +#define BIN1_PAYLOAD (140-7) + }; +unsigned char binn[140]={ + 11, /* UDH length */ + 0x05, /* IEI */ + 0x04, /* IEDL */ + 0x15, 0x8A, /* dest port (ring tones) */ + 0x15, 0x8A, /* src port (unused) */ + 0x00, 0x03, /* multipart */ + /* 0x??, unique serial ID */ + /* 0x??, total messages */ + /* 0x??, message number (# from 1) */ +#define BINN_PAYLOAD (140-12) + }; +unsigned char header[]={ + 0x30, /* version string '0' */ + 0x02, /* item=OTA bitmap */ +#define PICTURE_BYTES (((PICTURE_WIDTH+7)/8)*PICTURE_HEIGHT) +#define PICTURE_BYTES_INCL_HEADER (PICTURE_BYTES +4/*header*/) + PICTURE_BYTES_INCL_HEADER>>8,PICTURE_BYTES_INCL_HEADER&0xFF, /* picture size in bytes incl. header */ + 0x00, /* animation pictures - 0=static picture */ + PICTURE_WIDTH,PICTURE_HEIGHT, /* picture size in pixels */ + 0x01, /* picture depth - B/W */ + }; +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(picturename,"rb"))) + error(_("^!Cannot open picture file \"%s\" for r/o"),picturename); + if ((size=getfilesize(f,picturename))==-1) + error(_("!File size determination is essential to continue operation")); + if (size!=PICTURE_BYTES) + error(_("!File \"%s\" size %ld doesn't match .res size for %dx%d picture"), + picturename,size,PICTURE_WIDTH,PICTURE_HEIGHT); + if (size<=BIN1_PAYLOAD-sizeof(header)) { + memcpy(bin1+7,header,sizeof(header)); + if ((got=fread(bin1+7+sizeof(header),1,size,f))!=size) + error(_("^Read error on \"%s\", wanted %ld, got %d"),picturename,size,got); + error(_("\nSending picture \"%s\" as single SMS (size %ld, max %d)"), + picturename,size,BIN1_PAYLOAD-sizeof(header)); + nokiaprep(bin1,7+sizeof(header)+size); + } + else { + memcpy(binn+12,header,sizeof(header)); + totn=(sizeof(header)+size+BINN_PAYLOAD-1)/BINN_PAYLOAD; + if (totn>0xFF) + error(_("!File size %ld too large even for multi-SMS picture upload (max=%d)"), + size,BINN_PAYLOAD*0xFF-sizeof(header)); + binn[10]=totn; + if (verbose>=1) + error(_("\nSending picture \"%s\" as %d multi-SMSes (size %ld, max %d, frag %d, header %d)"), + picturename,totn,size,BIN1_PAYLOAD,BINN_PAYLOAD,sizeof(header)); + 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++) { +size_t isheader=(fragn==1 ? sizeof(header) : 0); + + binn[11]=fragn; + want=MIN(size,BINN_PAYLOAD-isheader); + if ((got=fread(binn+12+isheader,1,want,f))!=want) + error(_("^Read error on \"%s\", wanted %d, got %d"),picturename,want,got); + nokiaprep(binn,12+isheader+want); + size-=want; + } + } + chkfclose(f,picturename); +#undef WORD +} + static inline void genpdu(void) { static unsigned char pdu[64+MAXNUMLEN/2+(MAXBODYLEN*7)/8]; @@ -1976,10 +2076,11 @@ char *buf=malloc(l+50); switch (mode) { case MODE_SEND: /* FALLTHRU */ - case MODE_SEND_MOBILDOCK: cmdline_send (); break; - case MODE_LOGO_SEND: cmdline_logo_send(); break; - case MODE_RING_SEND: cmdline_ring_send(); break; - case MODE_RECEIVE: cmdline_receive (); break; + case MODE_SEND_MOBILDOCK: cmdline_send (); break; + case MODE_LOGO_SEND: cmdline_logo_send (); break; + case MODE_RING_SEND: cmdline_ring_send (); break; + case MODE_PICTURE_SEND: cmdline_picture_send(); break; + case MODE_RECEIVE: cmdline_receive (); break; default: assert(0); } cmdline_done(); @@ -2047,6 +2148,9 @@ size_t l=strlen(device); case MODE_RING_SEND: ringread(); break; + case MODE_PICTURE_SEND: + pictureread(); + break; case MODE_RECEIVE: break; default: assert(0); } @@ -2170,7 +2274,8 @@ retryall: } break; case MODE_LOGO_SEND: - case MODE_RING_SEND: { + case MODE_RING_SEND: + case MODE_PICTURE_SEND: { struct hexdata *hd; restore="\r\nAT+CSMP=17,,0,0"; -- 1.8.3.1