nm-dbus-device.c 14.5 KB
Newer Older
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
/* NetworkManager -- Network link manager
 *
 * Dan Williams <dcbw@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * (C) Copyright 2005 Red Hat, Inc.
 */

#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <stdarg.h>
#include <syslog.h>
28
#include <netinet/ether.h>
29

30
#include "nm-utils.h"
31
32
33
34
#include "NetworkManagerDevice.h"
#include "NetworkManagerDbus.h"
#include "NetworkManagerDbusUtils.h"
#include "NetworkManagerPolicy.h"
35
#include "NetworkManagerUtils.h"
36
37
#include "nm-dbus-device.h"

38

39
40
41
42
43
44
45
46
static DBusMessage *nm_dbus_device_get_name (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	dev = data->dev;
47
48
49
50
51
	if ((reply = dbus_message_new_method_return (message))) {
                const char *iface;
                iface = nm_device_get_iface (dev);
		dbus_message_append_args (reply, DBUS_TYPE_STRING, &iface, DBUS_TYPE_INVALID);
        }
52
53
54
55
56
57
58
59
60
61
62
63

	return reply;
}

static DBusMessage *nm_dbus_device_get_type (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	dev = data->dev;
64
65
66
67
68
	if ((reply = dbus_message_new_method_return (message))) {
                dbus_int32_t type;
                type = nm_device_get_type (dev);
		dbus_message_append_args (reply, DBUS_TYPE_INT32, &type, DBUS_TYPE_INVALID);
        }
69
70
71
72
73
74
75
76
77
78
79
80

	return reply;
}

static DBusMessage *nm_dbus_device_get_hal_udi (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	dev = data->dev;
81
82
83
84
85
	if ((reply = dbus_message_new_method_return (message))) {
                const char *udi;
                udi = nm_device_get_udi (dev);
		dbus_message_append_args (reply, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID);
        }
86
87
88
89
90
91
92
93
94
95
96
97

	return reply;
}

static DBusMessage *nm_dbus_device_get_ip4_address (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	dev = data->dev;
98
99
100
101
102
103
	if ((reply = dbus_message_new_method_return (message))) {
                dbus_uint32_t address;
                
                address = nm_device_get_ip4_address (dev);
		dbus_message_append_args (reply, DBUS_TYPE_UINT32, &address, DBUS_TYPE_INVALID);
        }
104
105
106
107

	return reply;
}

108
109
110
111
112
113
114
115
116
117
118
119
120
121
static DBusMessage *nm_dbus_device_get_hw_address (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	dev = data->dev;
	if ((reply = dbus_message_new_method_return (message)))
	{
		struct ether_addr	addr;
		char				char_addr[20];
		char				*ptr = &char_addr[0];

122
		nm_device_get_hw_address (dev, &addr);
123
124
125
126
127
128
129
130
		memset (char_addr, 0, 20);
		ether_ntoa_r (&addr, &char_addr[0]);
		dbus_message_append_args (reply, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_INVALID);
	}

	return reply;
}

131
132
133
134
135
136
137
138
static DBusMessage *nm_dbus_device_get_mode (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	dev = data->dev;
139
140
141
142
143
	if ((reply = dbus_message_new_method_return (message))) {
                dbus_uint32_t mode;
                mode = nm_device_get_mode (dev);
		dbus_message_append_args (reply, DBUS_TYPE_UINT32, &mode, DBUS_TYPE_INVALID);
        }
144
145
146
147
148
149
150
151
152
153
154
155

	return reply;
}

static DBusMessage *nm_dbus_device_get_link_active (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	dev = data->dev;
156
157
158
	if ((reply = dbus_message_new_method_return (message))) {
                dbus_bool_t is_active;

159
                is_active = nm_device_has_active_link (dev);
160
161
		dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &is_active, DBUS_TYPE_INVALID);
        }
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

	return reply;
}

static DBusMessage *nm_dbus_device_get_active_network (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	gboolean		 success = FALSE;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	/* Only wireless devices have an active network */
	dev = data->dev;
	if (!nm_device_is_wireless (dev))
	{
		reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotWireless",
				"Wired devices cannot have active networks.");
	}
	else if ((reply = dbus_message_new_method_return (message)))
	{
183
184
		NMActRequest *		req = nm_device_get_act_request (dev);
		NMAccessPoint *	ap;
185

186
		if (req && (ap = nm_act_request_get_ap (req)))
187
		{
188
189
			NMAccessPoint *tmp_ap;
			char *		object_path = NULL;
190

191
			if (    (tmp_ap = nm_device_ap_list_get_ap_by_essid (dev, nm_ap_get_essid (ap)))
192
				&& (object_path = nm_dbus_get_object_path_for_network (dev, tmp_ap)))
193
			{
194
				dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID);
195
				g_free (object_path);
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
				success = TRUE;
			}
		}
		if (!success)
		{
			dbus_message_unref (reply);
			reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoActiveNetwork",
					"The device is not associated with any networks at this time.");
		}
	}

	return reply;
}

static DBusMessage *nm_dbus_device_get_networks (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	/* Only wireless devices have networks */
	dev = data->dev;
	if (!nm_device_is_wireless (dev))
	{
		reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotWireless",
				"Wired devices cannot see wireless networks.");
	}
	else if ((reply = dbus_message_new_method_return (message)))
	{
		DBusMessageIter	 iter;
		DBusMessageIter	 iter_array;
		NMAccessPoint		*ap = NULL;
		gboolean			 success = FALSE;
		NMAccessPointList	*ap_list;
		NMAPListIter		*list_iter;
232
		char			*escaped_object_path;
233

234
		dbus_message_iter_init_append (reply, &iter);
235
		dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter_array);
Dan Williams's avatar
Dan Williams committed
236

237
238
239
240
241
242
243
244
		if ((ap_list = nm_device_ap_list_get (dev)))
		{
			if ((list_iter = nm_ap_list_iter_new (ap_list)))
			{
				while ((ap = nm_ap_list_iter_next (list_iter)))
				{
					if (nm_ap_get_essid (ap))
					{
245
246
						escaped_object_path = nm_dbus_get_object_path_for_network (dev, ap);
						dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, &escaped_object_path);
247
						g_free (escaped_object_path);
248
249
250
251
252
253
254
						success = TRUE;
					}
				}
				nm_ap_list_iter_free (list_iter);
			}
		}

255
256
		dbus_message_iter_close_container (&iter, &iter_array);

257
258
259
260
261
262
263
264
265
266
267
		if (!success)
		{
			dbus_message_unref (reply);
			reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoNetworks",
					"The device cannot see any wireless networks.");
		}
	}

	return reply;
}

268
static DBusMessage *nm_dbus_device_get_driver_support_level (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
269
270
271
272
273
274
275
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	dev = data->dev;
276
	if ((reply = dbus_message_new_method_return (message)))
277
	{
278
279
		dbus_uint32_t driver_support_level = nm_device_get_driver_support_level (dev);
		dbus_message_append_args (reply, DBUS_TYPE_UINT32, &driver_support_level, DBUS_TYPE_INVALID);
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
	}

	return reply;
}

static DBusMessage *nm_dbus_device_set_link_active (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	/* Can only set link status for active devices */
	dev = data->dev;
	if (!nm_device_is_test_device (dev))
	{
		reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NotTestDevice",
					"Only test devices can have their link status set manually.");
	}
	else if ((reply = dbus_message_new_method_return (message)))
	{
		DBusError	error;
		gboolean	link;

		dbus_error_init (&error);
		if (dbus_message_get_args (message, &error, DBUS_TYPE_BOOLEAN, &link, DBUS_TYPE_INVALID))
		{
			nm_device_set_link_active (dev, link);
308
			nm_policy_schedule_device_change_check (data->data);
309
310
311
312
313
314
		}
	}

	return reply;
}

315
316
317
318
319
320
321
322
323
324
325
326
327
328
static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
	DBusMessage	*reply = NULL;
	NMDevice		*dev;

	g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);

	dev = data->dev;
	if ((reply = dbus_message_new_method_return (message)))
	{
		char *			op = nm_dbus_get_object_path_for_device (dev);
		const char *		iface = nm_device_get_iface (dev);
		dbus_uint32_t		type = (dbus_uint32_t) nm_device_get_type (dev);
		const char *		udi = nm_device_get_udi (dev);
329
330
331
		gchar *			ip4_address;
		gchar *			broadcast;
		gchar *			subnetmask;
332
333
334
335
336
337
338
339
340
341
		struct ether_addr	hw_addr;
		char				hw_addr_buf[20];
		char *			hw_addr_buf_ptr = &hw_addr_buf[0];
		dbus_uint32_t		mode = 0;
		dbus_int32_t		strength = -1;
		char *			active_network_path = NULL;
		dbus_bool_t		link_active = (dbus_bool_t) nm_device_has_active_link (dev);
		dbus_uint32_t		driver_support_level = (dbus_uint32_t) nm_device_get_driver_support_level (dev);
		char **			networks = NULL;
		int				num_networks = 0;
342
		dbus_bool_t		active = nm_device_get_act_request (dev) ? TRUE : FALSE;
343
		NMActStage		act_stage = active ? nm_act_request_get_stage (nm_device_get_act_request (dev)) : NM_ACT_STAGE_UNKNOWN;
344
		NMIP4Config *		ip4config;
345
346
		guint32			broadcast_addr = 0;
		guint32			subnetmask_addr = 0;
347

348
		nm_device_get_hw_address (dev, &hw_addr);
349
350
351
		memset (hw_addr_buf, 0, 20);
		ether_ntoa_r (&hw_addr, &hw_addr_buf[0]);

352
		ip4config = nm_device_get_ip4_config (dev);
353
354
355
356
357
		if (ip4config)
		{
			broadcast_addr = nm_ip4_config_get_broadcast (ip4config);
			subnetmask_addr = nm_ip4_config_get_netmask (ip4config);
		}
358
		ip4_address = nm_utils_inet_ip4_address_as_string (nm_device_get_ip4_address (dev));
359
360
		broadcast = nm_utils_inet_ip4_address_as_string (broadcast_addr);
		subnetmask = nm_utils_inet_ip4_address_as_string (subnetmask_addr);
361

362
363
		if (nm_device_is_wireless (dev))
		{
364
365
			NMActRequest *		req = nm_device_get_act_request (dev);
			NMAccessPoint *	ap;
366
367
368
369
370
371
			NMAccessPointList *	ap_list;
			NMAPListIter *		iter;

			strength = (dbus_int32_t) nm_device_get_signal_strength (dev);
			mode = (dbus_uint32_t) nm_device_get_mode (dev);

372
			if (req && (ap = nm_act_request_get_ap (req)))
373
374
375
			{
				NMAccessPoint	*tmp_ap;

376
				if ((tmp_ap = nm_device_ap_list_get_ap_by_essid (dev, nm_ap_get_essid (ap))))
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
					active_network_path = nm_dbus_get_object_path_for_network (dev, tmp_ap);
			}

			ap_list = nm_device_ap_list_get (dev);
			if (ap_list && (num_networks = nm_ap_list_size (ap_list)))
			{
				if ((iter = nm_ap_list_iter_new (ap_list)))
				{
					int				i = 0;
					NMAccessPoint *	ap;

					networks = g_malloc0 (sizeof (char *) * (num_networks + 1));
					while ((ap = nm_ap_list_iter_next (iter)))
					{
						char *ap_op = nm_dbus_get_object_path_for_network (dev, ap);
						if (ap_op)
							networks[i++] = ap_op;
					}
					num_networks = i;	/* # actually added to array, since we can have NULL essid access points */

					nm_ap_list_iter_free (iter);
				}
			}
		}
		if (!active_network_path)
			active_network_path = g_strdup ("");

		dbus_message_append_args (reply,	DBUS_TYPE_OBJECT_PATH, &op,
									DBUS_TYPE_STRING, &iface,
									DBUS_TYPE_UINT32, &type,
									DBUS_TYPE_STRING, &udi,
408
									DBUS_TYPE_BOOLEAN,&active,
409
									DBUS_TYPE_UINT32, &act_stage,
410
411
412
									DBUS_TYPE_STRING, &ip4_address,
									DBUS_TYPE_STRING, &subnetmask,
									DBUS_TYPE_STRING, &broadcast,
413
414
415
416
417
418
419
420
421
422
423
									DBUS_TYPE_STRING, &hw_addr_buf_ptr,
									DBUS_TYPE_UINT32, &mode,
									DBUS_TYPE_INT32,  &strength,
									DBUS_TYPE_BOOLEAN,&link_active,
									DBUS_TYPE_UINT32, &driver_support_level,
									DBUS_TYPE_STRING, &active_network_path,
									DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &networks, num_networks,
									DBUS_TYPE_INVALID);
		g_free (op);
		g_free (active_network_path);
		g_strfreev (networks);
424
425
426
		g_free (ip4_address);
		g_free (broadcast);
		g_free (subnetmask);
427
428
429
430
431
	}

	return reply;
}

432
433
434
435
436
437
438
439
440
441
442

/*
 * nm_dbus_device_methods_setup
 *
 * Register handlers for dbus methods on the org.freedesktop.NetworkManager.Devices object.
 *
 */
NMDbusMethodList *nm_dbus_device_methods_setup (void)
{
	NMDbusMethodList	*list = nm_dbus_method_list_new (NULL);

443
444
	nm_dbus_method_list_add_method (list, "getProperties",			nm_dbus_device_get_properties);

445
446
447
448
449
450
451
452
453
454
455
	nm_dbus_method_list_add_method (list, "getName",				nm_dbus_device_get_name);
	nm_dbus_method_list_add_method (list, "getType",				nm_dbus_device_get_type);
	nm_dbus_method_list_add_method (list, "getHalUdi",			nm_dbus_device_get_hal_udi);
	nm_dbus_method_list_add_method (list, "getIP4Address",			nm_dbus_device_get_ip4_address);
	nm_dbus_method_list_add_method (list, "getHWAddress",			nm_dbus_device_get_hw_address);
	nm_dbus_method_list_add_method (list, "getMode",				nm_dbus_device_get_mode);
	nm_dbus_method_list_add_method (list, "getActiveNetwork",		nm_dbus_device_get_active_network);
	nm_dbus_method_list_add_method (list, "getNetworks",			nm_dbus_device_get_networks);
	nm_dbus_method_list_add_method (list, "getLinkActive",			nm_dbus_device_get_link_active);
	nm_dbus_method_list_add_method (list, "setLinkActive",			nm_dbus_device_set_link_active);
	nm_dbus_method_list_add_method (list, "getDriverSupportLevel",	nm_dbus_device_get_driver_support_level);
456
457
458

	return (list);
}