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