金笛工业手机论坛  

返回   金笛工业手机论坛 > 开发者乐园 > 短信开发资料

短信开发资料 短信开发技巧,代码分析

回复
 
LinkBack 主题工具 显示模式
旧 2012-08-25   #1 (permalink)
论坛管理员
 
admin 的头像
 
注册日期: 2009-06-30
帖子: 861
admin 的声望功能已被禁用
默认 CDMA短信发送程序

CDMA短信发送程序

写了一个通过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 }
__________________

让世界倾听我们的笛声
admin 当前离线   回复时引用此帖
回复

书签


当前查看此主题的会员: 1 (0 位会员和 1 位游客)
 

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛禁用 HTML 代码
Trackbacks are 启用
Pingbacks are 启用
Refbacks are 启用



所有时间均为北京时间。现在的时间是 19:42


Powered by vBulletin® 版本 3.8.3
版权所有 ©2000 - 2024,Jelsoft Enterprises Ltd.