⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smsc_at.c

📁 gateway-1.3.2.tar.gz WAP gw code
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 Kannel Group   * Copyright (c) 1998-2001 WapIT Ltd.    * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Kannel Group (http://www.kannel.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Kannel" and "Kannel Group" must not be used to  *    endorse or promote products derived from this software without  *    prior written permission. For written permission, please   *    contact org@kannel.org.  *  * 5. Products derived from this software may not be called "Kannel",  *    nor may "Kannel" appear in their name, without prior written  *    permission of the Kannel Group.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Kannel Group.  For more information on   * the Kannel Group, please see <http://www.kannel.org/>.  *  * Portions of this software are based upon software originally written at   * WapIT Ltd., Helsinki, Finland for the Kannel project.   */ /* * smsc_at.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_at.h"static int at2_open_device1(PrivAT2data *privdata){    info(0, "AT2[%s]: opening device", octstr_get_cstr(privdata->name));    if (privdata->fd > 0) {        warning(0, "AT2[%s]: trying to open device with not closed device!!! Please report!!!",                 octstr_get_cstr(privdata->name));        at2_close_device(privdata);    }    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;    privdata->pin_ready = 0;    privdata->phase2plus = 0;    if (privdata->ilb != NULL)        octstr_destroy(privdata->ilb);    privdata->ilb = octstr_create("");}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, data_written = 0;    Octstr *linestr = NULL;    linestr = octstr_format("%s\r", line);    debug("bb.smsc.at2", 0, "AT2[%s]: --> %s^M", octstr_get_cstr(privdata->name), line);    count = octstr_len(linestr);    while (count > data_written) {	errno = 0;	s = write(privdata->fd, octstr_get_cstr(linestr) + data_written, count - data_written);	if (s < 0 && errno == EAGAIN && write_count < RETRY_SEND) {	    gwthread_sleep(1);	    ++write_count;        } else if (s > 0) {            data_written += s;            write_count = 0;	} else	    break;    };    O_DESTROY(linestr);    if (s < 0) {        error(errno, "AT2[%s]: Couldnot write to device.",               octstr_get_cstr(privdata->name));        tcflush(privdata->fd, TCOFLUSH);        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 = "\032" ;    int write_count = 0;        debug("bb.smsc.at2", 0, "AT2[%s]: --> ^Z", octstr_get_cstr(privdata->name));    while (1) {	errno = 0;	s = write(privdata->fd, ctrlz, 1);	if (s < 0 && errno == EAGAIN && write_count < RETRY_SEND) {	    gwthread_sleep(1);	    ++write_count;	} else	    break;    };    if (s < 0) {        error(errno, "AT2[%s]: Couldnot write to device.",               octstr_get_cstr(privdata->name));        tcflush(privdata->fd, TCOFLUSH);        return s;    }    tcdrain(privdata->fd);    gwthread_sleep((double) (privdata->modem == NULL ?        100 : privdata->modem->sendline_sleep) / 1000);    return s;}      int at2_write(PrivAT2data *privdata, char *line){    int count, data_written = 0, write_count = 0;    int s = 0;    debug("bb.smsc.at2", 0, "AT2[%s]: --> %s", octstr_get_cstr(privdata->name), line);    count = strlen(line);    while(count > data_written) {        s = write(privdata->fd, line + data_written, count - data_written);        if (s < 0 && errno == EAGAIN && write_count < RETRY_SEND) {            gwthread_sleep(1);            ++write_count;        } else if (s > 0) {            data_written += s;            write_count = 0;        } else            break;    }    if (s < 0) {        error(errno, "AT2[%s]: Couldnot write to device.",              octstr_get_cstr(privdata->name));        tcflush(privdata->fd, TCOFLUSH);        return s;    }    tcdrain(privdata->fd);    gwthread_sleep((double) (privdata->modem == NULL ?        100 : privdata->modem->sendline_sleep) / 1000);    return s;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -