DOC

SMS cdma

By Jane Rodriguez,2014-09-13 16:00
8 views 0
SMS 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;

     1

    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:

     2

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)

     3

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:

     4

    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

     5

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);

     6

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 }

     7

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 }

     8

346

    347 return (outbufsiz - outbytesleft); /*output encode length*/ 348 }

     9

Report this document

For any questions or suggestions please email
cust-service@docsford.com