免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1270 | 回复: 0
打印 上一主题 下一主题

CDMA短信发送程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-28 07:05 |只看该作者 |倒序浏览
写了一个通过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 }


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/270/showart_238905.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP