From 5b0fffe66a4bebdddc8b8b4ab2b9eb9c8e0a8d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Wed, 19 Aug 2009 10:57:37 +0300 Subject: [PATCH] Phonet: GPRS pipe end point low-level support --- gisi/Makefile.am | 1 + gisi/pep.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++ gisi/pep.h | 28 +++++++++++ 3 files changed, 149 insertions(+) create mode 100644 gisi/pep.c create mode 100644 gisi/pep.h 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 + * + * 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 + +#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 + * + * 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);