1
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
3
* Dan Williams <dcbw@redhat.com>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
* (C) Copyright 2004 Red Hat, Inc.
27
#include <glib/gi18n.h>
31
#include <dbus/dbus.h>
32
#include <dbus/dbus-glib-lowlevel.h>
34
#include "applet-dbus.h"
35
#include "applet-dbus-devices.h"
36
#include "applet-dbus-vpn.h"
37
#include "applet-dbus-info.h"
38
#include "vpn-connection.h"
39
#include "passphrase-dialog.h"
42
#define DBUS_NO_SERVICE_ERROR "org.freedesktop.DBus.Error.ServiceDoesNotExist"
49
static DBusHandlerResult nma_dbus_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
51
NMApplet *applet = (NMApplet *)user_data;
52
gboolean handled = TRUE;
54
const char * object_path;
56
const char * interface;
58
g_return_val_if_fail (applet != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
59
g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
60
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
62
if (!(object_path = dbus_message_get_path (message)))
64
if (!(member = dbus_message_get_member (message)))
66
if (!(interface = dbus_message_get_interface (message)))
69
/* nm_info ("signal(): got signal op='%s' member='%s' interface='%s'", object_path, member, interface); */
71
if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
73
dbus_connection_unref (applet->connection);
74
applet->connection = NULL;
75
nma_set_running (applet, FALSE);
76
if (!applet->connection_timeout_id)
77
nma_start_dbus_connection_watch (applet);
79
else if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
85
if (dbus_message_get_args (message, NULL,
86
DBUS_TYPE_STRING, &service,
87
DBUS_TYPE_STRING, &old_owner,
88
DBUS_TYPE_STRING, &new_owner,
91
if (strcmp (service, NM_DBUS_SERVICE) == 0)
93
gboolean old_owner_good = (old_owner && (strlen (old_owner) > 0));
94
gboolean new_owner_good = (new_owner && (strlen (new_owner) > 0));
96
if (!old_owner_good && new_owner_good && !applet->nm_running)
98
/* NetworkManager started up */
99
nma_set_running (applet, TRUE);
100
nma_set_state (applet, NM_STATE_DISCONNECTED);
102
nma_dbus_update_nm_state (applet);
103
nma_dbus_update_devices (applet);
104
nma_dbus_update_dialup (applet);
105
nma_dbus_vpn_update_vpn_connections (applet);
107
/* Immediate redraw */
108
nma_update_state (applet);
110
else if (old_owner_good && !new_owner_good)
112
nma_set_state (applet, NM_STATE_DISCONNECTED);
113
nma_set_running (applet, FALSE);
114
nmi_passphrase_dialog_destroy (applet);
116
/* One last redraw to capture new state before sleeping */
117
nma_update_state (applet);
122
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, NM_DBUS_SIGNAL_STATE_CHANGE))
124
NMState state = NM_STATE_UNKNOWN;
126
if (dbus_message_get_args (message, NULL, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
128
NetworkDevice *act_dev = nma_get_first_active_device (applet->device_list);
130
/* If we've switched to connecting, update the active device to ensure that we have
131
* valid wireless network information for it.
133
if (state == NM_STATE_CONNECTING && act_dev && network_device_is_wireless (act_dev))
135
nma_dbus_device_update_one_device (applet, network_device_get_nm_path (act_dev));
137
nma_set_state (applet, state);
140
else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceAdded")
141
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceActivating")
142
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceCarrierOn")
143
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceCarrierOff"))
147
if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
148
nma_dbus_device_update_one_device (applet, path);
150
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNowActive"))
155
if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_STRING, &essid, DBUS_TYPE_INVALID))
156
nma_dbus_device_activated (applet, path, essid);
157
else if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
158
nma_dbus_device_activated (applet, path, NULL);
160
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNoLongerActive"))
164
if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
165
nma_dbus_device_deactivated (applet, path);
167
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceRemoved"))
171
if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
172
nma_dbus_device_remove_one_device (applet, path);
174
else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionAdded")
175
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionUpdate")) /* VPN connection properties changed */
179
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
180
nma_dbus_vpn_update_one_vpn_connection (applet, name);
182
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionStateChange")) /* Active VPN connection changed */
185
NMVPNActStage vpn_stage;
186
dbus_uint32_t vpn_stage_int;
188
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &vpn_stage_int, DBUS_TYPE_INVALID))
190
vpn_stage = (NMVPNActStage) vpn_stage_int;
191
nma_dbus_vpn_update_vpn_connection_stage (applet, name, vpn_stage);
194
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, "VPNConnectionRemoved"))
198
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
199
nma_dbus_vpn_remove_one_vpn_connection (applet, name);
201
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkAppeared"))
203
char *dev_path = NULL;
204
char *net_path = NULL;
206
if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_OBJECT_PATH, &net_path, DBUS_TYPE_INVALID))
207
nma_dbus_device_update_one_network (applet, dev_path, net_path, NULL);
209
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkDisappeared"))
211
char *dev_path = NULL;
212
char *net_path = NULL;
214
if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_OBJECT_PATH, &net_path, DBUS_TYPE_INVALID))
215
nma_dbus_device_remove_one_network (applet, dev_path, net_path);
217
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkStrengthChanged"))
219
char * dev_path = NULL;
220
char * net_path = NULL;
223
if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_OBJECT_PATH, &net_path, DBUS_TYPE_INT32, &strength, DBUS_TYPE_INVALID))
224
nma_dbus_update_strength (applet, dev_path, net_path, strength);
226
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceStrengthChanged"))
228
char *dev_path = NULL;
230
if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INT32, &strength, DBUS_TYPE_INVALID))
231
nma_dbus_update_strength (applet, dev_path, NULL, strength);
233
else if ( dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED)
234
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED)
235
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED)
236
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD)
237
|| dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
242
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_STRING, &error_msg, DBUS_TYPE_INVALID)) {
243
nma_show_vpn_failure_alert (applet, member, vpn_name, error_msg);
244
/* clear the 'last_attempt_success' key in gconf so we prompt for password next time */
245
nma_dbus_vpn_set_last_attempt_status (applet, vpn_name, FALSE);
248
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE_VPN, NM_DBUS_VPN_SIGNAL_LOGIN_BANNER))
253
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &vpn_name, DBUS_TYPE_STRING, &banner, DBUS_TYPE_INVALID))
255
char *stripped = g_strstrip (g_strdup (banner));
257
nma_show_vpn_login_banner (applet, vpn_name, stripped);
260
/* set the 'last_attempt_success' key in gconf so we DON'T prompt for password next time */
261
nma_dbus_vpn_set_last_attempt_status (applet, vpn_name, TRUE);
264
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceActivationFailed"))
269
if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &dev, DBUS_TYPE_STRING, &net, DBUS_TYPE_INVALID))
270
dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &dev, DBUS_TYPE_INVALID);
274
char *string = g_strdup_printf (_("Connection to the wireless network '%s' failed."), net);
275
nma_schedule_warning_dialog (applet, string);
279
nma_schedule_warning_dialog (applet, _("Connection to the wired network failed."));
281
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceActivationStage"))
283
char * dev_path = NULL;
286
if (dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_UINT32, &stage, DBUS_TYPE_INVALID))
290
if ((dev = nma_get_device_for_nm_path (applet->device_list, dev_path)))
291
network_device_set_act_stage (dev, stage);
297
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
302
* nma_dbus_nm_is_running
304
* Ask dbus whether or not NetworkManager is running
307
static gboolean nma_dbus_nm_is_running (DBusConnection *connection)
312
g_return_val_if_fail (connection != NULL, FALSE);
314
dbus_error_init (&error);
315
exists = dbus_bus_name_has_owner (connection, NM_DBUS_SERVICE, &error);
316
if (dbus_error_is_set (&error))
317
dbus_error_free (&error);
325
* Initialize a connection to NetworkManager if we can get one
328
static DBusConnection * nma_dbus_init (NMApplet *applet)
330
DBusConnection * connection = NULL;
332
DBusObjectPathVTable vtable = { NULL, &nmi_dbus_info_message_handler, NULL, NULL, NULL, NULL };
334
dbus_bool_t success = FALSE;
336
g_return_val_if_fail (applet != NULL, NULL);
338
dbus_error_init (&error);
339
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
340
if (dbus_error_is_set (&error)) {
341
nm_warning ("%s raised:\n %s\n\n", error.name, error.message);
345
dbus_error_init (&error);
346
acquisition = dbus_bus_request_name (connection,
348
DBUS_NAME_FLAG_REPLACE_EXISTING,
350
if (dbus_error_is_set (&error)) {
351
nm_warning ("could not acquire its service. dbus_bus_acquire_service()"
356
if (acquisition == DBUS_REQUEST_NAME_REPLY_EXISTS)
359
success = dbus_connection_register_object_path (connection,
364
nm_warning ("could not register a messgae handler for the"
365
" NetworkManagerInfo service. Not enough memory?");
369
success = dbus_connection_add_filter (connection, nma_dbus_filter, applet, NULL);
373
dbus_connection_set_exit_on_disconnect (connection, FALSE);
374
dbus_connection_setup_with_g_main (connection, NULL);
376
dbus_error_init (&error);
377
dbus_bus_add_match(connection,
379
"interface='" DBUS_INTERFACE_DBUS "',"
380
"sender='" DBUS_SERVICE_DBUS "'",
382
if (dbus_error_is_set (&error)) {
383
nm_warning ("Could not register signal handlers. '%s'",
388
dbus_error_init (&error);
389
dbus_bus_add_match(connection,
391
"interface='" NM_DBUS_INTERFACE "',"
392
"path='" NM_DBUS_PATH "',"
393
"sender='" NM_DBUS_SERVICE "'",
395
if (dbus_error_is_set (&error)) {
396
nm_warning ("Could not register signal handlers. '%s'",
401
dbus_error_init (&error);
402
dbus_bus_add_match(connection,
404
"interface='" NM_DBUS_INTERFACE_VPN "',"
405
"path='" NM_DBUS_PATH_VPN "',"
406
"sender='" NM_DBUS_SERVICE "'",
408
if (dbus_error_is_set (&error)) {
409
nm_warning ("Could not register signal handlers. '%s'",
417
if (dbus_error_is_set (&error))
418
dbus_error_free (&error);
420
dbus_connection_unref (connection);
426
* nma_dbus_connection_watcher
428
* Try to reconnect if we ever get disconnected from the bus
432
nma_dbus_connection_watcher (gpointer user_data)
434
NMApplet * applet = (NMApplet *)user_data;
436
g_return_val_if_fail (applet != NULL, TRUE);
438
nma_dbus_init_helper (applet);
439
if (applet->connection) {
440
applet->connection_timeout_id = 0;
441
return FALSE; /* Remove timeout */
449
nma_start_dbus_connection_watch (NMApplet *applet)
451
if (applet->connection_timeout_id)
452
g_source_remove (applet->connection_timeout_id);
454
applet->connection_timeout_id = g_timeout_add (5000,
455
(GSourceFunc) nma_dbus_connection_watcher,
461
* nma_dbus_init_helper
463
* Set up the applet's NMI dbus methods and dbus connection
467
nma_dbus_init_helper (NMApplet *applet)
469
g_return_if_fail (applet != NULL);
471
applet->connection = nma_dbus_init (applet);
472
if (applet->connection) {
473
if (applet->connection_timeout_id) {
474
g_source_remove (applet->connection_timeout_id);
475
applet->connection_timeout_id = 0;
478
if (nma_dbus_nm_is_running (applet->connection)) {
479
nma_set_running (applet, TRUE);
480
nma_dbus_update_nm_state (applet);
481
nma_dbus_update_devices (applet);
482
nma_dbus_update_dialup (applet);
483
nma_dbus_vpn_update_vpn_connections (applet);
485
/* Immediate redraw */
486
nma_update_state (applet);