文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>CDMA短信发送程序

CDMA短信发送程序

时间:2007-01-28  来源:rockins

写了一个通过CDMA Modem发送短信的小程序,在桌面环境和嵌入式环境下测试通过。涉及到的内容有:串口编程、termios有关的终端IO设置、modem的设置、AT指令集的运用、GB2312字符集向UNICODE字符集编码的转换。测试所用的短信内容为:welcome to 成电。测试结果良好。程序中有关字符集编码转换的三个函数iconv_open()、iconv()、iconv_close()请参见GNU的文档;有关终端IO请参见《UNIX环境高级编程》;有关AT指令集的部分请参见WAVECOM公司的《CDMA AT command interface specification v1.78》。  

1 /*
  2 * $file:    cdmasms_en.c
  3 * $auth:    rockins
  4 * $desc:    send English SMS via CDMA modem
  5 * $date:    Sun Jan 21 04:41:20 CST 2007
  6 */
  7 #include <stdio.h>
  8 #include <stdlib.h>
  9 #include <errno.h>
 10 #include <sys/types.h>
 11 #include <sys/stat.h>
 12 #include <fcntl.h>
 13 #include <termios.h>
 14 #include <iconv.h>
 15 #include <unistd.h>
 16
 17 #define    CTRL_Z    "\x00\x1A"            /*finish sms input*/
 18 #define    CTRL_Z_LEN    2                /*length of CTRL_Z*/
 19 #define    ESC        "\x00\x1B"            /*abort sms input*/
 20 #define    ESC_LEN        2                /*length of ESC*/
 21 #define    CR        '\r'                /*carriage return*/
 22 #define    NL        '\n'                /*next line*/
 23 #define    ST_REP    "+CDS"                /*sms-status-report*/
 24
 25 #define    SERIAL    "/dev/ttyS1"        /*serial port*/
 26 #define    MAX_SZ    1024                /*buffer size*/
 27 #define    SMS_LEN    140                    /*max length of sms*/
 28 #define    RETRY    20                    /*retry time*/
 29
 30 static int CDMAGB2312toUNICODEBIG(char *in,
 31         size_t instrlen, char *out, size_t outbufsiz);
 32
 33 int
 34 main(int argc, char *argv[])
 35 {
 36     int CDMAFd;
 37     int err = 0;
 38     /*GB2312 message: welcome to 成电*/
 39     char message[] = "\x77\x65\x6C\x63\x6F\x6D\x65"
 40                     "\x20\x74\x6F\x20\xB3\xC9\xB5\xE7";
 41     
 42     /*check command-line*/
 43     if (argc != 3) {
 44         printf("usage:%s tel sms\n", argv[0]);
 45         printf("sms must be in English\n");
 46         exit(-1);
 47     }
 48
 49     CDMAFd= CDMAOpenModem(SERIAL);
 50     if (CDMAFd < 0) {
 51         printf("open CDMA Modem %s failed!\n", SERIAL);
 52         return (-1);
 53     }
 54
 55     err = CDMASetModemParams(CDMAFd);
 56     if (err < 0)
 57         goto fail;
 58
 59     err = CDMAInitModem(CDMAFd);
 60     if (err < 0)
 61         goto fail;
 62
 63     err = CDMASendSMS(CDMAFd, argv[1], message);
 64     if (err < 0)
 65         goto fail;
 66
 67     CDMACloseModem(CDMAFd);
 68     printf("send Chinese(Unicode) SMS success!\n");
 69     return (0);
 70
 71 fail:
 72     CDMACloseModem(CDMAFd);
 73     printf("send Chinese(Unicode) SMS failed!\n");
 74     return (-1);
 75 }
 76
 77 /*
 78 * open CDMA Modem device
 79 * params:
 80 *         CDMADevice:    device namde
 81 * returns:
 82 *         non-negtive file descriptor if success,
 83 *         else -1
 84 */
 85 int
 86 CDMAOpenModem(char *CDMADevice)
 87 {
 88     int fd;
 89
 90     /*
 91      * open CDMA serial port, O_NOCTTY means it's
 92      * not a controll tty device, O_NDELAY means
 93      * it's not block
 94      */
 95     fd = open(CDMADevice, O_RDWR | O_NOCTTY);
 96     if (fd < 0) {
 97         perror("open()");
 98         return (-1);
 99     }
100     return (fd);
101 }
102
103 /*
104 * close modem
105 */
106 int
107 CDMACloseModem(int CDMAFd)
108 {
109     return (close(CDMAFd));
110 }
111
112 /*
113 * establish working settings
114 * params:
115 *         CDMAFd:    file descriptor of CDMA modem
116 * returns:
117 *         0 if set success, else -1
118 * note(default setting):
119 *         speed:        115200 bps
120 *         databit:    8 bits
121 *         parity:        none
122 *         stopbit:    1 bit
123 */
124 int
125 CDMASetModemParams(int CDMAFd)
126 {
127     struct termios    term_opt;
128
129     /*
130      * get current attributes
131      */
132     tcgetattr(CDMAFd, &term_opt);
133
134     /*
135      * set attribute to 8N1
136      */
137     term_opt.c_cflag &= ~CSIZE;
138     term_opt.c_cflag |= CS8;        /*8 bit databit*/
139     term_opt.c_cflag &= ~PARENB;    /*disable parity*/
140     term_opt.c_cflag &= ~CSTOPB;    /*set 1 bit stopbit*/
141
142     /*
143      * set in&out serial port speed to 115200 bps
144      */
145     cfsetispeed(&term_opt, B115200);
146     cfsetospeed(&term_opt, B115200);
147
148     /*
149      * set to raw mode
150      */
151     cfmakeraw(&term_opt);
152
153     /*
154      * set reading timeout to 5 seconds
155      */
156     term_opt.c_cc[VMIN] = 0;
157     term_opt.c_cc[VTIME] = 100;        /*timeout: 10 seconds*/
158
159     /*
160      * make new attr be committed
161      */
162     tcsetattr(CDMAFd, TCSANOW, &term_opt);
163 }
164
165 /*
166 * check if CDMA work correctly?
167 * params:
168 *         CDMAFd:    the file descritor of CDMA Modem
169 * returns:
170 *         0 if work healthy,else -1
171 * note:
172 *         according AT command manual, if send "AT" to DCE and
173 *         it response "OK", then can treat the device is
174 *         working correctly.
175 */
176 int
177 CDMAInitModem(int CDMAFd)
178 {
179     unsigned char cmd_buf[MAX_SZ];
180     int retry;
181     int len;
182     
183     /*flush data received and transimitted*/
184     tcflush(CDMAFd, TCIOFLUSH);
185
186     /*issue AT command*/
187     memset(cmd_buf, 0, MAX_SZ);
188     strncpy(cmd_buf, "AT\r", MAX_SZ);
189     len = write(CDMAFd, cmd_buf, strnlen(cmd_buf, MAX_SZ));
190     if (len != strnlen(cmd_buf, MAX_SZ)) {
191         perror("write()");
192         return (-1);
193     }
194
195     for (retry = 0; retry < RETRY; retry++) {
196         /*wait for 1 second*/
197         sleep(1);
198         
199         memset(cmd_buf, 0, MAX_SZ);
200         if ((len = read(CDMAFd, cmd_buf, MAX_SZ)) < 0) {
201             perror("read()");
202             continue;
203         }
204         
205         if (strstr(cmd_buf, "OK"))
206             return (0);
207     }
208
209     return (-1);
210 }
211
212 /*
213 * send SMS via the CDMA modem
214 * params:
215 *         CDMAFd:    file descriptor
216 *         msg:    message to send
217 * returns:
218 *         0 if success, else -1
219 * note:
220 *         message must be in TEXT mode,
221 *         CDMA do not support PDU mode as GSM does.
222 *         tel must be 13xxxxxxxxx format, no +prefix,
223 *         message should be pure English words.
224 */
225 int
226 CDMASendSMS(int CDMAFd, char *phone, char *msg)
227 {
228     char buf[MAX_SZ];            /*command and response buffer*/
229     int len;                    /*length written*/
230     int cmd_len;                /*AT command's length*/
231     char *msg_p;                /*point to msg*/
232     int msg_len;                /*msg's length, in bytes*/
233     char conv_buf[MAX_SZ];        /*buff for encode conversion*/
234     int conv_len;        /*converted msg's length*/
235     int retry;            /*retry time*/
236
237     /* AT+CMGF=1\r set in TEXT mode, whereas AT+CMGF=0\r
238      * is PDU mode, which is not supported by CDMA*/
239     memset(buf, 0, MAX_SZ);
240     cmd_len = snprintf(buf, MAX_SZ, "AT+CMGF=1\r");
241     len = write(CDMAFd, buf, cmd_len);
242     if (len != cmd_len) {
243         perror("write()");
244         return (-1);
245     }
246
247     /*set language and encoding: 6,4 means Chinese,unicode*/
248     memset(buf, 0, MAX_SZ);
249     cmd_len = snprintf(buf, MAX_SZ, "AT+WSCL=6,4\r");
250     len = write(CDMAFd, buf, cmd_len);
251     if (len != cmd_len) {
252         perror("write()");
253         return (-1);
254     }
255
256     /*convert from GB2312 to UNICODE*/
257     msg_len = strnlen(msg, MAX_SZ);
258     memset(conv_buf, 0, MAX_SZ);
259     if ((conv_len = CDMAGB2312toUNICODEBIG(msg, msg_len,
260                             conv_buf, MAX_SZ)) < 0) {
261         printf("convert encoding failed!\n");
262         return (-1);
263     }
264
265     if (conv_len> SMS_LEN) {
266         printf("too long SMS,SMS must not be more than"
267                 " 140 English words or 70 Chinese words\n");
268         return (-1);
269     }
270
271     /*send message*/
272     memset(buf, 0, MAX_SZ);
273     cmd_len = snprintf(buf, MAX_SZ, "AT+CMGS=\"%s\",%d\r",
274                 phone, conv_len);
275     msg_p = buf + cmd_len;
276     memcpy(msg_p, conv_buf, conv_len);
277     msg_p = buf + cmd_len + conv_len;
278
279     /*below is critical area*/
280     memcpy(msg_p, CTRL_Z, CTRL_Z_LEN);
281     len = write(CDMAFd, buf, cmd_len + conv_len + CTRL_Z_LEN);
282     if (len != (cmd_len + conv_len + CTRL_Z_LEN)) {
283         perror("write()");
284         return (-1);
285     }
286
287     /*waiting for acknowledge from the SMS center*/
288     for (retry = 0; retry < RETRY; retry++) {
289         /*wait for 1 second*/
290         sleep(1);
291
292         len = 0;
293         memset(buf, 0, MAX_SZ);
294         if ((len = read(CDMAFd, buf, MAX_SZ)) > 0) {
295             printf("%s\n", buf);
296
297             /*positive acknoledge*/
298             if (strstr(buf, ST_REP))
299                 return (0);
300         }
301     }
302
303     return (-1);
304 }
305
306 /*
307 * convert GB2312 to UNICODE
308 * params:
309 *         in:        input GB2312 string
310 *         instrlen:    input bytes number
311 *         out:    output UNICODE big-endian string
312 *         outbufsiz:    output buffer's size
313 * returns:
314 *         if success return output encoding's
315 *         length in byte; else return -1
316 */
317 static int
318 CDMAGB2312toUNICODEBIG(char *in, size_t instrlen,
319         char *out, size_t outbufsiz)
320 {
321     char *in_p = in;
322     char *out_p = out;
323     size_t inbytesleft = instrlen;
324     size_t outbytesleft = outbufsiz;
325     size_t err = 0;
326     iconv_t cd;
327
328     cd = iconv_open("UNICODEBIG", "GB2312");
329     if (cd == (iconv_t)(-1)) {
330         perror("iconv_open()");
331         return (-1);
332     }
333
334     err = iconv(cd, &in_p, &inbytesleft,
335             &out_p, &outbytesleft);
336     if (err == (size_t)(-1)) {
337         perror("iconv()");
338         return (-1);
339     }
340
341     err = iconv_close(cd);
342     if (err == -1) {
343         perror("iconv_close()");
344         return (-1);
345     }
346
347     return (outbufsiz - outbytesleft);    /*output encode length*/
348 }

相关阅读 更多 +
排行榜 更多 +
大武道最新版

大武道最新版

休闲益智 下载
宝宝巴士手机版(babybus)

宝宝巴士手机版(babybus)

休闲益智 下载
宝宝巴士快乐启蒙游戏

宝宝巴士快乐启蒙游戏

休闲益智 下载