~mdz/network-manager/ubuntu.0.7

« back to all changes in this revision

Viewing changes to src/NetworkManagerDbus.c

  • Committer: dcbw
  • Date: 2004-06-24 14:18:37 UTC
  • Revision ID: vcs-imports@canonical.com-20040624141837-b23a721fd03ea23f
Initial revision

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* NetworkManager -- Network link manager
 
2
 *
 
3
 * Dan Williams <dcbw@redhat.com>
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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.
 
18
 *
 
19
 * (C) Copyright 2004 Red Hat, Inc.
 
20
 */
 
21
 
 
22
#include <glib.h>
 
23
#include <dbus/dbus-glib.h>
 
24
#include <stdarg.h>
 
25
 
 
26
extern gboolean debug;
 
27
 
 
28
#include "NetworkManager.h"
 
29
#include "NetworkManagerUtils.h"
 
30
#include "NetworkManagerDevice.h"
 
31
#include "NetworkManagerDbus.h"
 
32
#include "NetworkManagerAP.h"
 
33
 
 
34
 
 
35
/*
 
36
 * nm_dbus_create_error_message
 
37
 *
 
38
 * Make a DBus error message
 
39
 *
 
40
 */
 
41
static DBusMessage *nm_dbus_create_error_message (DBusMessage *message, const char *exception_namespace,
 
42
                                                                                const char *exception, const char *format, ...)
 
43
{
 
44
        DBusMessage     *reply_message;
 
45
        va_list          args;
 
46
        char                     error_text[512];
 
47
 
 
48
 
 
49
        va_start (args, format);
 
50
        vsnprintf (error_text, 512, format, args);
 
51
        va_end (args);
 
52
 
 
53
        char *exception_text = g_strdup_printf ("%s.%s", exception_namespace, exception);
 
54
        reply_message = dbus_message_new_error (message, exception_text, error_text);
 
55
        g_free (exception_text);
 
56
 
 
57
        return (reply_message);
 
58
}
 
59
 
 
60
 
 
61
/*
 
62
 * nm_dbus_get_object_path_from_device
 
63
 *
 
64
 * Copies the object path for a device object into a provided buffer
 
65
 *
 
66
 */
 
67
void nm_dbus_get_object_path_from_device (NMDevice *dev, unsigned char *buf, unsigned int buf_len, gboolean lock_dev_list)
 
68
{
 
69
        NMData  *data = nm_get_global_data ();
 
70
 
 
71
        g_return_if_fail (buf != NULL);
 
72
        g_return_if_fail (buf_len > 0);
 
73
        memset (buf, 0, buf_len);
 
74
 
 
75
        g_return_if_fail (dev != NULL);
 
76
        g_return_if_fail (data != NULL);
 
77
 
 
78
        /* Iterate over device list */
 
79
        if (!lock_dev_list || nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
 
80
        {
 
81
                NMDevice        *list_dev = NULL;
 
82
                GSList  *element = data->dev_list;
 
83
                int              i = 0;
 
84
 
 
85
                while (element)
 
86
                {
 
87
                        list_dev = (NMDevice *)(element->data);
 
88
                        if (dev == list_dev)
 
89
                        {
 
90
                                snprintf (buf, buf_len-1, "%s/%d", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, i);
 
91
                                break;
 
92
                        }
 
93
 
 
94
                        i++;
 
95
                        element = g_slist_next (element);
 
96
                }
 
97
 
 
98
                if (lock_dev_list)
 
99
                        nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
 
100
        }
 
101
}
 
102
 
 
103
 
 
104
/*
 
105
 * nm_dbus_get_device_from_object_path
 
106
 *
 
107
 * Returns the device associated with a dbus object path
 
108
 *
 
109
 */
 
110
NMDevice *nm_dbus_get_device_from_object_path (const char *path, int *dev_index)
 
111
{
 
112
        NMData  *data = nm_get_global_data ();
 
113
        NMDevice        *dev = NULL;
 
114
 
 
115
        *dev_index = -1;
 
116
 
 
117
        g_return_val_if_fail (path != NULL, NULL);
 
118
        g_return_val_if_fail (data != NULL, NULL);
 
119
 
 
120
        /* FIXME
 
121
         * This function could be much more efficient, for example we could
 
122
         * actually _parse_ the object path, but that's a lot more code and
 
123
         * stupid stuff.  The approach below is slower, less efficient, but
 
124
         * less code and less error-prone.
 
125
         */
 
126
 
 
127
        /* Iterate over device list */
 
128
        if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
 
129
        {
 
130
                GSList  *element = data->dev_list;
 
131
                char             compare_path[100];
 
132
                int              i = 0;
 
133
 
 
134
                while (element)
 
135
                {
 
136
                        snprintf (compare_path, 100, "%s/%d", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, i);
 
137
 
 
138
                        /* Compare against our constructed path, but ignore any trailing elements */
 
139
                        dev = (NMDevice *)(element->data);
 
140
                        if (dev && (strncmp (path, compare_path, strlen (compare_path)) == 0))
 
141
                        {
 
142
                                *dev_index = i;
 
143
                                break;
 
144
                        }
 
145
                        else
 
146
                                dev = NULL;
 
147
 
 
148
                        i++;
 
149
                        element = g_slist_next (element);
 
150
                }
 
151
                nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
 
152
        }
 
153
 
 
154
        return (dev);
 
155
}
 
156
 
 
157
 
 
158
/*
 
159
 * nm_dbus_get_network_by_object_path
 
160
 *
 
161
 * Returns the network (ap) associated with a dbus object path
 
162
 *
 
163
 */
 
164
NMAccessPoint *nm_dbus_get_network_by_object_path (const char *path, NMDevice *dev, int dev_index, int *ap_index)
 
165
{
 
166
        NMData          *data;
 
167
        NMAccessPoint   *ap = NULL;
 
168
        int                      i = 0;
 
169
        char                     compare_path[100];
 
170
 
 
171
        *ap_index = -1;
 
172
 
 
173
        g_return_val_if_fail (path != NULL, NULL);
 
174
 
 
175
        while (ap = nm_device_ap_list_get_ap (dev, i))
 
176
        {
 
177
                snprintf (compare_path, 100, "%s/%d/Networks/%d", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, dev_index, i);
 
178
                if (strncmp (path, compare_path, strlen (compare_path)) == 0)
 
179
                {
 
180
                        *ap_index = i;
 
181
                        break;
 
182
                }
 
183
                else
 
184
                        ap = NULL;
 
185
 
 
186
                i++;
 
187
        }
 
188
 
 
189
        return (ap);
 
190
}
 
191
 
 
192
 
 
193
/*
 
194
 * nm_dbus_nm_get_active_device
 
195
 *
 
196
 * Returns the object path of the currently active device
 
197
 *
 
198
 */
 
199
static DBusMessage *nm_dbus_nm_get_active_device (DBusConnection *connection, DBusMessage *message)
 
200
{
 
201
        DBusMessage             *reply_message = NULL;
 
202
        DBusMessageIter  iter;
 
203
        NMData                  *data;
 
204
 
 
205
        data = nm_get_global_data ();
 
206
        if (!data)
 
207
        {
 
208
                /* If we can't get our global data, something is really wrong... */
 
209
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "NoGlobalData",
 
210
                                                        "NetworkManager couldn't get its global data.");
 
211
                goto end;
 
212
        }
 
213
 
 
214
        if (!data->active_device)
 
215
        {
 
216
                reply_message = dbus_message_new_method_return (message);
 
217
                dbus_message_iter_init (reply_message, &iter);
 
218
                dbus_message_iter_append_string (&iter, "");
 
219
 
 
220
                goto end;
 
221
        }
 
222
 
 
223
        /* Iterate over device list and grab index of "active device" */
 
224
        if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
 
225
        {
 
226
                GSList  *element = data->dev_list;
 
227
                int              i = 0;
 
228
 
 
229
                while (element)
 
230
                {
 
231
                        NMDevice        *dev = (NMDevice *)(element->data);
 
232
 
 
233
                        if (dev && (dev == data->active_device))
 
234
                        {
 
235
                                char *object_path = g_strdup_printf ("%s/%d", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, i);
 
236
 
 
237
                                reply_message = dbus_message_new_method_return (message);
 
238
                                dbus_message_iter_init (reply_message, &iter);
 
239
                                dbus_message_iter_append_string (&iter, object_path);
 
240
                                g_free (object_path);
 
241
 
 
242
                                break;
 
243
                        }
 
244
 
 
245
                        i++;
 
246
                        element = g_slist_next (element);
 
247
                }
 
248
 
 
249
                if (!reply_message)
 
250
                {
 
251
                        /* If the active device wasn't in the list, its been removed. */
 
252
                        reply_message = dbus_message_new_method_return (message);
 
253
                        dbus_message_iter_init (reply_message, &iter);
 
254
                        dbus_message_iter_append_string (&iter, "");
 
255
                }
 
256
 
 
257
                nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
 
258
        }
 
259
        else
 
260
        {
 
261
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "Retry",
 
262
                                                "NetworkManager could not lock device list, try again.");
 
263
        }
 
264
 
 
265
        end:
 
266
                return (reply_message);
 
267
}
 
268
 
 
269
 
 
270
/*
 
271
 * nm_dbus_nm_get_devices
 
272
 *
 
273
 * Returns a string array of object paths corresponding to the
 
274
 * devices in the device list.
 
275
 *
 
276
 */
 
277
static DBusMessage *nm_dbus_nm_get_devices (DBusConnection *connection, DBusMessage *message)
 
278
{
 
279
        DBusMessage             *reply_message = NULL;
 
280
        DBusMessageIter  iter;
 
281
        DBusMessageIter  iter_array;
 
282
        NMData                  *data;
 
283
 
 
284
        data = nm_get_global_data ();
 
285
        if (!data)
 
286
        {
 
287
                /* If we can't get our global data, something is really wrong... */
 
288
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "NoGlobalData",
 
289
                                                        "NetworkManager couldn't get its global data.");
 
290
                goto end;
 
291
        }
 
292
 
 
293
        /* Check for no devices */
 
294
        if (!data->dev_list)
 
295
        {
 
296
                reply_message = dbus_message_new_method_return (message);
 
297
                dbus_message_iter_init (reply_message, &iter);
 
298
                dbus_message_iter_append_array (&iter, &iter_array, DBUS_TYPE_STRING);
 
299
                dbus_message_iter_append_string (&iter_array, "");
 
300
 
 
301
                goto end;
 
302
        }
 
303
 
 
304
        /* Iterate over device list and grab index of "active device" */
 
305
        if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
 
306
        {
 
307
                GSList  *element = data->dev_list;
 
308
                int              i = 0;
 
309
                gboolean         appended = FALSE;
 
310
 
 
311
                reply_message = dbus_message_new_method_return (message);
 
312
                dbus_message_iter_init (reply_message, &iter);
 
313
                dbus_message_iter_append_array (&iter, &iter_array, DBUS_TYPE_STRING);
 
314
 
 
315
                while (element)
 
316
                {
 
317
                        NMDevice        *dev = (NMDevice *)(element->data);
 
318
 
 
319
                        if (dev)
 
320
                        {
 
321
                                char *object_path = g_strdup_printf ("%s/%d", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, i);
 
322
                                dbus_message_iter_append_string (&iter_array, object_path);
 
323
                                g_free (object_path);
 
324
                                appended = TRUE;
 
325
                        }
 
326
 
 
327
                        i++;
 
328
                        element = g_slist_next (element);
 
329
                }
 
330
 
 
331
                /* If by some chance there is a device list, but it has no devices in it
 
332
                 * (something which should never happen), append an empty string like
 
333
                 * there are no devices in the list.
 
334
                 */
 
335
                if (!appended)
 
336
                        dbus_message_iter_append_string (&iter_array, "");
 
337
 
 
338
                nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
 
339
        }
 
340
        else
 
341
        {
 
342
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "Retry",
 
343
                                                "NetworkManager could not lock device list, try again.");
 
344
        }
 
345
 
 
346
        end:
 
347
                return (reply_message);
 
348
}
 
349
 
 
350
 
 
351
/*-------------------------------------------------------------*/
 
352
/* Handler code */
 
353
/*-------------------------------------------------------------*/
 
354
 
 
355
 
 
356
/*
 
357
 * nm_dbus_signal_device_no_longer_active
 
358
 *
 
359
 * Notifies the bus that a particular device is no longer active.
 
360
 *
 
361
 */
 
362
void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevice *dev)
 
363
{
 
364
        DBusMessage             *message;
 
365
        unsigned char           *object_path = g_new0 (unsigned char, 100);
 
366
 
 
367
        g_return_if_fail (object_path != NULL);
 
368
 
 
369
        message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "DeviceNoLongerActive");
 
370
        if (!message)
 
371
        {
 
372
                NM_DEBUG_PRINT ("nm_dbus_signal_device_no_longer_active(): Not enough memory for new dbus message!\n");
 
373
        }
 
374
 
 
375
        nm_dbus_get_object_path_from_device (dev, object_path, 100, FALSE);
 
376
        dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID);
 
377
        g_free (object_path);
 
378
 
 
379
        if (!dbus_connection_send (connection, message, NULL))
 
380
                NM_DEBUG_PRINT ("nm_dbus_signal_device_no_longer_active(): Could not raise the DeviceNoLongerActive signal!\n");
 
381
 
 
382
        dbus_message_unref (message);
 
383
}
 
384
 
 
385
 
 
386
/*
 
387
 * nm_dbus_signal_device_now_active
 
388
 *
 
389
 * Notifies the bus that a particular device is newly active.
 
390
 *
 
391
 */
 
392
void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev)
 
393
{
 
394
        DBusMessage             *message;
 
395
        unsigned char           *object_path = g_new0 (unsigned char, 100);
 
396
 
 
397
        message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "DeviceNowActive");
 
398
        if (!message)
 
399
        {
 
400
                NM_DEBUG_PRINT ("nm_dbus_signal_device_now_active(): Not enough memory for new dbus message!\n");
 
401
        }
 
402
 
 
403
        nm_dbus_get_object_path_from_device (dev, object_path, 100, FALSE);
 
404
        dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID);
 
405
        g_free (object_path);
 
406
 
 
407
        if (!dbus_connection_send (connection, message, NULL))
 
408
                NM_DEBUG_PRINT ("nm_dbus_signal_device_now_active(): Could not raise the DeviceNowActive signal!\n");
 
409
 
 
410
        dbus_message_unref (message);
 
411
}
 
412
 
 
413
 
 
414
/*
 
415
 * nm_dbus_devices_handle_networks_request
 
416
 *
 
417
 * Converts a property request on a _network_ into a dbus message.
 
418
 *
 
419
 */
 
420
static DBusMessage *nm_dbus_devices_handle_networks_request (DBusConnection *connection, DBusMessage *message,
 
421
                                                                        const char *path, const char *request, NMDevice *dev, int dev_index)
 
422
{
 
423
        NMAccessPoint           *ap;
 
424
        DBusMessage             *reply_message = NULL;
 
425
        DBusMessageIter  iter;
 
426
        int                              ap_index;
 
427
 
 
428
        ap = nm_dbus_get_network_by_object_path (path, dev, dev_index, &ap_index);
 
429
        if (!ap || (ap_index == -1))
 
430
        {
 
431
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "NetworkNotFound",
 
432
                                                "The requested network does not exist for this device.");
 
433
                return (reply_message);
 
434
        }
 
435
 
 
436
        reply_message = dbus_message_new_method_return (message);
 
437
        dbus_message_iter_init (reply_message, &iter);
 
438
 
 
439
        if (strcmp ("getName", request) == 0)
 
440
                dbus_message_iter_append_string (&iter, nm_ap_get_essid (ap));
 
441
        else if (strcmp ("getAddress", request) == 0)
 
442
                dbus_message_iter_append_string (&iter, nm_ap_get_address (ap));
 
443
        else if (strcmp ("getQuality", request) == 0)
 
444
                dbus_message_iter_append_int32 (&iter, nm_ap_get_quality (ap));
 
445
        else if (strcmp ("getFrequency", request) == 0)
 
446
                dbus_message_iter_append_double (&iter, nm_ap_get_freq (ap));
 
447
        else if (strcmp ("getRate", request) == 0)
 
448
                dbus_message_iter_append_int32 (&iter, nm_ap_get_rate (ap));
 
449
        else if (strcmp ("getStamp", request) == 0)
 
450
                dbus_message_iter_append_int32 (&iter, nm_ap_get_stamp (ap));
 
451
        else
 
452
        {
 
453
                /* Must destroy the allocated message */
 
454
                dbus_message_unref (reply_message);
 
455
 
 
456
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "UnknownMethod",
 
457
                                                        "NetworkManager knows nothing about the method %s for object %s", request, path);
 
458
        }
 
459
 
 
460
        return (reply_message);
 
461
}
 
462
 
 
463
 
 
464
/*
 
465
 * nm_dbus_devices_handle_request
 
466
 *
 
467
 * Converts a property request into a dbus message.
 
468
 *
 
469
 */
 
470
static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection, DBusMessage *message, const char *path, const char *request)
 
471
{
 
472
        NMDevice                        *dev;
 
473
        DBusMessage             *reply_message = NULL;
 
474
        DBusMessageIter  iter;
 
475
        int                              dev_index;
 
476
        char                            *object_path;
 
477
 
 
478
        dev = nm_dbus_get_device_from_object_path (path, &dev_index);
 
479
        if (!dev || (dev_index == -1))
 
480
        {
 
481
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "DeviceNotFound",
 
482
                                                "The requested network device does not exist.");
 
483
                return (reply_message);
 
484
        }
 
485
 
 
486
        /* Test whether or not the _networks_ of a device were queried instead of the device itself */
 
487
        object_path = g_strdup_printf ("%s/%d/Networks/", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, dev_index);
 
488
        if (strncmp (path, object_path, strlen (object_path)) == 0)
 
489
        {
 
490
                free (object_path);
 
491
                reply_message = nm_dbus_devices_handle_networks_request (connection, message, path, request, dev, dev_index);
 
492
                return (reply_message);
 
493
        }
 
494
        free (object_path);
 
495
 
 
496
        reply_message = dbus_message_new_method_return (message);
 
497
        dbus_message_iter_init (reply_message, &iter);
 
498
 
 
499
        if (strcmp ("getName", request) == 0)
 
500
                dbus_message_iter_append_string (&iter, nm_device_get_iface (dev));
 
501
        else if (strcmp ("getType", request) == 0)
 
502
                dbus_message_iter_append_int32 (&iter, nm_device_get_iface_type (dev));
 
503
        else if (strcmp ("getActiveNetwork", request) == 0)
 
504
        {
 
505
                NMAccessPoint           *ap = NULL;
 
506
                int                              i = 0;
 
507
        
 
508
                while (ap = nm_device_ap_list_get_ap (dev, i))
 
509
                {
 
510
                        if (nm_null_safe_strcmp (nm_ap_get_essid (ap), nm_device_get_essid (dev)) == 0)
 
511
                        {
 
512
                                object_path = g_strdup_printf ("%s/%d/Networks/%d", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, dev_index, i);
 
513
                                dbus_message_iter_append_string (&iter, object_path);
 
514
                                g_free (object_path);
 
515
                                break;
 
516
                        }
 
517
                        i++;
 
518
                        ap = NULL;
 
519
                }
 
520
 
 
521
                /* If we didn't find the devices current network among the known networks, just append a blank item */
 
522
                if (!ap)
 
523
                        dbus_message_iter_append_string (&iter, "");
 
524
        }
 
525
        else if (strcmp ("getNetworks", request) == 0)
 
526
        {
 
527
                DBusMessageIter  iter_array;
 
528
                NMAccessPoint           *ap = NULL;
 
529
                int                              i = 0;
 
530
        
 
531
                dbus_message_iter_append_array (&iter, &iter_array, DBUS_TYPE_STRING);
 
532
 
 
533
                while (ap = nm_device_ap_list_get_ap (dev, i))
 
534
                {
 
535
                        object_path = g_strdup_printf ("%s/%d/Networks/%d", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, dev_index, i);
 
536
                        dbus_message_iter_append_string (&iter_array, object_path);
 
537
                        g_free (object_path);
 
538
                        
 
539
                        i++;
 
540
                }
 
541
        }
 
542
        else
 
543
        {
 
544
                /* Must destroy the allocated message */
 
545
                dbus_message_unref (reply_message);
 
546
 
 
547
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "UnknownMethod",
 
548
                                                        "NetworkManager knows nothing about the method %s for object %s", request, path);
 
549
        }
 
550
 
 
551
        return (reply_message);
 
552
}
 
553
 
 
554
 
 
555
/*
 
556
 * nm_dbus_nm_message_handler
 
557
 *
 
558
 * Dispatch messages against our NetworkManager object
 
559
 *
 
560
 */
 
561
static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
 
562
{
 
563
        const char              *method;
 
564
        const char              *path;
 
565
        DBusMessage             *reply_message = NULL;
 
566
 
 
567
        method = dbus_message_get_member (message);
 
568
        path = dbus_message_get_path (message);
 
569
 
 
570
        NM_DEBUG_PRINT_2 ("nm_dbus_devices_message_handler() got method %s for path %s\n", method, path);
 
571
 
 
572
        if (strcmp ("getActiveDevice", method) == 0)
 
573
        {
 
574
                reply_message = nm_dbus_nm_get_active_device (connection, message);
 
575
        }
 
576
        else if (strcmp ("getDevices", method) == 0)
 
577
        {
 
578
                reply_message = nm_dbus_nm_get_devices (connection, message);
 
579
        }
 
580
        else
 
581
        {
 
582
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "UnknownMethod",
 
583
                                                        "NetworkManager knows nothing about the method %s for object %s", method, path);
 
584
        }
 
585
 
 
586
        dbus_connection_send (connection, reply_message, NULL);
 
587
 
 
588
        return DBUS_HANDLER_RESULT_HANDLED;
 
589
}
 
590
 
 
591
 
 
592
/*
 
593
 * nm_dbus_nm_unregister_handler
 
594
 *
 
595
 * Nothing happens here.
 
596
 *
 
597
 */
 
598
void nm_dbus_nm_unregister_handler (DBusConnection *connection, void *user_data)
 
599
{
 
600
        /* do nothing */
 
601
}
 
602
 
 
603
 
 
604
/*
 
605
 * nm_dbus_devices_message_handler
 
606
 *
 
607
 * Dispatch messages against individual network devices
 
608
 *
 
609
 */
 
610
static DBusHandlerResult nm_dbus_devices_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
 
611
{
 
612
        const char              *method;
 
613
        const char              *path;
 
614
        DBusMessage             *reply_message = NULL;
 
615
 
 
616
        method = dbus_message_get_member (message);
 
617
        path = dbus_message_get_path (message);
 
618
 
 
619
        /* NM_DEBUG_PRINT_2 ("nm_dbus_nm_message_handler() got method %s for path %s\n", method, path); */
 
620
 
 
621
        reply_message = nm_dbus_devices_handle_request (connection, message, path, method);
 
622
        dbus_connection_send (connection, reply_message, NULL);
 
623
 
 
624
        return DBUS_HANDLER_RESULT_HANDLED;
 
625
}
 
626
 
 
627
 
 
628
/*
 
629
 * nm_dbus_devices_unregister_handler
 
630
 *
 
631
 * Nothing happens here.
 
632
 *
 
633
 */
 
634
void nm_dbus_devices_unregister_handler (DBusConnection *connection, void *user_data)
 
635
{
 
636
        /* do nothing */
 
637
}
 
638
 
 
639
 
 
640
/*
 
641
 * nm_dbus_init
 
642
 *
 
643
 * Connect to the system messagebus and register ourselves as a service.
 
644
 *
 
645
 */
 
646
DBusConnection *nm_dbus_init (void)
 
647
{
 
648
        DBusError                                dbus_error;
 
649
        dbus_bool_t                      success;
 
650
        DBusConnection                  *dbus_connection;
 
651
        DBusObjectPathVTable     nm_vtable = { &nm_dbus_nm_unregister_handler, &nm_dbus_nm_message_handler, NULL, NULL, NULL, NULL };
 
652
        const char                      *nm_path[] = { "org", "freedesktop", "NetworkManager", NULL };
 
653
        DBusObjectPathVTable     devices_vtable = { &nm_dbus_devices_unregister_handler, &nm_dbus_devices_message_handler, NULL, NULL, NULL, NULL };
 
654
        const char                      *devices_path[] = { "org", "freedesktop", "NetworkManager", "Devices", NULL };
 
655
 
 
656
        dbus_connection_set_change_sigpipe (TRUE);
 
657
 
 
658
        dbus_error_init (&dbus_error);
 
659
        dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error);
 
660
        if (dbus_connection == NULL)
 
661
        {
 
662
                NM_DEBUG_PRINT ("nm_dbus_init() could not get the system bus.  Make sure the message bus daemon is running?\n");
 
663
                return (NULL);
 
664
        }
 
665
 
 
666
        dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE);
 
667
        dbus_connection_setup_with_g_main (dbus_connection, NULL);
 
668
        dbus_bus_acquire_service (dbus_connection, NM_DBUS_NM_NAMESPACE, 0, &dbus_error);
 
669
        if (dbus_error_is_set (&dbus_error))
 
670
        {
 
671
                NM_DEBUG_PRINT_1 ("nm_dbus_init() could not acquire its service.  dbus_bus_acquire_service() says: '%s'\n", dbus_error.message);
 
672
                return (NULL);
 
673
        }
 
674
 
 
675
        success = dbus_connection_register_object_path (dbus_connection, nm_path, &nm_vtable, NULL);
 
676
        if (!success)
 
677
        {
 
678
                NM_DEBUG_PRINT ("nm_dbus_init() could not register a handler for NetworkManager.  Not enough memory?\n");
 
679
                return (NULL);
 
680
        }
 
681
 
 
682
        success = dbus_connection_register_fallback (dbus_connection, devices_path, &devices_vtable, NULL);
 
683
        if (!success)
 
684
        {
 
685
                NM_DEBUG_PRINT ("nm_dbus_init() could not register a handler for NetworkManager devices.  Not enough memory?\n");
 
686
                return (NULL);
 
687
        }
 
688
 
 
689
        return (dbus_connection);
 
690
}