~awe/phablet-extras/ofono-nettime-plugin

1.1.1 by Andres Salomon
Import upstream version 0.4
1
/*
1.3.1 by Jonny Lamb
Import upstream version 0.36
2
 *
3
 *  oFono - Open Source Telephony
4
 *
1.4.2 by Hector Oron
Import upstream version 1.6
5
 *  Copyright (C) 2009-2010  Nokia Corporation and/or its subsidiary(-ies).
1.3.1 by Jonny Lamb
Import upstream version 0.36
6
 *
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.
10
 *
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.
15
 *
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
1.1.1 by Andres Salomon
Import upstream version 0.4
19
 *
20
 */
21
22
#ifdef HAVE_CONFIG_H
23
#include <config.h>
24
#endif
25
26
#include <stdint.h>
27
#include <sys/ioctl.h>
28
#include <net/if.h>
29
#include <fcntl.h>
30
#include <unistd.h>
31
#include <glib.h>
32
33
#include "phonet.h"
34
#include "socket.h"
35
#include "pep.h"
36
37
struct _GIsiPEP {
38
	GIsiPEPCallback ready;
39
	void *opaque;
40
	int gprs_fd;
41
	guint source;
42
	uint16_t handle;
43
};
44
45
46
static gboolean g_isi_pep_callback(GIOChannel *channel, GIOCondition cond,
47
					gpointer data)
48
49
{
50
	GIsiPEP *pep = data;
51
	int fd = g_io_channel_unix_get_fd(channel);
52
	int encap = PNPIPE_ENCAP_IP;
53
54
	if (cond & (G_IO_HUP|G_IO_NVAL))
55
		return FALSE;
56
57
	fd = accept(fd, NULL, NULL);
58
	if (fd == -1)
59
		return TRUE;
60
	fcntl(fd, F_SETFD, FD_CLOEXEC);
61
62
	if (setsockopt(fd, SOL_PNPIPE, PNPIPE_ENCAP, &encap, sizeof(encap))) {
63
		close(fd);
64
		return TRUE;
65
	}
66
	pep->gprs_fd = fd;
1.2.5 by Sebastien Bacher
Import upstream version 0.23
67
1.4.1 by Jonny Lamb
Import upstream version 0.53
68
	if (pep->ready != NULL)
1.2.5 by Sebastien Bacher
Import upstream version 0.23
69
		pep->ready(pep, pep->opaque);
70
1.1.1 by Andres Salomon
Import upstream version 0.4
71
	return FALSE;
72
}
73
74
GIsiPEP *g_isi_pep_create(GIsiModem *modem, GIsiPEPCallback cb, void *opaque)
75
{
1.2.4 by Chris Coulson
Import upstream version 0.20
76
	unsigned ifi = g_isi_modem_index(modem);
77
	GIsiPEP *pep = NULL;
1.1.1 by Andres Salomon
Import upstream version 0.4
78
	GIOChannel *channel;
79
	int fd;
80
	char buf[IF_NAMESIZE];
81
82
	fd = socket(PF_PHONET, SOCK_SEQPACKET, 0);
83
	if (fd == -1)
84
		return NULL;
85
86
	fcntl(fd, F_SETFD, FD_CLOEXEC);
87
	fcntl(fd, F_SETFL, O_NONBLOCK|fcntl(fd, F_GETFL));
88
1.2.4 by Chris Coulson
Import upstream version 0.20
89
	if (if_indextoname(ifi, buf) == NULL)
90
		goto error;
91
92
	if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, buf, IF_NAMESIZE) != 0)
93
		goto error;
94
95
	pep = g_try_malloc(sizeof(GIsiPEP));
96
	if (pep == NULL)
1.1.1 by Andres Salomon
Import upstream version 0.4
97
		goto error;
98
99
	pep->ready = cb;
100
	pep->opaque = opaque;
101
	pep->gprs_fd = -1;
102
	pep->handle = 0;
1.2.4 by Chris Coulson
Import upstream version 0.20
103
1.1.1 by Andres Salomon
Import upstream version 0.4
104
	if (listen(fd, 1) || ioctl(fd, SIOCPNGETOBJECT, &pep->handle))
105
		goto error;
106
107
	channel = g_io_channel_unix_new(fd);
108
	g_io_channel_set_close_on_unref(channel, TRUE);
109
	g_io_channel_set_encoding(channel, NULL, NULL);
110
	g_io_channel_set_buffered(channel, FALSE);
111
	pep->source = g_io_add_watch(channel,
112
					G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
113
					g_isi_pep_callback, pep);
114
	g_io_channel_unref(channel);
1.2.4 by Chris Coulson
Import upstream version 0.20
115
1.1.1 by Andres Salomon
Import upstream version 0.4
116
	return pep;
1.2.4 by Chris Coulson
Import upstream version 0.20
117
1.1.1 by Andres Salomon
Import upstream version 0.4
118
error:
119
	close(fd);
120
	g_free(pep);
121
	return NULL;
122
}
123
124
uint16_t g_isi_pep_get_object(const GIsiPEP *pep)
125
{
126
	return pep->handle;
127
}
128
129
void g_isi_pep_destroy(GIsiPEP *pep)
130
{
131
	if (pep->gprs_fd != -1)
132
		close(pep->gprs_fd);
133
	else
134
		g_source_remove(pep->source);
135
	g_free(pep);
136
}
137
138
unsigned g_isi_pep_get_ifindex(const GIsiPEP *pep)
139
{
140
	unsigned ifi;
1.2.3 by Andres Salomon
Import upstream version 0.18
141
	socklen_t len = sizeof(ifi);
1.1.1 by Andres Salomon
Import upstream version 0.4
142
1.2.3 by Andres Salomon
Import upstream version 0.18
143
	g_assert(pep->gprs_fd != -1);
1.1.1 by Andres Salomon
Import upstream version 0.4
144
145
	getsockopt(pep->gprs_fd, SOL_PNPIPE, PNPIPE_IFINDEX, &ifi, &len);
146
	return ifi;
147
}
148
149
char *g_isi_pep_get_ifname(const GIsiPEP *pep, char *ifname)
150
{
1.3.1 by Jonny Lamb
Import upstream version 0.36
151
	if (pep->gprs_fd == -1)
152
		return NULL;
153
154
	return if_indextoname(g_isi_pep_get_ifindex(pep), ifname);
1.1.1 by Andres Salomon
Import upstream version 0.4
155
}