summaryrefslogtreecommitdiffstats
path: root/gisi
diff options
context:
space:
mode:
authorRémi Denis-Courmont <remi.denis-courmont@nokia.com>2009-08-19 10:57:37 +0300
committerAki Niemi <aki.niemi@nokia.com>2009-08-19 17:07:16 +0300
commit5b0fffe66a4bebdddc8b8b4ab2b9eb9c8e0a8d89 (patch)
tree4eb69f27a4881d97173d265b9fc6ae3e5e80e242 /gisi
parentcf88062682d915f78a76e013bebe6ee70cc0dcf4 (diff)
downloadofono-5b0fffe66a4bebdddc8b8b4ab2b9eb9c8e0a8d89.tar.bz2
Phonet: GPRS pipe end point low-level support
Diffstat (limited to 'gisi')
-rw-r--r--gisi/Makefile.am1
-rw-r--r--gisi/pep.c120
-rw-r--r--gisi/pep.h28
3 files changed, 149 insertions, 0 deletions
diff --git a/gisi/Makefile.am b/gisi/Makefile.am
index 9987f318..2bd0a33c 100644
--- a/gisi/Makefile.am
+++ b/gisi/Makefile.am
@@ -8,5 +8,6 @@ libgisi_la_SOURCES = \
netlink.h netlink.c \
socket.h socket.c \
client.h client.c \
+ pep.h pep.c \
pipe.h pipe.c
libgisi_la_LIBADD = @GLIB_LIBS@
diff --git a/gisi/pep.c b/gisi/pep.c
new file mode 100644
index 00000000..40efc377
--- /dev/null
+++ b/gisi/pep.c
@@ -0,0 +1,120 @@
+/*
+ * This file is part of oFono - Open Source Telephony
+ *
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
+ *
+ * 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 <config.h>
+#endif
+
+#include <stdint.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <fcntl.h>
+#include <glib.h>
+
+#include "phonet.h"
+#include "socket.h"
+#include "pep.h"
+
+struct _GIsiPEP {
+ int gprs_fd;
+ guint source;
+ uint16_t handle;
+};
+
+
+static gboolean g_isi_pep_callback(GIOChannel *channel, GIOCondition cond,
+ gpointer data)
+
+{
+ GIsiPEP *pep = data;
+ int fd = g_io_channel_unix_get_fd(channel);
+ int encap = PNPIPE_ENCAP_IP;
+ unsigned ifi;
+ socklen_t len = sizeof(ifi);
+
+ if (cond & (G_IO_HUP|G_IO_NVAL))
+ return FALSE;
+
+ fd = accept(fd, NULL, NULL);
+ if (fd == -1)
+ return TRUE;
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+ if (setsockopt(fd, SOL_PNPIPE, PNPIPE_ENCAP, &encap, sizeof(encap))
+ || getsockopt(fd, SOL_PNPIPE, PNPIPE_IFINDEX, &ifi, &len)) {
+ close(fd);
+ return TRUE;
+ }
+ pep->gprs_fd = fd;
+ return FALSE;
+}
+
+GIsiPEP *g_isi_pep_create(GIsiModem *modem)
+{
+ GIsiPEP *pep = g_malloc(sizeof(*pep));
+ GIOChannel *channel;
+ int fd;
+ unsigned ifi = g_isi_modem_index(modem);
+ char buf[IF_NAMESIZE];
+
+ fd = socket(PF_PHONET, SOCK_SEQPACKET|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
+ if (fd == -1)
+ return NULL;
+
+ if (if_indextoname(ifi, buf) == NULL ||
+ setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, buf, IF_NAMESIZE))
+ goto error;
+
+ pep->gprs_fd = -1;
+ pep->handle = 0;
+ if (ioctl(fd, SIOCPNGETOBJECT, &pep->handle) || listen(fd, 1))
+ goto error;
+
+ channel = g_io_channel_unix_new(fd);
+ g_io_channel_set_close_on_unref(channel, TRUE);
+ g_io_channel_set_encoding(channel, NULL, NULL);
+ g_io_channel_set_buffered(channel, FALSE);
+ pep->source = g_io_add_watch(channel,
+ G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
+ g_isi_pep_callback, pep);
+ g_io_channel_unref(channel);
+ return pep;
+error:
+ close(fd);
+ g_free(pep);
+ return NULL;
+}
+
+uint16_t g_isi_pep_get_object(const GIsiPEP *pep)
+{
+ return pep->handle;
+}
+
+void g_isi_pep_destroy(GIsiPEP *pep)
+{
+ if (pep->gprs_fd != -1)
+ close(pep->gprs_fd);
+ else
+ g_source_remove(pep->source);
+ g_free(pep);
+}
diff --git a/gisi/pep.h b/gisi/pep.h
new file mode 100644
index 00000000..7de5bf61
--- /dev/null
+++ b/gisi/pep.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of oFono - Open Source Telephony
+ *
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
+ *
+ * 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
+ *
+ */
+
+typedef struct _GIsiPEP GIsiPEP;
+
+GIsiPEP *g_isi_pep_create(GIsiModem *modem);
+void g_isi_pep_destroy(GIsiPEP *pep);
+uint16_t g_isi_pep_get_object(const GIsiPEP *pep);