From 6a78e402d32d2fdc6b60e6269818f264d744e0f0 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Thu, 1 Oct 2009 16:37:30 -0500 Subject: Replace g_at_chat_new_from_tty with g_at_tty_open --- gatchat/gattty.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 gatchat/gattty.c (limited to 'gatchat/gattty.c') diff --git a/gatchat/gattty.c b/gatchat/gattty.c new file mode 100644 index 00000000..c3dcf47b --- /dev/null +++ b/gatchat/gattty.c @@ -0,0 +1,238 @@ +/* + * + * AT chat library with GLib integration + * + * Copyright (C) 2008-2009 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include "gattty.h" + +static gboolean set_baud(const char *baud, struct termios *ti) +{ + speed_t speed; + + if (g_str_equal(baud, "300")) + speed = B300; + else if (g_str_equal(baud, "1200")) + speed = B1200; + else if (g_str_equal(baud, "2400")) + speed = B2400; + else if (g_str_equal(baud, "4800")) + speed = B4800; + else if (g_str_equal(baud, "9600")) + speed = B9600; + else if (g_str_equal(baud, "19200")) + speed = B19200; + else if (g_str_equal(baud, "38400")) + speed = B38400; + else if (g_str_equal(baud, "57600")) + speed = B57600; + else if (g_str_equal(baud, "115200")) + speed = B115200; + else if (g_str_equal(baud, "230400")) + speed = B230400; + else if (g_str_equal(baud, "460800")) + speed = B460800; + else if (g_str_equal(baud, "500000")) + speed = B500000; + else if (g_str_equal(baud, "576000")) + speed = B576000; + else if (g_str_equal(baud, "921600")) + speed = B921600; + else if (g_str_equal(baud, "1000000")) + speed = B1000000; + else if (g_str_equal(baud, "1152000")) + speed = B1152000; + else if (g_str_equal(baud, "1500000")) + speed = B1500000; + else if (g_str_equal(baud, "2000000")) + speed = B2000000; + else if (g_str_equal(baud, "2500000")) + speed = B2500000; + else if (g_str_equal(baud, "3000000")) + speed = B3000000; + else if (g_str_equal(baud, "3500000")) + speed = B3500000; + else if (g_str_equal(baud, "4000000")) + speed = B4000000; + else + return FALSE; + + cfsetospeed(ti, speed); + cfsetispeed(ti, speed); + + return TRUE; +} + +static gboolean set_stop_bits(const char *bits, struct termios *ti) +{ + if (g_str_equal(bits, "1")) + ti->c_cflag &= ~(CSTOPB); + else if (g_str_equal(bits, "2")) + ti->c_cflag |= CSTOPB; + else + return FALSE; + + return TRUE; +} + +static gboolean set_data_bits(const char *bits, struct termios *ti) +{ + if (g_str_equal(bits, "7")) { + ti->c_cflag &= ~(CSIZE); + ti->c_cflag |= CS7; + } else if (g_str_equal(bits, "8")) { + ti->c_cflag &= ~(CSIZE); + ti->c_cflag |= CS8; + } else + return FALSE; + + return TRUE; +} + +static gboolean set_parity(const char *parity, struct termios *ti) +{ + if (g_str_equal(parity, "none")) + ti->c_cflag &= ~(PARENB); + else if (g_str_equal(parity, "even")) { + ti->c_cflag |= PARENB; + ti->c_cflag &= ~(PARODD); + } else if (g_str_equal(parity, "odd")) { + ti->c_cflag |= PARENB; + ti->c_cflag |= PARODD; + } else + return FALSE; + + return TRUE; +} + +static gboolean set_xonxoff(const char *xonxoff, struct termios *ti) +{ + if (g_str_equal(xonxoff, "on")) { + ti->c_iflag |= (IXON | IXOFF | IXANY); + ti->c_cc[VSTART] = 17; + ti->c_cc[VSTOP] = 19; + } else if (g_str_equal(xonxoff, "off")) + ti->c_iflag &= ~(IXON | IXOFF | IXANY); + else + return FALSE; + + return TRUE; +} + +static gboolean set_rtscts(const char *rtscts, struct termios *ti) +{ + if (g_str_equal(rtscts, "on")) + ti->c_cflag |= CRTSCTS; + else if (g_str_equal(rtscts, "off")) + ti->c_cflag &= ~(CRTSCTS); + else + return FALSE; + + return TRUE; +} + +static gboolean set_local(const char *local, struct termios *ti) +{ + if (g_str_equal(local, "on")) + ti->c_cflag |= CLOCAL; + else if (g_str_equal(local, "off")) + ti->c_cflag &= ~(CLOCAL); + else + return FALSE; + + return TRUE; +} + +static int open_device(const char *tty, GHashTable *options) +{ + struct termios ti; + int fd; + + /* Switch TTY to raw mode */ + memset(&ti, 0, sizeof(ti)); + cfmakeraw(&ti); + + if (options) { + GHashTableIter iter; + const char *key; + const char *value; + + g_hash_table_iter_init (&iter, options); + while (g_hash_table_iter_next(&iter, (void *) &key, + (void *) &value)) { + gboolean ok = FALSE; + + if (g_str_equal(key, "baud")) + ok = set_baud(value, &ti); + else if (g_str_equal(key, "stopbits")) + ok = set_stop_bits(value, &ti); + else if (g_str_equal(key, "databits")) + ok = set_data_bits(value, &ti); + else if (g_str_equal(key, "parity")) + ok = set_parity(value, &ti); + else if (g_str_equal(key, "xonxoff")) + ok = set_xonxoff(value, &ti); + else if (g_str_equal(key, "rtscts")) + ok = set_rtscts(value, &ti); + else if (g_str_equal(key, "local")) + ok = set_local(value, &ti); + + if (ok == FALSE) + return -1; + } + } + + fd = open(tty, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (fd < 0) + return -1; + + tcflush(fd, TCIOFLUSH); + tcsetattr(fd, TCSANOW, &ti); + + return fd; +} + +GIOChannel *g_at_tty_open(const char *tty, GHashTable *options) +{ + GIOChannel *channel; + int fd; + + fd = open_device(tty, options); + if (fd < 0) + return NULL; + + channel = g_io_channel_unix_new(fd); + + if (channel == NULL) { + close(fd); + return NULL; + } + + g_io_channel_set_close_on_unref(channel, TRUE); + + return channel; +} -- cgit v1.2.3