3 * AT chat library with GLib integration
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include <sys/ioctl.h>
31 #include <linux/if_tun.h>
35 #include "ringbuffer.h"
43 struct ring_buffer *write_buffer;
44 struct ring_buffer *tun_write_buffer;
49 GAtRawIP *g_at_rawip_new(GIOChannel *channel)
54 io = g_at_io_new(channel);
58 rawip = g_at_rawip_new_from_io(io);
65 GAtRawIP *g_at_rawip_new_from_io(GAtIO *io)
69 rawip = g_try_new0(GAtRawIP, 1);
75 rawip->write_buffer = NULL;
76 rawip->tun_write_buffer = NULL;
78 rawip->io = g_at_io_ref(io);
83 GAtRawIP *g_at_rawip_ref(GAtRawIP *rawip)
88 g_atomic_int_inc(&rawip->ref_count);
93 void g_at_rawip_unref(GAtRawIP *rawip)
98 if (g_atomic_int_dec_and_test(&rawip->ref_count) == FALSE)
101 g_at_rawip_shutdown(rawip);
103 g_at_io_unref(rawip->io);
106 g_free(rawip->ifname);
107 rawip->ifname = NULL;
112 static gboolean can_write_data(gpointer data)
114 GAtRawIP *rawip = data;
119 if (rawip->write_buffer == NULL)
122 len = ring_buffer_len_no_wrap(rawip->write_buffer);
123 buf = ring_buffer_read_ptr(rawip->write_buffer, 0);
125 bytes_written = g_at_io_write(rawip->io, (gchar *) buf, len);
126 ring_buffer_drain(rawip->write_buffer, bytes_written);
128 if (ring_buffer_len(rawip->write_buffer) > 0)
131 rawip->write_buffer = NULL;
136 static gboolean tun_write_data(gpointer data)
138 GAtRawIP *rawip = data;
143 if (rawip->tun_write_buffer == NULL)
146 len = ring_buffer_len_no_wrap(rawip->tun_write_buffer);
147 buf = ring_buffer_read_ptr(rawip->tun_write_buffer, 0);
149 bytes_written = g_at_io_write(rawip->tun_io, (gchar *) buf, len);
150 ring_buffer_drain(rawip->tun_write_buffer, bytes_written);
152 if (ring_buffer_len(rawip->tun_write_buffer) > 0)
155 rawip->tun_write_buffer = NULL;
160 static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
162 GAtRawIP *rawip = user_data;
164 rawip->tun_write_buffer = rbuf;
166 g_at_io_set_write_handler(rawip->tun_io, tun_write_data, rawip);
169 static void tun_bytes(struct ring_buffer *rbuf, gpointer user_data)
171 GAtRawIP *rawip = user_data;
173 rawip->write_buffer = rbuf;
175 g_at_io_set_write_handler(rawip->io, can_write_data, rawip);
178 static void create_tun(GAtRawIP *rawip)
184 fd = open("/dev/net/tun", O_RDWR);
188 memset(&ifr, 0, sizeof(ifr));
189 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
190 strcpy(ifr.ifr_name, "gprs%d");
192 err = ioctl(fd, TUNSETIFF, (void *) &ifr);
198 rawip->ifname = g_strdup(ifr.ifr_name);
200 channel = g_io_channel_unix_new(fd);
201 if (channel == NULL) {
206 rawip->tun_io = g_at_io_new(channel);
208 g_io_channel_unref(channel);
211 void g_at_rawip_open(GAtRawIP *rawip)
218 if (rawip->tun_io == NULL)
221 g_at_io_set_read_handler(rawip->io, new_bytes, rawip);
222 g_at_io_set_read_handler(rawip->tun_io, tun_bytes, rawip);
225 void g_at_rawip_shutdown(GAtRawIP *rawip)
230 if (rawip->tun_io == NULL)
233 g_at_io_set_read_handler(rawip->io, NULL, NULL);
234 g_at_io_set_read_handler(rawip->tun_io, NULL, NULL);
236 rawip->write_buffer = NULL;
237 rawip->tun_write_buffer = NULL;
239 g_at_io_unref(rawip->tun_io);
240 rawip->tun_io = NULL;
243 const char *g_at_rawip_get_interface(GAtRawIP *rawip)
248 return rawip->ifname;
251 void g_at_rawip_set_debug(GAtRawIP *rawip, GAtDebugFunc func,
257 rawip->debugf = func;
258 rawip->debug_data = user_data;