1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
/*******************************************************************************
* libproxy - A library for proxy configuration
* Copyright (C) 2006 Nathaniel McCallum <nathaniel@natemccallum.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
#include <stdint.h> // For uint32_t
#include "../extension_network.hpp"
using namespace libproxy;
#include <dbus/dbus.h>
#include <NetworkManager.h>
// Backwards compatibility: with the switch to libnm, NM_STATE_CONNECTED is no
// longer defined. NM_STATE_CONNECTED_GLOBAL appeared with NM 0.9 and was aliased
#ifndef NM_STATE_CONNECTED
#define NM_STATE_CONNECTED NM_STATE_CONNECTED_GLOBAL
#endif
class networkmanager_network_extension : public network_extension {
public:
networkmanager_network_extension() {
this->conn = NULL;
}
~networkmanager_network_extension() {
if (this->conn) dbus_connection_close(this->conn);
}
bool changed() {
// Make sure we have a valid connection with a proper match
DBusConnection *conn = this->conn;
if (!conn || !dbus_connection_get_is_connected(conn))
{
// If the connection was disconnected,
// close it an clear the queue
if (conn)
{
dbus_connection_close(conn);
dbus_connection_read_write(conn, 0);
for (DBusMessage *msg=NULL ; (msg = dbus_connection_pop_message(conn)) ; dbus_message_unref(msg)) {};
}
// Create a new connections
conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);
this->conn = conn;
if (!conn) return false;
// If connection was successful, set it up
dbus_connection_set_exit_on_disconnect(conn, false);
dbus_bus_add_match(conn, "type='signal',interface='" NM_DBUS_INTERFACE "',member='StateChanged'", NULL);
dbus_connection_flush(conn);
}
// We are guaranteed a connection,
// so check for incoming messages
bool changed = false;
while (true)
{
DBusMessage *msg = NULL;
uint32_t state;
// Pull messages off the queue
dbus_connection_read_write(conn, 0);
if (!(msg = dbus_connection_pop_message(conn)))
break;
// If a message is the right type and value,
// we'll reset the network
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
if (state == NM_STATE_CONNECTED)
changed = true;
dbus_message_unref(msg);
}
return changed;
}
private:
DBusConnection *conn;
};
MM_MODULE_INIT_EZ(networkmanager_network_extension, true, NULL, NULL);
|