00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <sys/types.h>
00016 #include <sys/stat.h>
00017 #include <fcntl.h>
00018 #include <termios.h>
00019 #include <stdio.h>
00020 #include <string.h>
00021 #include <unistd.h>
00022 #include <syslog.h>
00023 #include "sms_funcs.h"
00024 #include "libsms_charset.h"
00025 #include "libsms_modem.h"
00026
00027
00028 int sms_report_type;
00029
00030 static char hexa[16] = {
00031 '0','1','2','3','4','5','6','7',
00032 '8','9','A','B','C','D','E','F'
00033 };
00034
00035
00036 void swapchars(char* string, int len)
00037 {
00038 int position;
00039 char c;
00040
00041 for (position=0; position<len-1; position+=2)
00042 {
00043 c=string[position];
00044 string[position]=string[position+1];
00045 string[position+1]=c;
00046 }
00047 }
00048
00049
00050
00051
00052
00053
00054 int ascii2pdu(char* ascii, int asciiLength, char* pdu, int cs_convert)
00055 {
00056 static char tmp[500];
00057 int pdubitposition=0;
00058 int pdubyteposition=0;
00059 int character;
00060 int bit;
00061 int pdubitnr;
00062 char converted;
00063 unsigned char foo;
00064
00065 memset(tmp,0,asciiLength);
00066 for (character=0;character<asciiLength;character++)
00067 {
00068 if (cs_convert)
00069 converted=ascii2sms(ascii[character]);
00070 else
00071 converted=ascii[character];
00072 for (bit=0;bit<7;bit++)
00073 {
00074 pdubitnr=7*character+bit;
00075 pdubyteposition=pdubitnr/8;
00076 pdubitposition=pdubitnr%8;
00077 if (converted & (1<<bit))
00078 tmp[pdubyteposition]=tmp[pdubyteposition]|(1<<pdubitposition);
00079 else
00080 tmp[pdubyteposition]=tmp[pdubyteposition]&~(1<<pdubitposition);
00081 }
00082 }
00083 tmp[pdubyteposition+1]=0;
00084 for (character=0;character<=pdubyteposition; character++)
00085 {
00086 foo = tmp[character] ;
00087 pdu[2*character ] = hexa[foo>>4];
00088 pdu[2*character+1] = hexa[foo&0x0f];
00089 }
00090 pdu[2*(pdubyteposition+1)]=0;
00091 return 2*(pdubyteposition+1);
00092 }
00093
00094
00095
00096
00097
00098 int binary2pdu(char* binary, int length, char* pdu)
00099 {
00100 int character;
00101 unsigned char foo;
00102
00103 for (character=0;character<length; character++)
00104 {
00105 foo = binary[character];
00106 pdu[2*character ] = hexa[foo>>4];
00107 pdu[2*character+1] = hexa[foo&0x0f];
00108 }
00109 pdu[2*length]=0;
00110 return 2*length;
00111 }
00112
00113
00114
00115
00116
00117 int make_pdu(struct sms_msg *msg, struct modem *mdm, char* pdu)
00118 {
00119 int coding;
00120 int flags;
00121 char tmp[500];
00122 int pdu_len=0;
00123 int foo;
00124
00125 memcpy(tmp,msg->to.s,msg->to.len);
00126 foo = msg->to.len;
00127 tmp[foo] = 0;
00128
00129 if ( foo%2 ) {
00130 tmp[foo]='F';
00131 tmp[++foo] = 0;
00132 }
00133
00134 swapchars(tmp,foo);
00135 flags = 0x01;
00136 if (sms_report_type!=NO_REPORT)
00137 flags |= 0x20 ;
00138 coding=240+1;
00139 if (mdm->mode!=MODE_OLD)
00140 flags+=16;
00141
00142 if (mdm->mode==MODE_OLD)
00143 pdu_len += sprintf(pdu,"%02X00%02X91%s00%02X%02X",flags,
00144 msg->to.len,tmp,coding,msg->text.len);
00145 else
00146 pdu_len += sprintf(pdu,"00%02X00%02X91%s00%02XA7%02X",flags,
00147 msg->to.len,tmp,coding,msg->text.len);
00148
00149
00150 pdu_len += ascii2pdu(msg->text.s,msg->text.len,pdu+pdu_len,1);
00151
00152 return pdu_len;
00153 }
00154
00155
00156
00157
00158
00159 inline int fetch_sms_id(char *answer)
00160 {
00161 char *p;
00162 int id;
00163
00164 p = strstr(answer,"+CMGS:");
00165 if (!p)
00166 goto error;
00167 p += 6;
00168
00169 while(p && *p && (*p==' ' || *p=='\r' || *p=='\n'))
00170 p++;
00171 if (*p<'0' || *p>'9')
00172 goto error;
00173
00174 id = 0;
00175 while (p && *p>='0' && *p<='9')
00176 id = id*10 + *(p++)-'0';
00177
00178 return id;
00179 error:
00180 return -1;
00181 }
00182
00183
00184
00185
00186
00187 int putsms( struct sms_msg *sms_messg, struct modem *mdm)
00188 {
00189 char command[500];
00190 char command2[500];
00191 char answer[500];
00192 char pdu[500];
00193 int clen,clen2;
00194 int retries;
00195 int err_code;
00196 int pdu_len;
00197 int sms_id;
00198
00199 pdu_len = make_pdu(sms_messg, mdm, pdu);
00200 if (mdm->mode==MODE_OLD)
00201 clen = sprintf(command,"AT+CMGS=%i\r",pdu_len/2);
00202 else if (mdm->mode==MODE_ASCII)
00203 clen = sprintf(command,"AT+CMGS=\"+%.*s\"\r",sms_messg->to.len,
00204 sms_messg->to.s);
00205 else
00206 clen = sprintf(command,"AT+CMGS=%i\r",pdu_len/2-1);
00207
00208 if (mdm->mode==MODE_ASCII)
00209 clen2=sprintf(command2,"%.*s\x1A",sms_messg->text.len,
00210 sms_messg->text.s);
00211 else
00212 clen2=sprintf(command2,"%.*s\x1A",pdu_len,pdu);
00213
00214 sms_id = 0;
00215 for(err_code=0,retries=0;err_code<2 && retries<mdm->retry; retries++)
00216 {
00217 if (put_command(mdm,command,clen,answer,sizeof(answer),50,"\r\n> ")
00218 && put_command(mdm,command2,clen2,answer,sizeof(answer),1000,0)
00219 && strstr(answer,"OK") )
00220 {
00221
00222 err_code = 2;
00223
00224
00225 if (sms_report_type!=NO_REPORT) {
00226 sms_id = fetch_sms_id(answer);
00227 if (sms_id==-1)
00228 err_code = 1;
00229 }
00230 } else {
00231
00232 if (checkmodem(mdm)==-1) {
00233 err_code = 0;
00234 LM_WARN("resending last sms! \n");
00235 } else if (err_code==0) {
00236 LM_WARN("possible corrupted sms. Let's try again!\n");
00237 err_code = 1;
00238 }else {
00239 LM_ERR("We have a FUBAR sms!! drop it!\n");
00240 err_code = 3;
00241 }
00242 }
00243 }
00244
00245 if (err_code==0)
00246 LM_WARN("something spooky is going on with the modem!"
00247 " Re-inited and re-tried for %d times without success!\n",
00248 mdm->retry);
00249 return (err_code==0?-2:(err_code==2?sms_id:-1));
00250 }
00251