smsc_at2.c
资源名称:gateway-1.2.1 [点击查看]
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:70k
源码类别:
手机WAP编程
开发平台:
WINDOWS
- /*
- * smsc_at2.c
- *
- * New driver for serial connected AT based
- * devices.
- * 4.9.2001
- * Andreas Fink <afink@smsrelay.com>
- *
- */
- #include <errno.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include <termios.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <sys/ioctl.h>
- #include <time.h>
- #include <math.h>
- #include "gwlib/gwlib.h"
- #include "gwlib/charset.h"
- #include "smscconn.h"
- #include "smscconn_p.h"
- #include "bb_smscconn_cb.h"
- #include "msg.h"
- #include "sms.h"
- #include "dlr.h"
- #include "smsc_at2.h"
- static int at2_open_device1(PrivAT2data *privdata)
- {
- info(0, "AT2[%s]: opening device", octstr_get_cstr(privdata->name));
- privdata->fd = open(octstr_get_cstr(privdata->device),
- O_RDWR | O_NONBLOCK | O_NOCTTY);
- if (privdata->fd == -1) {
- error(errno, "AT2[%s]: open failed! ERRNO=%d", octstr_get_cstr(privdata->name), errno);
- privdata->fd = -1;
- return -1;
- }
- debug("bb.smsc.at2", 0, "AT2[%s]: device opened", octstr_get_cstr(privdata->name));
- return 0;
- }
- int at2_open_device(PrivAT2data *privdata)
- {
- struct termios tios;
- int ret;
- if ((ret = at2_open_device1(privdata)) != 0)
- return ret;
- tcgetattr(privdata->fd, &tios);
- kannel_cfmakeraw(&tios);
- tios.c_iflag |= IGNBRK; /* ignore break & parity errors */
- tios.c_iflag &= ~INPCK; /* INPCK: disable parity check */
- tios.c_cflag |= HUPCL; /* hangup on close */
- tios.c_cflag |= CREAD; /* enable receiver */
- tios.c_cflag &= ~CSIZE; /* set to 8 bit */
- tios.c_cflag |= CS8;
- tios.c_oflag &= ~ONLCR; /* no NL to CR-NL mapping outgoing */
- tios.c_iflag |= IGNPAR; /* ignore parity */
- tios.c_iflag &= ~INPCK;
- tios.c_cflag |= CRTSCTS; /* enable hardware flow control */
- tios.c_cc[VSUSP] = 0; /* otherwhise we can not send CTRL Z */
- /*
- if ( ModemTypes[privdata->modemid].enable_parity )
- tios.c_cflag ^= PARODD;
- */
- ret = tcsetattr(privdata->fd, TCSANOW, &tios); /* apply changes now */
- if (ret == -1) {
- error(errno, "AT2[%s]: at_data_link: fail to set termios attribute",
- octstr_get_cstr(privdata->name));
- }
- tcflush(privdata->fd, TCIOFLUSH);
- /*
- * Nokia 7110 and 6210 need some time between opening
- * the connection and sending the first AT commands
- */
- if (privdata->modem->need_sleep)
- sleep(1);
- debug("bb.smsc.at2", 0, "AT2[%s]: device opened", octstr_get_cstr(privdata->name));
- return 0;
- }
- void at2_close_device(PrivAT2data *privdata)
- {
- info(0, "AT2[%s]: closing device", octstr_get_cstr(privdata->name));
- close(privdata->fd);
- privdata->fd = -1;
- }
- void at2_read_buffer(PrivAT2data *privdata)
- {
- char buf[MAX_READ + 1];
- int s, ret;
- int count;
- fd_set read_fd;
- struct timeval tv;
- if (privdata->fd == -1) {
- error(errno, "AT2[%s]: at2_read_buffer: fd = -1. Can not read",
- octstr_get_cstr(privdata->name));
- return ;
- }
- count = MAX_READ;
- #ifdef SSIZE_MAX
- if (count > SSIZE_MAX)
- count = SSIZE_MAX;
- #endif
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- FD_ZERO(&read_fd);
- FD_SET(privdata->fd, &read_fd);
- ret = select(privdata->fd + 1, &read_fd, NULL, NULL, &tv);
- if (ret == -1) {
- if (!(errno == EINTR || errno == EAGAIN))
- error(errno, "AT2[%s]: error on select", octstr_get_cstr(privdata->name));
- return;
- }
- s = read(privdata->fd, buf, count);
- if (s > 0)
- octstr_append_data(privdata->ilb, buf, s);
- }
- Octstr *at2_wait_line(PrivAT2data *privdata, time_t timeout, int gt_flag)
- {
- Octstr *line;
- time_t end_time;
- time_t cur_time;
- time(&end_time);
- if (timeout == 0)
- timeout = 3;
- end_time += timeout;
- if (privdata->lines != NULL)
- octstr_destroy(privdata->lines);
- privdata->lines = octstr_create("");
- while (time(&cur_time) <= end_time) {
- line = at2_read_line(privdata, gt_flag);
- if (line)
- return line;
- }
- return NULL;
- }
- Octstr *at2_read_line(PrivAT2data *privdata, int gt_flag)
- {
- int eol;
- int gtloc;
- int len;
- Octstr *line;
- Octstr *buf2;
- int i;
- at2_read_buffer(privdata);
- len = octstr_len(privdata->ilb);
- if (len == 0)
- return NULL;
- if (gt_flag)
- /* looking for > if needed */
- gtloc = octstr_search_char(privdata->ilb, '>', 0);
- else
- gtloc = -1;
- /*
- if (gt_flag && (gtloc != -1))
- debug("bb.smsc.at2", 0, "in at2_read_line with gt_flag=1, gtloc=%d, ilb=%s",
- gtloc, octstr_get_cstr(privdata->ilb));
- */
- eol = octstr_search_char(privdata->ilb, 'r', 0); /* looking for CR */
- if ( (gtloc != -1) && ( (eol == -1) || (eol > gtloc) ) )
- eol = gtloc;
- if (eol == -1)
- return NULL;
- line = octstr_copy(privdata->ilb, 0, eol);
- buf2 = octstr_copy(privdata->ilb, eol + 1, len);
- octstr_destroy(privdata->ilb);
- privdata->ilb = buf2;
- /* remove any non printable chars (including linefeed for example) */
- for (i = 0; i < octstr_len(line); i++) {
- if (octstr_get_char(line, i) < 32)
- octstr_set_char(line, i, ' ');
- }
- octstr_strip_blanks(line);
- /* empty line, skipping */
- if ((strcmp(octstr_get_cstr(line), "") == 0) && ( gt_flag == 0))
- {
- octstr_destroy(line);
- return NULL;
- }
- if ((gt_flag) && (gtloc != -1)) {
- /* got to re-add it again as the parser needs to see it */
- octstr_append_cstr(line, ">");
- }
- debug("bb.smsc.at2", 0, "AT2[%s]: <-- %s", octstr_get_cstr(privdata->name),
- octstr_get_cstr(line));
- return line;
- }
- int at2_write_line(PrivAT2data *privdata, char *line)
- {
- int count;
- int s = 0;
- int write_count = 0;
- Octstr *linestr = NULL;
- linestr = octstr_format("%sr", line);
- debug("bb.smsc.at2", 0, "AT2[%s]: --> %s^M", octstr_get_cstr(privdata->name), line);
- count = octstr_len(linestr);
- while (1) {
- errno = 0;
- s = write(privdata->fd, octstr_get_cstr(linestr), count);
- if (s < 0 && errno == EAGAIN && write_count < RETRY_SEND) {
- gwthread_sleep(1);
- ++write_count;
- } else
- break;
- };
- O_DESTROY(linestr);
- if (s < 0) {
- debug("bb.smsc.at2", 0, "AT2[%s]: write failed with errno %d",
- octstr_get_cstr(privdata->name), errno);
- return s;
- }
- tcdrain(privdata->fd);
- gwthread_sleep((double) (privdata->modem == NULL ?
- 100 : privdata->modem->sendline_sleep) / 1000);
- return s;
- }
- int at2_write_ctrlz(PrivAT2data *privdata)
- {
- int s;
- char *ctrlz = "