libnm: add code comments to hint that NMConnection might not validate
[NetworkManager.git] / libnm / nm-client.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /*
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the
15  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  * Boston, MA 02110-1301 USA.
17  *
18  * Copyright 2007 - 2008 Novell, Inc.
19  * Copyright 2007 - 2014 Red Hat, Inc.
20  */
21
22 #include "nm-default.h"
23
24 #include <string.h>
25
26 #include "nm-utils.h"
27 #include "nm-client.h"
28 #include "nm-manager.h"
29 #include "nm-remote-settings.h"
30 #include "nm-device-ethernet.h"
31 #include "nm-device-wifi.h"
32 #include "nm-device-private.h"
33 #include "nm-core-internal.h"
34 #include "nm-active-connection.h"
35 #include "nm-vpn-connection.h"
36 #include "nm-remote-connection.h"
37 #include "nm-object-cache.h"
38 #include "nm-dbus-helpers.h"
39
40 void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled);
41
42 static void nm_client_initable_iface_init (GInitableIface *iface);
43 static void nm_client_async_initable_iface_init (GAsyncInitableIface *iface);
44
45 G_DEFINE_TYPE_WITH_CODE (NMClient, nm_client, G_TYPE_OBJECT,
46                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_client_initable_iface_init);
47                          G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_client_async_initable_iface_init);
48                          )
49
50 #define NM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CLIENT, NMClientPrivate))
51
52 typedef struct {
53         NMManager *manager;
54         NMRemoteSettings *settings;
55 } NMClientPrivate;
56
57 enum {
58         PROP_0,
59         PROP_VERSION,
60         PROP_STATE,
61         PROP_STARTUP,
62         PROP_NM_RUNNING,
63         PROP_NETWORKING_ENABLED,
64         PROP_WIRELESS_ENABLED,
65         PROP_WIRELESS_HARDWARE_ENABLED,
66         PROP_WWAN_ENABLED,
67         PROP_WWAN_HARDWARE_ENABLED,
68         PROP_WIMAX_ENABLED,
69         PROP_WIMAX_HARDWARE_ENABLED,
70         PROP_ACTIVE_CONNECTIONS,
71         PROP_CONNECTIVITY,
72         PROP_PRIMARY_CONNECTION,
73         PROP_ACTIVATING_CONNECTION,
74         PROP_DEVICES,
75         PROP_ALL_DEVICES,
76         PROP_CONNECTIONS,
77         PROP_HOSTNAME,
78         PROP_CAN_MODIFY,
79         PROP_METERED,
80
81         LAST_PROP
82 };
83
84 enum {
85         DEVICE_ADDED,
86         DEVICE_REMOVED,
87         ANY_DEVICE_ADDED,
88         ANY_DEVICE_REMOVED,
89         PERMISSION_CHANGED,
90         CONNECTION_ADDED,
91         CONNECTION_REMOVED,
92
93         LAST_SIGNAL
94 };
95
96 static guint signals[LAST_SIGNAL] = { 0 };
97
98 /**********************************************************************/
99
100 /**
101  * nm_client_error_quark:
102  *
103  * Registers an error quark for #NMClient if necessary.
104  *
105  * Returns: the error quark used for #NMClient errors.
106  **/
107 GQuark
108 nm_client_error_quark (void)
109 {
110         static GQuark quark;
111
112         if (G_UNLIKELY (!quark))
113                 quark = g_quark_from_static_string ("nm-client-error-quark");
114         return quark;
115 }
116
117 /**********************************************************************/
118
119 static void
120 nm_client_init (NMClient *client)
121 {
122 }
123
124 static gboolean
125 _nm_client_check_nm_running (NMClient *client, GError **error)
126 {
127         if (nm_client_get_nm_running (client))
128                 return TRUE;
129         else {
130                 g_set_error_literal (error,
131                                      NM_CLIENT_ERROR,
132                                      NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
133                                      "NetworkManager is not running");
134                 return FALSE;
135         }
136 }
137
138 /**
139  * nm_client_get_version:
140  * @client: a #NMClient
141  *
142  * Gets NetworkManager version.
143  *
144  * Returns: string with the version (or %NULL if NetworkManager is not running)
145  **/
146 const char *
147 nm_client_get_version (NMClient *client)
148 {
149         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
150
151         return nm_manager_get_version (NM_CLIENT_GET_PRIVATE (client)->manager);
152 }
153
154 /**
155  * nm_client_get_state:
156  * @client: a #NMClient
157  *
158  * Gets the current daemon state.
159  *
160  * Returns: the current %NMState
161  **/
162 NMState
163 nm_client_get_state (NMClient *client)
164 {
165         g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN);
166
167         return nm_manager_get_state (NM_CLIENT_GET_PRIVATE (client)->manager);
168 }
169
170 /**
171  * nm_client_get_startup:
172  * @client: a #NMClient
173  *
174  * Tests whether the daemon is still in the process of activating
175  * connections at startup.
176  *
177  * Returns: whether the daemon is still starting up
178  **/
179 gboolean
180 nm_client_get_startup (NMClient *client)
181 {
182         g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN);
183
184         return nm_manager_get_startup (NM_CLIENT_GET_PRIVATE (client)->manager);
185 }
186
187 /**
188  * nm_client_get_nm_running:
189  * @client: a #NMClient
190  *
191  * Determines whether the daemon is running.
192  *
193  * Returns: %TRUE if the daemon is running
194  **/
195 gboolean
196 nm_client_get_nm_running (NMClient *client)
197 {
198         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
199
200         return nm_manager_get_nm_running (NM_CLIENT_GET_PRIVATE (client)->manager);
201 }
202
203 /**
204  * nm_client_networking_get_enabled:
205  * @client: a #NMClient
206  *
207  * Whether networking is enabled or disabled.
208  *
209  * Returns: %TRUE if networking is enabled, %FALSE if networking is disabled
210  **/
211 gboolean
212 nm_client_networking_get_enabled (NMClient *client)
213 {
214         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
215
216         return nm_manager_networking_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
217 }
218
219 /**
220  * nm_client_networking_set_enabled:
221  * @client: a #NMClient
222  * @enabled: %TRUE to set networking enabled, %FALSE to set networking disabled
223  * @error: (allow-none): return location for a #GError, or %NULL
224  *
225  * Enables or disables networking.  When networking is disabled, all controlled
226  * interfaces are disconnected and deactivated.  When networking is enabled,
227  * all controlled interfaces are available for activation.
228  *
229  * Returns: %TRUE on success, %FALSE otherwise
230  **/
231 gboolean
232 nm_client_networking_set_enabled (NMClient *client, gboolean enable, GError **error)
233 {
234         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
235
236         if (!_nm_client_check_nm_running (client, error))
237                 return FALSE;
238
239         return nm_manager_networking_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager,
240                                                   enable, error);
241 }
242
243 /**
244  * nm_client_wireless_get_enabled:
245  * @client: a #NMClient
246  *
247  * Determines whether the wireless is enabled.
248  *
249  * Returns: %TRUE if wireless is enabled
250  **/
251 gboolean
252 nm_client_wireless_get_enabled (NMClient *client)
253 {
254         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
255
256         return nm_manager_wireless_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
257 }
258
259 /**
260  * nm_client_wireless_set_enabled:
261  * @client: a #NMClient
262  * @enabled: %TRUE to enable wireless
263  *
264  * Enables or disables wireless devices.
265  **/
266 void
267 nm_client_wireless_set_enabled (NMClient *client, gboolean enabled)
268 {
269         g_return_if_fail (NM_IS_CLIENT (client));
270
271         if (!_nm_client_check_nm_running (client, NULL))
272                 return;
273
274         nm_manager_wireless_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled);
275 }
276
277 /**
278  * nm_client_wireless_hardware_get_enabled:
279  * @client: a #NMClient
280  *
281  * Determines whether the wireless hardware is enabled.
282  *
283  * Returns: %TRUE if the wireless hardware is enabled
284  **/
285 gboolean
286 nm_client_wireless_hardware_get_enabled (NMClient *client)
287 {
288         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
289
290         return nm_manager_wireless_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
291 }
292
293 /**
294  * nm_client_wwan_get_enabled:
295  * @client: a #NMClient
296  *
297  * Determines whether WWAN is enabled.
298  *
299  * Returns: %TRUE if WWAN is enabled
300  **/
301 gboolean
302 nm_client_wwan_get_enabled (NMClient *client)
303 {
304         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
305
306         return nm_manager_wwan_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
307 }
308
309 /**
310  * nm_client_wwan_set_enabled:
311  * @client: a #NMClient
312  * @enabled: %TRUE to enable WWAN
313  *
314  * Enables or disables WWAN devices.
315  **/
316 void
317 nm_client_wwan_set_enabled (NMClient *client, gboolean enabled)
318 {
319         g_return_if_fail (NM_IS_CLIENT (client));
320
321         if (!_nm_client_check_nm_running (client, NULL))
322                 return;
323
324         nm_manager_wwan_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled);
325 }
326
327 /**
328  * nm_client_wwan_hardware_get_enabled:
329  * @client: a #NMClient
330  *
331  * Determines whether the WWAN hardware is enabled.
332  *
333  * Returns: %TRUE if the WWAN hardware is enabled
334  **/
335 gboolean
336 nm_client_wwan_hardware_get_enabled (NMClient *client)
337 {
338         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
339
340         return nm_manager_wwan_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
341 }
342
343 /**
344  * nm_client_wimax_get_enabled:
345  * @client: a #NMClient
346  *
347  * Determines whether WiMAX is enabled.
348  *
349  * Returns: %TRUE if WiMAX is enabled
350  **/
351 gboolean
352 nm_client_wimax_get_enabled (NMClient *client)
353 {
354         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
355
356         return nm_manager_wimax_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
357 }
358
359 /**
360  * nm_client_wimax_set_enabled:
361  * @client: a #NMClient
362  * @enabled: %TRUE to enable WiMAX
363  *
364  * Enables or disables WiMAX devices.
365  **/
366 void
367 nm_client_wimax_set_enabled (NMClient *client, gboolean enabled)
368 {
369         g_return_if_fail (NM_IS_CLIENT (client));
370
371         if (!_nm_client_check_nm_running (client, NULL))
372                 return;
373
374         nm_manager_wimax_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled);
375 }
376
377 /**
378  * nm_client_wimax_hardware_get_enabled:
379  * @client: a #NMClient
380  *
381  * Determines whether the WiMAX hardware is enabled.
382  *
383  * Returns: %TRUE if the WiMAX hardware is enabled
384  **/
385 gboolean
386 nm_client_wimax_hardware_get_enabled (NMClient *client)
387 {
388         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
389
390         return nm_manager_wimax_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
391 }
392
393 /**
394  * nm_client_get_logging:
395  * @client: a #NMClient
396  * @level: (allow-none): return location for logging level string
397  * @domains: (allow-none): return location for log domains string. The string is
398  *   a list of domains separated by ","
399  * @error: (allow-none): return location for a #GError, or %NULL
400  *
401  * Gets NetworkManager current logging level and domains.
402  *
403  * Returns: %TRUE on success, %FALSE otherwise
404  **/
405 gboolean
406 nm_client_get_logging (NMClient *client, char **level, char **domains, GError **error)
407 {
408         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
409         g_return_val_if_fail (level == NULL || *level == NULL, FALSE);
410         g_return_val_if_fail (domains == NULL || *domains == NULL, FALSE);
411         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
412
413         if (!_nm_client_check_nm_running (client, error))
414                 return FALSE;
415
416         return nm_manager_get_logging (NM_CLIENT_GET_PRIVATE (client)->manager,
417                                        level, domains, error);
418 }
419
420 /**
421  * nm_client_set_logging:
422  * @client: a #NMClient
423  * @level: (allow-none): logging level to set (%NULL or an empty string for no change)
424  * @domains: (allow-none): logging domains to set. The string should be a list of log
425  *   domains separated by ",". (%NULL or an empty string for no change)
426  * @error: (allow-none): return location for a #GError, or %NULL
427  *
428  * Sets NetworkManager logging level and/or domains.
429  *
430  * Returns: %TRUE on success, %FALSE otherwise
431  **/
432 gboolean
433 nm_client_set_logging (NMClient *client, const char *level, const char *domains, GError **error)
434 {
435         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
436         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
437
438         if (!_nm_client_check_nm_running (client, error))
439                 return FALSE;
440
441         return nm_manager_set_logging (NM_CLIENT_GET_PRIVATE (client)->manager,
442                                        level, domains, error);
443 }
444
445 /**
446  * nm_client_get_permission_result:
447  * @client: a #NMClient
448  * @permission: the permission for which to return the result, one of #NMClientPermission
449  *
450  * Requests the result of a specific permission, which indicates whether the
451  * client can or cannot perform the action the permission represents
452  *
453  * Returns: the permission's result, one of #NMClientPermissionResult
454  **/
455 NMClientPermissionResult
456 nm_client_get_permission_result (NMClient *client, NMClientPermission permission)
457 {
458         g_return_val_if_fail (NM_IS_CLIENT (client), NM_CLIENT_PERMISSION_RESULT_UNKNOWN);
459
460         return nm_manager_get_permission_result (NM_CLIENT_GET_PRIVATE (client)->manager, permission);
461 }
462
463 /**
464  * nm_client_get_connectivity:
465  * @client: an #NMClient
466  *
467  * Gets the current network connectivity state. Contrast
468  * nm_client_check_connectivity() and
469  * nm_client_check_connectivity_async(), which re-check the
470  * connectivity state first before returning any information.
471  *
472  * Returns: the current connectivity state
473  */
474 NMConnectivityState
475 nm_client_get_connectivity (NMClient *client)
476 {
477         g_return_val_if_fail (NM_IS_CLIENT (client), NM_CONNECTIVITY_UNKNOWN);
478
479         return nm_manager_get_connectivity (NM_CLIENT_GET_PRIVATE (client)->manager);
480 }
481
482 /**
483  * nm_client_check_connectivity:
484  * @client: an #NMClient
485  * @cancellable: a #GCancellable
486  * @error: return location for a #GError
487  *
488  * Updates the network connectivity state and returns the (new)
489  * current state. Contrast nm_client_get_connectivity(), which returns
490  * the most recent known state without re-checking.
491  *
492  * This is a blocking call; use nm_client_check_connectivity_async()
493  * if you do not want to block.
494  *
495  * Returns: the (new) current connectivity state
496  */
497 NMConnectivityState
498 nm_client_check_connectivity (NMClient *client,
499                               GCancellable *cancellable,
500                               GError **error)
501 {
502         g_return_val_if_fail (NM_IS_CLIENT (client), NM_CONNECTIVITY_UNKNOWN);
503
504         if (!_nm_client_check_nm_running (client, error))
505                 return NM_CONNECTIVITY_UNKNOWN;
506
507         return nm_manager_check_connectivity (NM_CLIENT_GET_PRIVATE (client)->manager,
508                                               cancellable, error);
509 }
510
511 static void
512 check_connectivity_cb (GObject *object,
513                        GAsyncResult *result,
514                        gpointer user_data)
515 {
516         GSimpleAsyncResult *simple = user_data;
517         NMConnectivityState connectivity;
518         GError *error = NULL;
519
520         connectivity = nm_manager_check_connectivity_finish (NM_MANAGER (object),
521                                                              result, &error);
522         if (!error)
523                 g_simple_async_result_set_op_res_gssize (simple, connectivity);
524         else
525                 g_simple_async_result_take_error (simple, error);
526
527         g_simple_async_result_complete (simple);
528         g_object_unref (simple);
529 }
530
531 /**
532  * nm_client_check_connectivity_async:
533  * @client: an #NMClient
534  * @cancellable: a #GCancellable
535  * @callback: callback to call with the result
536  * @user_data: data for @callback.
537  *
538  * Asynchronously updates the network connectivity state and invokes
539  * @callback when complete. Contrast nm_client_get_connectivity(),
540  * which (immediately) returns the most recent known state without
541  * re-checking, and nm_client_check_connectivity(), which blocks.
542  */
543 void
544 nm_client_check_connectivity_async (NMClient *client,
545                                     GCancellable *cancellable,
546                                     GAsyncReadyCallback callback,
547                                     gpointer user_data)
548 {
549         GSimpleAsyncResult *simple;
550         GError *error = NULL;
551
552         g_return_if_fail (NM_IS_CLIENT (client));
553
554         if (!_nm_client_check_nm_running (client, &error)) {
555                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
556                 return;
557         }
558
559         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
560                                             nm_client_check_connectivity_async);
561         nm_manager_check_connectivity_async (NM_CLIENT_GET_PRIVATE (client)->manager,
562                                              cancellable, check_connectivity_cb, simple);
563 }
564
565 /**
566  * nm_client_check_connectivity_finish:
567  * @client: an #NMClient
568  * @result: the #GAsyncResult
569  * @error: return location for a #GError
570  *
571  * Retrieves the result of an nm_client_check_connectivity_async()
572  * call.
573  *
574  * Returns: the (new) current connectivity state
575  */
576 NMConnectivityState
577 nm_client_check_connectivity_finish (NMClient *client,
578                                      GAsyncResult *result,
579                                      GError **error)
580 {
581         GSimpleAsyncResult *simple;
582
583         g_return_val_if_fail (NM_IS_CLIENT (client), NM_CONNECTIVITY_UNKNOWN);
584         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NM_CONNECTIVITY_UNKNOWN);
585
586         simple = G_SIMPLE_ASYNC_RESULT (result);
587
588         if (g_simple_async_result_propagate_error (simple, error))
589                 return NM_CONNECTIVITY_UNKNOWN;
590         return (NMConnectivityState) g_simple_async_result_get_op_res_gssize (simple);
591 }
592
593
594 /**
595  * nm_client_save_hostname:
596  * @client: the %NMClient
597  * @hostname: (allow-none): the new persistent hostname to set, or %NULL to
598  *   clear any existing persistent hostname
599  * @cancellable: a #GCancellable, or %NULL
600  * @error: return location for #GError
601  *
602  * Requests that the machine's persistent hostname be set to the specified value
603  * or cleared.
604  *
605  * Returns: %TRUE if the request was successful, %FALSE if it failed
606  **/
607 gboolean
608 nm_client_save_hostname (NMClient *client,
609                          const char *hostname,
610                          GCancellable *cancellable,
611                          GError **error)
612 {
613         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
614
615         return nm_remote_settings_save_hostname (NM_CLIENT_GET_PRIVATE (client)->settings,
616                                                  hostname, cancellable, error);
617 }
618
619 static void
620 save_hostname_cb (GObject *object,
621                   GAsyncResult *result,
622                   gpointer user_data)
623 {
624         GSimpleAsyncResult *simple = user_data;
625         GError *error = NULL;
626
627         if (nm_remote_settings_save_hostname_finish (NM_REMOTE_SETTINGS (object), result, &error))
628                 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
629         else
630                 g_simple_async_result_take_error (simple, error);
631
632         g_simple_async_result_complete (simple);
633         g_object_unref (simple);
634 }
635
636 /**
637  * nm_client_save_hostname_async:
638  * @client: the %NMClient
639  * @hostname: (allow-none): the new persistent hostname to set, or %NULL to
640  *   clear any existing persistent hostname
641  * @cancellable: a #GCancellable, or %NULL
642  * @callback: (scope async): callback to be called when the operation completes
643  * @user_data: (closure): caller-specific data passed to @callback
644  *
645  * Requests that the machine's persistent hostname be set to the specified value
646  * or cleared.
647  **/
648 void
649 nm_client_save_hostname_async (NMClient *client,
650                                const char *hostname,
651                                GCancellable *cancellable,
652                                GAsyncReadyCallback callback,
653                                gpointer user_data)
654 {
655         GSimpleAsyncResult *simple;
656         GError *error = NULL;
657
658         g_return_if_fail (NM_IS_CLIENT (client));
659
660         if (!_nm_client_check_nm_running (client, &error)) {
661                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
662                 return;
663         }
664
665         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
666                                             nm_client_save_hostname_async);
667         nm_remote_settings_save_hostname_async (NM_CLIENT_GET_PRIVATE (client)->settings,
668                                                 hostname,
669                                                 cancellable, save_hostname_cb, simple);
670 }
671
672 /**
673  * nm_client_save_hostname_finish:
674  * @client: the %NMClient
675  * @result: the result passed to the #GAsyncReadyCallback
676  * @error: return location for #GError
677  *
678  * Gets the result of an nm_client_save_hostname_async() call.
679  *
680  * Returns: %TRUE if the request was successful, %FALSE if it failed
681  **/
682 gboolean
683 nm_client_save_hostname_finish (NMClient *client,
684                                 GAsyncResult *result,
685                                 GError **error)
686 {
687         GSimpleAsyncResult *simple;
688
689         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
690         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
691
692         simple = G_SIMPLE_ASYNC_RESULT (result);
693         if (g_simple_async_result_propagate_error (simple, error))
694                 return FALSE;
695         else
696                 return g_simple_async_result_get_op_res_gboolean (simple);
697 }
698
699 /****************************************************************/
700 /* Devices                                                      */
701 /****************************************************************/
702
703 /**
704  * nm_client_get_devices:
705  * @client: a #NMClient
706  *
707  * Gets all the known network devices.  Use nm_device_get_type() or the
708  * <literal>NM_IS_DEVICE_XXXX</literal> functions to determine what kind of
709  * device member of the returned array is, and then you may use device-specific
710  * methods such as nm_device_ethernet_get_hw_address().
711  *
712  * Returns: (transfer none) (element-type NMDevice): a #GPtrArray
713  * containing all the #NMDevices.  The returned array is owned by the
714  * #NMClient object and should not be modified.
715  **/
716 const GPtrArray *
717 nm_client_get_devices (NMClient *client)
718 {
719         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
720
721         return nm_manager_get_devices (NM_CLIENT_GET_PRIVATE (client)->manager);
722 }
723
724 /**
725  * nm_client_get_all_devices:
726  * @client: a #NMClient
727  *
728  * Gets both real devices and device placeholders (eg, software devices which
729  * do not currently exist, but could be created automatically by NetworkManager
730  * if one of their NMDevice::ActivatableConnections was activated).  Use
731  * nm_device_is_real() to determine whether each device is a real device or
732  * a placeholder.
733  *
734  * Use nm_device_get_type() or the NM_IS_DEVICE_XXXX() functions to determine
735  * what kind of device each member of the returned array is, and then you may
736  * use device-specific methods such as nm_device_ethernet_get_hw_address().
737  *
738  * Returns: (transfer none) (element-type NMDevice): a #GPtrArray
739  * containing all the #NMDevices.  The returned array is owned by the
740  * #NMClient object and should not be modified.
741  *
742  * Since: 1.2
743  **/
744 const GPtrArray *
745 nm_client_get_all_devices (NMClient *client)
746 {
747         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
748
749         return nm_manager_get_all_devices (NM_CLIENT_GET_PRIVATE (client)->manager);
750 }
751
752 /**
753  * nm_client_get_device_by_path:
754  * @client: a #NMClient
755  * @object_path: the object path to search for
756  *
757  * Gets a #NMDevice from a #NMClient.
758  *
759  * Returns: (transfer none): the #NMDevice for the given @object_path or %NULL if none is found.
760  **/
761 NMDevice *
762 nm_client_get_device_by_path (NMClient *client, const char *object_path)
763 {
764         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
765         g_return_val_if_fail (object_path, NULL);
766
767         return nm_manager_get_device_by_path (NM_CLIENT_GET_PRIVATE (client)->manager, object_path);
768 }
769
770 /**
771  * nm_client_get_device_by_iface:
772  * @client: a #NMClient
773  * @iface: the interface name to search for
774  *
775  * Gets a #NMDevice from a #NMClient.
776  *
777  * Returns: (transfer none): the #NMDevice for the given @iface or %NULL if none is found.
778  **/
779 NMDevice *
780 nm_client_get_device_by_iface (NMClient *client, const char *iface)
781 {
782         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
783         g_return_val_if_fail (iface, NULL);
784
785         return nm_manager_get_device_by_iface (NM_CLIENT_GET_PRIVATE (client)->manager, iface);
786 }
787
788 /****************************************************************/
789 /* Active Connections                                           */
790 /****************************************************************/
791
792 /**
793  * nm_client_get_active_connections:
794  * @client: a #NMClient
795  *
796  * Gets the active connections.
797  *
798  * Returns: (transfer none) (element-type NMActiveConnection): a #GPtrArray
799  *  containing all the active #NMActiveConnections.
800  * The returned array is owned by the client and should not be modified.
801  **/
802 const GPtrArray *
803 nm_client_get_active_connections (NMClient *client)
804 {
805         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
806
807         return nm_manager_get_active_connections (NM_CLIENT_GET_PRIVATE (client)->manager);
808 }
809
810 /**
811  * nm_client_get_primary_connection:
812  * @client: an #NMClient
813  *
814  * Gets the #NMActiveConnection corresponding to the primary active
815  * network device.
816  *
817  * In particular, when there is no VPN active, or the VPN does not
818  * have the default route, this returns the active connection that has
819  * the default route. If there is a VPN active with the default route,
820  * then this function returns the active connection that contains the
821  * route to the VPN endpoint.
822  *
823  * If there is no default route, or the default route is over a
824  * non-NetworkManager-recognized device, this will return %NULL.
825  *
826  * Returns: (transfer none): the appropriate #NMActiveConnection, if
827  * any
828  */
829 NMActiveConnection *
830 nm_client_get_primary_connection (NMClient *client)
831 {
832         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
833
834         return nm_manager_get_primary_connection (NM_CLIENT_GET_PRIVATE (client)->manager);
835 }
836
837 /**
838  * nm_client_get_activating_connection:
839  * @client: an #NMClient
840  *
841  * Gets the #NMActiveConnection corresponding to a
842  * currently-activating connection that is expected to become the new
843  * #NMClient:primary-connection upon successful activation.
844  *
845  * Returns: (transfer none): the appropriate #NMActiveConnection, if
846  * any.
847  */
848 NMActiveConnection *
849 nm_client_get_activating_connection (NMClient *client)
850 {
851         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
852
853         return nm_manager_get_activating_connection (NM_CLIENT_GET_PRIVATE (client)->manager);
854 }
855
856 static void
857 activate_cb (GObject *object,
858              GAsyncResult *result,
859              gpointer user_data)
860 {
861         GSimpleAsyncResult *simple = user_data;
862         NMActiveConnection *ac;
863         GError *error = NULL;
864
865         ac = nm_manager_activate_connection_finish (NM_MANAGER (object), result, &error);
866         if (ac)
867                 g_simple_async_result_set_op_res_gpointer (simple, ac, g_object_unref);
868         else
869                 g_simple_async_result_take_error (simple, error);
870
871         g_simple_async_result_complete (simple);
872         g_object_unref (simple);
873 }
874
875 /**
876  * nm_client_activate_connection_async:
877  * @client: a #NMClient
878  * @connection: (allow-none): an #NMConnection
879  * @device: (allow-none): the #NMDevice
880  * @specific_object: (allow-none): the object path of a connection-type-specific
881  *   object this activation should use. This parameter is currently ignored for
882  *   wired and mobile broadband connections, and the value of %NULL should be used
883  *   (ie, no specific object).  For Wi-Fi or WiMAX connections, pass the object
884  *   path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can
885  *   get using nm_object_get_path(), and which will be used to complete the
886  *   details of the newly added connection.
887  * @cancellable: a #GCancellable, or %NULL
888  * @callback: callback to be called when the activation has started
889  * @user_data: caller-specific data passed to @callback
890  *
891  * Asynchronously starts a connection to a particular network using the
892  * configuration settings from @connection and the network device @device.
893  * Certain connection types also take a "specific object" which is the object
894  * path of a connection- specific object, like an #NMAccessPoint for Wi-Fi
895  * connections, or an #NMWimaxNsp for WiMAX connections, to which you wish to
896  * connect.  If the specific object is not given, NetworkManager can, in some
897  * cases, automatically determine which network to connect to given the settings
898  * in @connection.
899  *
900  * If @connection is not given for a device-based activation, NetworkManager
901  * picks the best available connection for the device and activates it.
902  *
903  * Note that the callback is invoked when NetworkManager has started activating
904  * the new connection, not when it finishes. You can used the returned
905  * #NMActiveConnection object (in particular, #NMActiveConnection:state) to
906  * track the activation to its completion.
907  **/
908 void
909 nm_client_activate_connection_async (NMClient *client,
910                                      NMConnection *connection,
911                                      NMDevice *device,
912                                      const char *specific_object,
913                                      GCancellable *cancellable,
914                                      GAsyncReadyCallback callback,
915                                      gpointer user_data)
916 {
917         GSimpleAsyncResult *simple;
918         GError *error = NULL;
919
920         g_return_if_fail (NM_IS_CLIENT (client));
921         if (device)
922                 g_return_if_fail (NM_IS_DEVICE (device));
923         if (connection)
924                 g_return_if_fail (NM_IS_CONNECTION (connection));
925
926         if (!_nm_client_check_nm_running (client, &error)) {
927                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
928                 return;
929         }
930
931         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
932                                             nm_client_activate_connection_async);
933         nm_manager_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager,
934                                               connection, device, specific_object,
935                                               cancellable, activate_cb, simple);
936 }
937
938 /**
939  * nm_client_activate_connection_finish:
940  * @client: an #NMClient
941  * @result: the result passed to the #GAsyncReadyCallback
942  * @error: location for a #GError, or %NULL
943  *
944  * Gets the result of a call to nm_client_activate_connection_async().
945  *
946  * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on
947  *   failure, in which case @error will be set.
948  **/
949 NMActiveConnection *
950 nm_client_activate_connection_finish (NMClient *client,
951                                       GAsyncResult *result,
952                                       GError **error)
953 {
954         GSimpleAsyncResult *simple;
955
956         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
957         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
958
959         simple = G_SIMPLE_ASYNC_RESULT (result);
960         if (g_simple_async_result_propagate_error (simple, error))
961                 return NULL;
962         else
963                 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
964 }
965
966 static void
967 add_activate_cb (GObject *object,
968                  GAsyncResult *result,
969                  gpointer user_data)
970 {
971         GSimpleAsyncResult *simple = user_data;
972         NMActiveConnection *ac;
973         GError *error = NULL;
974
975         ac = nm_manager_add_and_activate_connection_finish (NM_MANAGER (object), result, &error);
976         if (ac)
977                 g_simple_async_result_set_op_res_gpointer (simple, ac, g_object_unref);
978         else
979                 g_simple_async_result_take_error (simple, error);
980
981         g_simple_async_result_complete (simple);
982         g_object_unref (simple);
983 }
984
985 /**
986  * nm_client_add_and_activate_connection_async:
987  * @client: a #NMClient
988  * @partial: (allow-none): an #NMConnection to add; the connection may be
989  *   partially filled (or even %NULL) and will be completed by NetworkManager
990  *   using the given @device and @specific_object before being added
991  * @device: the #NMDevice
992  * @specific_object: (allow-none): the object path of a connection-type-specific
993  *   object this activation should use. This parameter is currently ignored for
994  *   wired and mobile broadband connections, and the value of %NULL should be used
995  *   (ie, no specific object).  For Wi-Fi or WiMAX connections, pass the object
996  *   path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can
997  *   get using nm_object_get_path(), and which will be used to complete the
998  *   details of the newly added connection.
999  * @cancellable: a #GCancellable, or %NULL
1000  * @callback: callback to be called when the activation has started
1001  * @user_data: caller-specific data passed to @callback
1002  *
1003  * Adds a new connection using the given details (if any) as a template,
1004  * automatically filling in missing settings with the capabilities of the given
1005  * device and specific object.  The new connection is then asynchronously
1006  * activated as with nm_client_activate_connection_async(). Cannot be used for
1007  * VPN connections at this time.
1008  *
1009  * Note that the callback is invoked when NetworkManager has started activating
1010  * the new connection, not when it finishes. You can used the returned
1011  * #NMActiveConnection object (in particular, #NMActiveConnection:state) to
1012  * track the activation to its completion.
1013  **/
1014 void
1015 nm_client_add_and_activate_connection_async (NMClient *client,
1016                                              NMConnection *partial,
1017                                              NMDevice *device,
1018                                              const char *specific_object,
1019                                              GCancellable *cancellable,
1020                                              GAsyncReadyCallback callback,
1021                                              gpointer user_data)
1022 {
1023         GSimpleAsyncResult *simple;
1024         GError *error = NULL;
1025
1026         g_return_if_fail (NM_IS_CLIENT (client));
1027         g_return_if_fail (NM_IS_DEVICE (device));
1028         if (partial)
1029                 g_return_if_fail (NM_IS_CONNECTION (partial));
1030
1031         if (!_nm_client_check_nm_running (client, &error)) {
1032                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
1033                 return;
1034         }
1035
1036         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
1037                                             nm_client_add_and_activate_connection_async);
1038         nm_manager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager,
1039                                                       partial, device, specific_object,
1040                                                       cancellable, add_activate_cb, simple);
1041 }
1042
1043 /**
1044  * nm_client_add_and_activate_connection_finish:
1045  * @client: an #NMClient
1046  * @result: the result passed to the #GAsyncReadyCallback
1047  * @error: location for a #GError, or %NULL
1048  *
1049  * Gets the result of a call to nm_client_add_and_activate_connection_async().
1050  *
1051  * You can call nm_active_connection_get_connection() on the returned
1052  * #NMActiveConnection to find the path of the created #NMConnection.
1053  *
1054  * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on
1055  *   failure, in which case @error will be set.
1056  **/
1057 NMActiveConnection *
1058 nm_client_add_and_activate_connection_finish (NMClient *client,
1059                                               GAsyncResult *result,
1060                                               GError **error)
1061 {
1062         GSimpleAsyncResult *simple;
1063
1064         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1065         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
1066
1067         simple = G_SIMPLE_ASYNC_RESULT (result);
1068         if (g_simple_async_result_propagate_error (simple, error))
1069                 return NULL;
1070         else
1071                 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1072 }
1073
1074 /**
1075  * nm_client_deactivate_connection:
1076  * @client: a #NMClient
1077  * @active: the #NMActiveConnection to deactivate
1078  * @cancellable: a #GCancellable, or %NULL
1079  * @error: location for a #GError, or %NULL
1080  *
1081  * Deactivates an active #NMActiveConnection.
1082  *
1083  * Returns: success or failure
1084  **/
1085 gboolean
1086 nm_client_deactivate_connection (NMClient *client,
1087                                  NMActiveConnection *active,
1088                                  GCancellable *cancellable,
1089                                  GError **error)
1090 {
1091         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1092         g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE);
1093
1094         if (!_nm_client_check_nm_running (client, NULL))
1095                 return TRUE;
1096
1097         return nm_manager_deactivate_connection (NM_CLIENT_GET_PRIVATE (client)->manager,
1098                                                  active, cancellable, error);
1099 }
1100
1101 static void
1102 deactivated_cb (GObject *object,
1103                 GAsyncResult *result,
1104                 gpointer user_data)
1105 {
1106         GSimpleAsyncResult *simple = user_data;
1107         GError *error = NULL;
1108
1109         if (nm_manager_deactivate_connection_finish (NM_MANAGER (object), result, &error))
1110                 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
1111         else
1112                 g_simple_async_result_take_error (simple, error);
1113         g_simple_async_result_complete (simple);
1114         g_object_unref (simple);
1115 }
1116
1117 /**
1118  * nm_client_deactivate_connection_async:
1119  * @client: a #NMClient
1120  * @active: the #NMActiveConnection to deactivate
1121  * @cancellable: a #GCancellable, or %NULL
1122  * @callback: callback to be called when the deactivation has completed
1123  * @user_data: caller-specific data passed to @callback
1124  *
1125  * Asynchronously deactivates an active #NMActiveConnection.
1126  **/
1127 void
1128 nm_client_deactivate_connection_async (NMClient *client,
1129                                        NMActiveConnection *active,
1130                                        GCancellable *cancellable,
1131                                        GAsyncReadyCallback callback,
1132                                        gpointer user_data)
1133 {
1134         GSimpleAsyncResult *simple;
1135
1136         g_return_if_fail (NM_IS_CLIENT (client));
1137         g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active));
1138
1139         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
1140                                             nm_client_deactivate_connection_async);
1141
1142         if (!_nm_client_check_nm_running (client, NULL)) {
1143                 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
1144                 g_simple_async_result_complete_in_idle (simple);
1145                 g_object_unref (simple);
1146                 return;
1147         }
1148
1149         nm_manager_deactivate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager,
1150                                                 active,
1151                                                 cancellable, deactivated_cb, simple);
1152 }
1153
1154 /**
1155  * nm_client_deactivate_connection_finish:
1156  * @client: a #NMClient
1157  * @result: the result passed to the #GAsyncReadyCallback
1158  * @error: location for a #GError, or %NULL
1159  *
1160  * Gets the result of a call to nm_client_deactivate_connection_async().
1161  *
1162  * Returns: success or failure
1163  **/
1164 gboolean
1165 nm_client_deactivate_connection_finish (NMClient *client,
1166                                         GAsyncResult *result,
1167                                         GError **error)
1168 {
1169         GSimpleAsyncResult *simple;
1170
1171         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1172         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
1173
1174         simple = G_SIMPLE_ASYNC_RESULT (result);
1175         if (g_simple_async_result_propagate_error (simple, error))
1176                 return FALSE;
1177         else
1178                 return g_simple_async_result_get_op_res_gboolean (simple);
1179 }
1180
1181 /****************************************************************/
1182 /* Connections                                                  */
1183 /****************************************************************/
1184
1185 /**
1186  * nm_client_get_connections:
1187  * @client: the %NMClient
1188  *
1189  * Returns: (transfer none) (element-type NMRemoteConnection): an array
1190  * containing all connections provided by the remote settings service.  The
1191  * returned array is owned by the #NMClient object and should not be modified.
1192  *
1193  * The connections are as received from D-Bus and might not validate according
1194  * to nm_connection_verify().
1195  **/
1196 const GPtrArray *
1197 nm_client_get_connections (NMClient *client)
1198 {
1199         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1200
1201         return nm_remote_settings_get_connections (NM_CLIENT_GET_PRIVATE (client)->settings);
1202 }
1203
1204 /**
1205  * nm_client_get_connection_by_id:
1206  * @client: the %NMClient
1207  * @id: the id of the remote connection
1208  *
1209  * Returns the first matching %NMRemoteConnection matching a given @id.
1210  *
1211  * Returns: (transfer none): the remote connection object on success, or %NULL if no
1212  *  matching object was found.
1213  *
1214  * The connection is as received from D-Bus and might not validate according
1215  * to nm_connection_verify().
1216  **/
1217 NMRemoteConnection *
1218 nm_client_get_connection_by_id (NMClient *client, const char *id)
1219 {
1220         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1221         g_return_val_if_fail (id != NULL, NULL);
1222
1223         return nm_remote_settings_get_connection_by_id (NM_CLIENT_GET_PRIVATE (client)->settings, id);
1224 }
1225
1226 /**
1227  * nm_client_get_connection_by_path:
1228  * @client: the %NMClient
1229  * @path: the D-Bus object path of the remote connection
1230  *
1231  * Returns the %NMRemoteConnection representing the connection at @path.
1232  *
1233  * Returns: (transfer none): the remote connection object on success, or %NULL if the object was
1234  *  not known
1235  *
1236  * The connection is as received from D-Bus and might not validate according
1237  * to nm_connection_verify().
1238  **/
1239 NMRemoteConnection *
1240 nm_client_get_connection_by_path (NMClient *client, const char *path)
1241 {
1242         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1243         g_return_val_if_fail (path != NULL, NULL);
1244
1245         return nm_remote_settings_get_connection_by_path (NM_CLIENT_GET_PRIVATE (client)->settings, path);
1246 }
1247
1248 /**
1249  * nm_client_get_connection_by_uuid:
1250  * @client: the %NMClient
1251  * @uuid: the UUID of the remote connection
1252  *
1253  * Returns the %NMRemoteConnection identified by @uuid.
1254  *
1255  * Returns: (transfer none): the remote connection object on success, or %NULL if the object was
1256  *  not known
1257  *
1258  * The connection is as received from D-Bus and might not validate according
1259  * to nm_connection_verify().
1260  **/
1261 NMRemoteConnection *
1262 nm_client_get_connection_by_uuid (NMClient *client, const char *uuid)
1263 {
1264         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1265         g_return_val_if_fail (uuid != NULL, NULL);
1266
1267         return nm_remote_settings_get_connection_by_uuid (NM_CLIENT_GET_PRIVATE (client)->settings, uuid);
1268 }
1269
1270 static void
1271 add_connection_cb (GObject *object,
1272                    GAsyncResult *result,
1273                    gpointer user_data)
1274 {
1275         GSimpleAsyncResult *simple = user_data;
1276         NMRemoteConnection *conn;
1277         GError *error = NULL;
1278
1279         conn = nm_remote_settings_add_connection_finish (NM_REMOTE_SETTINGS (object), result, &error);
1280         if (conn)
1281                 g_simple_async_result_set_op_res_gpointer (simple, conn, g_object_unref);
1282         else
1283                 g_simple_async_result_take_error (simple, error);
1284
1285         g_simple_async_result_complete (simple);
1286         g_object_unref (simple);
1287 }
1288
1289 /**
1290  * nm_client_add_connection_async:
1291  * @client: the %NMClient
1292  * @connection: the connection to add. Note that this object's settings will be
1293  *   added, not the object itself
1294  * @save_to_disk: whether to immediately save the connection to disk
1295  * @cancellable: a #GCancellable, or %NULL
1296  * @callback: (scope async): callback to be called when the add operation completes
1297  * @user_data: (closure): caller-specific data passed to @callback
1298  *
1299  * Requests that the remote settings service add the given settings to a new
1300  * connection.  If @save_to_disk is %TRUE, the connection is immediately written
1301  * to disk; otherwise it is initially only stored in memory, but may be saved
1302  * later by calling the connection's nm_remote_connection_commit_changes()
1303  * method.
1304  *
1305  * @connection is untouched by this function and only serves as a template of
1306  * the settings to add.  The #NMRemoteConnection object that represents what
1307  * NetworkManager actually added is returned to @callback when the addition
1308  * operation is complete.
1309  *
1310  * Note that the #NMRemoteConnection returned in @callback may not contain
1311  * identical settings to @connection as NetworkManager may perform automatic
1312  * completion and/or normalization of connection properties.
1313  **/
1314 void
1315 nm_client_add_connection_async (NMClient *client,
1316                                 NMConnection *connection,
1317                                 gboolean save_to_disk,
1318                                 GCancellable *cancellable,
1319                                 GAsyncReadyCallback callback,
1320                                 gpointer user_data)
1321 {
1322         GSimpleAsyncResult *simple;
1323         GError *error = NULL;
1324
1325         g_return_if_fail (NM_IS_CLIENT (client));
1326         g_return_if_fail (NM_IS_CONNECTION (connection));
1327
1328         if (!_nm_client_check_nm_running (client, &error)) {
1329                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
1330                 return;
1331         }
1332
1333         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
1334                                             nm_client_add_connection_async);
1335         nm_remote_settings_add_connection_async (NM_CLIENT_GET_PRIVATE (client)->settings,
1336                                                  connection, save_to_disk,
1337                                                  cancellable, add_connection_cb, simple);
1338 }
1339
1340 /**
1341  * nm_client_add_connection_finish:
1342  * @client: an #NMClient
1343  * @result: the result passed to the #GAsyncReadyCallback
1344  * @error: location for a #GError, or %NULL
1345  *
1346  * Gets the result of a call to nm_client_add_connection_async().
1347  *
1348  * Returns: (transfer full): the new #NMRemoteConnection on success, %NULL on
1349  *   failure, in which case @error will be set.
1350  **/
1351 NMRemoteConnection *
1352 nm_client_add_connection_finish (NMClient *client,
1353                                  GAsyncResult *result,
1354                                  GError **error)
1355 {
1356         GSimpleAsyncResult *simple;
1357
1358         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1359         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
1360
1361         simple = G_SIMPLE_ASYNC_RESULT (result);
1362         if (g_simple_async_result_propagate_error (simple, error))
1363                 return NULL;
1364         else
1365                 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1366 }
1367
1368 /**
1369  * nm_client_load_connections:
1370  * @client: the %NMClient
1371  * @filenames: %NULL-terminated array of filenames to load
1372  * @failures: (out) (transfer full): on return, a %NULL-terminated array of
1373  *   filenames that failed to load
1374  * @cancellable: a #GCancellable, or %NULL
1375  * @error: return location for #GError
1376  *
1377  * Requests that the remote settings service load or reload the given files,
1378  * adding or updating the connections described within.
1379  *
1380  * The changes to the indicated files will not yet be reflected in
1381  * @client's connections array when the function returns.
1382  *
1383  * If all of the indicated files were successfully loaded, the
1384  * function will return %TRUE, and @failures will be set to %NULL. If
1385  * NetworkManager tried to load the files, but some (or all) failed,
1386  * then @failures will be set to a %NULL-terminated array of the
1387  * filenames that failed to load.
1388  *
1389  * Returns: %TRUE if NetworkManager at least tried to load @filenames,
1390  * %FALSE if an error occurred (eg, permission denied).
1391  **/
1392 gboolean
1393 nm_client_load_connections (NMClient *client,
1394                             char **filenames,
1395                             char ***failures,
1396                             GCancellable *cancellable,
1397                             GError **error)
1398 {
1399         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1400         g_return_val_if_fail (filenames != NULL, FALSE);
1401
1402         if (!_nm_client_check_nm_running (client, error))
1403                 return FALSE;
1404
1405         return nm_remote_settings_load_connections (NM_CLIENT_GET_PRIVATE (client)->settings,
1406                                                     filenames, failures,
1407                                                     cancellable, error);
1408 }
1409
1410 static void
1411 load_connections_cb (GObject *object, GAsyncResult *result, gpointer user_data)
1412 {
1413         GSimpleAsyncResult *simple = user_data;
1414         GError *error = NULL;
1415         char **failures = NULL;
1416
1417         if (nm_remote_settings_load_connections_finish (NM_REMOTE_SETTINGS (object),
1418                                                         &failures, result, &error))
1419                 g_simple_async_result_set_op_res_gpointer (simple, failures, (GDestroyNotify) g_strfreev);
1420         else
1421                 g_simple_async_result_take_error (simple, error);
1422
1423         g_simple_async_result_complete (simple);
1424         g_object_unref (simple);
1425 }
1426
1427 /**
1428  * nm_client_load_connections_async:
1429  * @client: the %NMClient
1430  * @filenames: %NULL-terminated array of filenames to load
1431  * @cancellable: a #GCancellable, or %NULL
1432  * @callback: (scope async): callback to be called when the operation completes
1433  * @user_data: (closure): caller-specific data passed to @callback
1434  *
1435  * Requests that the remote settings service asynchronously load or reload the
1436  * given files, adding or updating the connections described within.
1437  *
1438  * See nm_client_load_connections() for more details.
1439  **/
1440 void
1441 nm_client_load_connections_async (NMClient *client,
1442                                   char **filenames,
1443                                   GCancellable *cancellable,
1444                                   GAsyncReadyCallback callback,
1445                                   gpointer user_data)
1446 {
1447         GSimpleAsyncResult *simple;
1448         GError *error = NULL;
1449
1450         g_return_if_fail (NM_IS_CLIENT (client));
1451         g_return_if_fail (filenames != NULL);
1452
1453         if (!_nm_client_check_nm_running (client, &error)) {
1454                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
1455                 return;
1456         }
1457
1458         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
1459                                             nm_client_load_connections_async);
1460         nm_remote_settings_load_connections_async (NM_CLIENT_GET_PRIVATE (client)->settings,
1461                                                    filenames,
1462                                                    cancellable, load_connections_cb, simple);
1463 }
1464
1465 /**
1466  * nm_client_load_connections_finish:
1467  * @client: the %NMClient
1468  * @failures: (out) (transfer full): on return, a %NULL-terminated array of
1469  *   filenames that failed to load
1470  * @result: the result passed to the #GAsyncReadyCallback
1471  * @error: location for a #GError, or %NULL
1472  *
1473  * Gets the result of an nm_client_load_connections_async() call.
1474
1475  * See nm_client_load_connections() for more details.
1476  *
1477  * Returns: %TRUE if NetworkManager at least tried to load @filenames,
1478  * %FALSE if an error occurred (eg, permission denied).
1479  **/
1480 gboolean
1481 nm_client_load_connections_finish (NMClient *client,
1482                                    char ***failures,
1483                                    GAsyncResult *result,
1484                                    GError **error)
1485 {
1486         GSimpleAsyncResult *simple;
1487
1488         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1489         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
1490
1491         simple = G_SIMPLE_ASYNC_RESULT (result);
1492         if (g_simple_async_result_propagate_error (simple, error))
1493                 return FALSE;
1494         else {
1495                 if (failures)
1496                         *failures = g_strdupv (g_simple_async_result_get_op_res_gpointer (simple));
1497                 return TRUE;
1498         }
1499 }
1500
1501 /**
1502  * nm_client_reload_connections:
1503  * @client: the #NMClient
1504  * @cancellable: a #GCancellable, or %NULL
1505  * @error: return location for #GError
1506  *
1507  * Requests that the remote settings service reload all connection
1508  * files from disk, adding, updating, and removing connections until
1509  * the in-memory state matches the on-disk state.
1510  *
1511  * Return value: %TRUE on success, %FALSE on failure
1512  **/
1513 gboolean
1514 nm_client_reload_connections (NMClient *client,
1515                               GCancellable *cancellable,
1516                               GError **error)
1517 {
1518         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1519
1520         if (!_nm_client_check_nm_running (client, error))
1521                 return FALSE;
1522
1523         return nm_remote_settings_reload_connections (NM_CLIENT_GET_PRIVATE (client)->settings,
1524                                                       cancellable, error);
1525 }
1526
1527 static void
1528 reload_connections_cb (GObject *object, GAsyncResult *result, gpointer user_data)
1529 {
1530         GSimpleAsyncResult *simple = user_data;
1531         GError *error = NULL;
1532
1533         if (nm_remote_settings_reload_connections_finish (NM_REMOTE_SETTINGS (object),
1534                                                           result, &error))
1535                 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
1536         else
1537                 g_simple_async_result_take_error (simple, error);
1538
1539         g_simple_async_result_complete (simple);
1540         g_object_unref (simple);
1541 }
1542
1543 /**
1544  * nm_client_reload_connections_async:
1545  * @client: the #NMClient
1546  * @cancellable: a #GCancellable, or %NULL
1547  * @callback: (scope async): callback to be called when the reload operation completes
1548  * @user_data: (closure): caller-specific data passed to @callback
1549  *
1550  * Requests that the remote settings service begin reloading all connection
1551  * files from disk, adding, updating, and removing connections until the
1552  * in-memory state matches the on-disk state.
1553  **/
1554 void
1555 nm_client_reload_connections_async (NMClient *client,
1556                                     GCancellable *cancellable,
1557                                     GAsyncReadyCallback callback,
1558                                     gpointer user_data)
1559 {
1560         GSimpleAsyncResult *simple;
1561         GError *error = NULL;
1562
1563         g_return_if_fail (NM_IS_CLIENT (client));
1564
1565         if (!_nm_client_check_nm_running (client, &error)) {
1566                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
1567                 return;
1568         }
1569
1570         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
1571                                             nm_client_reload_connections_async);
1572         nm_remote_settings_reload_connections_async (NM_CLIENT_GET_PRIVATE (client)->settings,
1573                                                      cancellable, reload_connections_cb, simple);
1574 }
1575
1576 /**
1577  * nm_client_reload_connections_finish:
1578  * @client: the #NMClient
1579  * @result: the result passed to the #GAsyncReadyCallback
1580  * @error: return location for #GError
1581  *
1582  * Gets the result of an nm_client_reload_connections_async() call.
1583  *
1584  * Return value: %TRUE on success, %FALSE on failure
1585  **/
1586 gboolean
1587 nm_client_reload_connections_finish (NMClient *client,
1588                                      GAsyncResult *result,
1589                                      GError **error)
1590 {
1591         GSimpleAsyncResult *simple;
1592
1593         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1594         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
1595
1596         simple = G_SIMPLE_ASYNC_RESULT (result);
1597         if (g_simple_async_result_propagate_error (simple, error))
1598                 return FALSE;
1599         else
1600                 return g_simple_async_result_get_op_res_gboolean (simple);
1601 }
1602
1603 /****************************************************************/
1604
1605 /**
1606  * nm_client_new:
1607  * @cancellable: a #GCancellable, or %NULL
1608  * @error: location for a #GError, or %NULL
1609  *
1610  * Creates a new #NMClient.
1611  *
1612  * Note that this will do blocking D-Bus calls to initialize the
1613  * client. You can use nm_client_new_async() if you want to avoid
1614  * that.
1615  *
1616  * Returns: a new #NMClient or NULL on an error
1617  **/
1618 NMClient *
1619 nm_client_new (GCancellable  *cancellable,
1620                GError       **error)
1621 {
1622         return g_initable_new (NM_TYPE_CLIENT, cancellable, error,
1623                                NULL);
1624 }
1625
1626 static void
1627 client_inited (GObject *source, GAsyncResult *result, gpointer user_data)
1628 {
1629         GSimpleAsyncResult *simple = user_data;
1630         GError *error = NULL;
1631
1632         if (!g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, &error))
1633                 g_simple_async_result_take_error (simple, error);
1634         else
1635                 g_simple_async_result_set_op_res_gpointer (simple, source, g_object_unref);
1636         g_simple_async_result_complete (simple);
1637         g_object_unref (simple);
1638 }
1639
1640 /**
1641  * nm_client_new_async:
1642  * @cancellable: a #GCancellable, or %NULL
1643  * @callback: callback to call when the client is created
1644  * @user_data: data for @callback
1645  *
1646  * Creates a new #NMClient and begins asynchronously initializing it.
1647  * @callback will be called when it is done; use
1648  * nm_client_new_finish() to get the result. Note that on an error,
1649  * the callback can be invoked with two first parameters as NULL.
1650  **/
1651 void
1652 nm_client_new_async (GCancellable *cancellable,
1653                      GAsyncReadyCallback callback,
1654                      gpointer user_data)
1655 {
1656         GSimpleAsyncResult *simple;
1657
1658         simple = g_simple_async_result_new (NULL, callback, user_data, nm_client_new_async);
1659
1660         g_async_initable_new_async (NM_TYPE_CLIENT, G_PRIORITY_DEFAULT,
1661                                     cancellable, client_inited, simple,
1662                                     NULL);
1663 }
1664
1665 /**
1666  * nm_client_new_finish:
1667  * @result: a #GAsyncResult
1668  * @error: location for a #GError, or %NULL
1669  *
1670  * Gets the result of an nm_client_new_async() call.
1671  *
1672  * Returns: a new #NMClient, or %NULL on error
1673  **/
1674 NMClient *
1675 nm_client_new_finish (GAsyncResult *result, GError **error)
1676 {
1677         GSimpleAsyncResult *simple;
1678
1679         g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, nm_client_new_async), NULL);
1680         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1681
1682         simple = G_SIMPLE_ASYNC_RESULT (result);
1683         if (g_simple_async_result_propagate_error (simple, error))
1684                 return NULL;
1685         else
1686                 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1687 }
1688
1689 static void
1690 subobject_notify (GObject *object,
1691                   GParamSpec *pspec,
1692                   gpointer client)
1693 {
1694         if (!g_str_has_suffix (pspec->name, "-internal"))
1695                 g_object_notify (client, pspec->name);
1696 }
1697
1698 static void
1699 manager_device_added (NMManager *manager,
1700                       NMDevice *device,
1701                       gpointer client)
1702 {
1703         g_signal_emit (client, signals[DEVICE_ADDED], 0, device);
1704 }
1705
1706 static void
1707 manager_device_removed (NMManager *manager,
1708                         NMDevice *device,
1709                         gpointer client)
1710 {
1711         g_signal_emit (client, signals[DEVICE_REMOVED], 0, device);
1712 }
1713
1714 static void
1715 manager_any_device_added (NMManager *manager,
1716                           NMDevice *device,
1717                           gpointer client)
1718 {
1719         g_signal_emit (client, signals[ANY_DEVICE_ADDED], 0, device);
1720 }
1721
1722 static void
1723 manager_any_device_removed (NMManager *manager,
1724                             NMDevice *device,
1725                             gpointer client)
1726 {
1727         g_signal_emit (client, signals[ANY_DEVICE_REMOVED], 0, device);
1728 }
1729
1730 static void
1731 manager_permission_changed (NMManager *manager,
1732                             NMClientPermission permission,
1733                             NMClientPermissionResult result,
1734                             gpointer client)
1735 {
1736         g_signal_emit (client, signals[PERMISSION_CHANGED], 0, permission, result);
1737 }
1738
1739 static void
1740 settings_connection_added (NMRemoteSettings *manager,
1741                            NMRemoteConnection *connection,
1742                            gpointer client)
1743 {
1744         g_signal_emit (client, signals[CONNECTION_ADDED], 0, connection);
1745 }
1746 static void
1747 settings_connection_removed (NMRemoteSettings *manager,
1748                              NMRemoteConnection *connection,
1749                              gpointer client)
1750 {
1751         g_signal_emit (client, signals[CONNECTION_REMOVED], 0, connection);
1752 }
1753
1754 static void
1755 constructed (GObject *object)
1756 {
1757         NMClient *client = NM_CLIENT (object);
1758         NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
1759
1760         priv->manager = g_object_new (NM_TYPE_MANAGER,
1761                                       NM_OBJECT_PATH, NM_DBUS_PATH,
1762                                       NULL);
1763         g_signal_connect (priv->manager, "notify",
1764                           G_CALLBACK (subobject_notify), client);
1765         g_signal_connect (priv->manager, "device-added",
1766                           G_CALLBACK (manager_device_added), client);
1767         g_signal_connect (priv->manager, "device-removed",
1768                           G_CALLBACK (manager_device_removed), client);
1769         g_signal_connect (priv->manager, "any-device-added",
1770                           G_CALLBACK (manager_any_device_added), client);
1771         g_signal_connect (priv->manager, "any-device-removed",
1772                           G_CALLBACK (manager_any_device_removed), client);
1773         g_signal_connect (priv->manager, "permission-changed",
1774                           G_CALLBACK (manager_permission_changed), client);
1775
1776         priv->settings = g_object_new (NM_TYPE_REMOTE_SETTINGS,
1777                                        NM_OBJECT_PATH, NM_DBUS_PATH_SETTINGS,
1778                                        NULL);
1779         g_signal_connect (priv->settings, "notify",
1780                           G_CALLBACK (subobject_notify), client);
1781         g_signal_connect (priv->settings, "connection-added",
1782                           G_CALLBACK (settings_connection_added), client);
1783         g_signal_connect (priv->settings, "connection-removed",
1784                           G_CALLBACK (settings_connection_removed), client);
1785
1786         G_OBJECT_CLASS (nm_client_parent_class)->constructed (object);
1787 }
1788
1789 static gboolean
1790 init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
1791 {
1792         NMClient *client = NM_CLIENT (initable);
1793         NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
1794
1795         if (!g_initable_init (G_INITABLE (priv->manager), cancellable, error))
1796                 return FALSE;
1797         if (!g_initable_init (G_INITABLE (priv->settings), cancellable, error))
1798                 return FALSE;
1799
1800         return TRUE;
1801 }
1802
1803 typedef struct {
1804         NMClient *client;
1805         GCancellable *cancellable;
1806         GSimpleAsyncResult *result;
1807         gboolean manager_inited;
1808         gboolean settings_inited;
1809 } NMClientInitData;
1810
1811 static void
1812 init_async_complete (NMClientInitData *init_data)
1813 {
1814         g_simple_async_result_complete (init_data->result);
1815         g_object_unref (init_data->result);
1816         g_clear_object (&init_data->cancellable);
1817         g_slice_free (NMClientInitData, init_data);
1818 }
1819
1820 static void
1821 init_async_inited_manager (GObject *object, GAsyncResult *result, gpointer user_data)
1822 {
1823         NMClientInitData *init_data = user_data;
1824         GError *error = NULL;
1825
1826         if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error))
1827                 g_simple_async_result_take_error (init_data->result, error);
1828
1829         init_data->manager_inited = TRUE;
1830         if (init_data->settings_inited)
1831                 init_async_complete (init_data);
1832 }
1833
1834 static void
1835 init_async_inited_settings (GObject *object, GAsyncResult *result, gpointer user_data)
1836 {
1837         NMClientInitData *init_data = user_data;
1838         GError *error = NULL;
1839
1840         if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error))
1841                 g_simple_async_result_take_error (init_data->result, error);
1842
1843         init_data->settings_inited = TRUE;
1844         if (init_data->manager_inited)
1845                 init_async_complete (init_data);
1846 }
1847
1848 static void
1849 init_async (GAsyncInitable *initable, int io_priority,
1850             GCancellable *cancellable, GAsyncReadyCallback callback,
1851             gpointer user_data)
1852 {
1853         NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (initable);
1854         NMClientInitData *init_data;
1855
1856         init_data = g_slice_new0 (NMClientInitData);
1857         init_data->client = NM_CLIENT (initable);
1858         init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1859         init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback,
1860                                                        user_data, init_async);
1861         g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE);
1862
1863         g_async_initable_init_async (G_ASYNC_INITABLE (priv->manager),
1864                                      G_PRIORITY_DEFAULT, init_data->cancellable,
1865                                      init_async_inited_manager, init_data);
1866         g_async_initable_init_async (G_ASYNC_INITABLE (priv->settings),
1867                                      G_PRIORITY_DEFAULT, init_data->cancellable,
1868                                      init_async_inited_settings, init_data);
1869 }
1870
1871 static gboolean
1872 init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
1873 {
1874         GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1875
1876         if (g_simple_async_result_propagate_error (simple, error))
1877                 return FALSE;
1878         else
1879                 return TRUE;
1880 }
1881
1882 static void
1883 dispose (GObject *object)
1884 {
1885         NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object);
1886
1887         if (priv->manager) {
1888                 g_signal_handlers_disconnect_by_data (priv->manager, object);
1889                 g_clear_object (&priv->manager);
1890         }
1891         if (priv->settings) {
1892                 g_signal_handlers_disconnect_by_data (priv->settings, object);
1893                 g_clear_object (&priv->settings);
1894         }
1895
1896         G_OBJECT_CLASS (nm_client_parent_class)->dispose (object);
1897 }
1898
1899 static void
1900 set_property (GObject *object, guint prop_id,
1901               const GValue *value, GParamSpec *pspec)
1902 {
1903         switch (prop_id) {
1904         case PROP_NETWORKING_ENABLED:
1905         case PROP_WIRELESS_ENABLED:
1906         case PROP_WWAN_ENABLED:
1907         case PROP_WIMAX_ENABLED:
1908                 g_object_set_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager),
1909                                        pspec->name, value);
1910                 break;
1911         default:
1912                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1913                 break;
1914         }
1915 }
1916
1917 static void
1918 get_property (GObject *object, guint prop_id,
1919               GValue *value, GParamSpec *pspec)
1920 {
1921         switch (prop_id) {
1922         case PROP_VERSION:
1923         case PROP_STATE:
1924         case PROP_STARTUP:
1925         case PROP_NM_RUNNING:
1926         case PROP_NETWORKING_ENABLED:
1927         case PROP_WIRELESS_ENABLED:
1928         case PROP_WIRELESS_HARDWARE_ENABLED:
1929         case PROP_WWAN_ENABLED:
1930         case PROP_WWAN_HARDWARE_ENABLED:
1931         case PROP_WIMAX_ENABLED:
1932         case PROP_WIMAX_HARDWARE_ENABLED:
1933         case PROP_ACTIVE_CONNECTIONS:
1934         case PROP_CONNECTIVITY:
1935         case PROP_PRIMARY_CONNECTION:
1936         case PROP_ACTIVATING_CONNECTION:
1937         case PROP_DEVICES:
1938         case PROP_METERED:
1939         case PROP_ALL_DEVICES:
1940                 g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager),
1941                                        pspec->name, value);
1942                 break;
1943         case PROP_CONNECTIONS:
1944         case PROP_HOSTNAME:
1945         case PROP_CAN_MODIFY:
1946                 g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->settings),
1947                                        pspec->name, value);
1948                 break;
1949         default:
1950                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1951                 break;
1952         }
1953 }
1954
1955 static void
1956 nm_client_class_init (NMClientClass *client_class)
1957 {
1958         GObjectClass *object_class = G_OBJECT_CLASS (client_class);
1959
1960         g_type_class_add_private (client_class, sizeof (NMClientPrivate));
1961
1962         /* virtual methods */
1963         object_class->constructed = constructed;
1964         object_class->set_property = set_property;
1965         object_class->get_property = get_property;
1966         object_class->dispose = dispose;
1967
1968         /* properties */
1969
1970         /**
1971          * NMClient:version:
1972          *
1973          * The NetworkManager version.
1974          **/
1975         g_object_class_install_property
1976                 (object_class, PROP_VERSION,
1977                  g_param_spec_string (NM_CLIENT_VERSION, "", "",
1978                                       NULL,
1979                                       G_PARAM_READABLE |
1980                                       G_PARAM_STATIC_STRINGS));
1981
1982         /**
1983          * NMClient:state:
1984          *
1985          * The current daemon state.
1986          **/
1987         g_object_class_install_property
1988                 (object_class, PROP_STATE,
1989                  g_param_spec_enum (NM_CLIENT_STATE, "", "",
1990                                     NM_TYPE_STATE,
1991                                     NM_STATE_UNKNOWN,
1992                                     G_PARAM_READABLE |
1993                                     G_PARAM_STATIC_STRINGS));
1994
1995         /**
1996          * NMClient:startup:
1997          *
1998          * Whether the daemon is still starting up.
1999          **/
2000         g_object_class_install_property
2001                 (object_class, PROP_STARTUP,
2002                  g_param_spec_boolean (NM_CLIENT_STARTUP, "", "",
2003                                        FALSE,
2004                                        G_PARAM_READABLE |
2005                                        G_PARAM_STATIC_STRINGS));
2006
2007         /**
2008          * NMClient:nm-running:
2009          *
2010          * Whether the daemon is running.
2011          **/
2012         g_object_class_install_property
2013                 (object_class, PROP_NM_RUNNING,
2014                  g_param_spec_boolean (NM_CLIENT_NM_RUNNING, "", "",
2015                                        FALSE,
2016                                        G_PARAM_READABLE |
2017                                        G_PARAM_STATIC_STRINGS));
2018
2019         /**
2020          * NMClient:networking-enabled:
2021          *
2022          * Whether networking is enabled.
2023          **/
2024         g_object_class_install_property
2025                 (object_class, PROP_NETWORKING_ENABLED,
2026                  g_param_spec_boolean (NM_CLIENT_NETWORKING_ENABLED, "", "",
2027                                        TRUE,
2028                                        G_PARAM_READWRITE |
2029                                        G_PARAM_STATIC_STRINGS));
2030
2031         /**
2032          * NMClient:wireless-enabled:
2033          *
2034          * Whether wireless is enabled.
2035          **/
2036         g_object_class_install_property
2037                 (object_class, PROP_WIRELESS_ENABLED,
2038                  g_param_spec_boolean (NM_CLIENT_WIRELESS_ENABLED, "", "",
2039                                        FALSE,
2040                                        G_PARAM_READWRITE |
2041                                        G_PARAM_STATIC_STRINGS));
2042
2043         /**
2044          * NMClient:wireless-hardware-enabled:
2045          *
2046          * Whether the wireless hardware is enabled.
2047          **/
2048         g_object_class_install_property
2049                 (object_class, PROP_WIRELESS_HARDWARE_ENABLED,
2050                  g_param_spec_boolean (NM_CLIENT_WIRELESS_HARDWARE_ENABLED, "", "",
2051                                        TRUE,
2052                                        G_PARAM_READABLE |
2053                                        G_PARAM_STATIC_STRINGS));
2054
2055         /**
2056          * NMClient:wwan-enabled:
2057          *
2058          * Whether WWAN functionality is enabled.
2059          **/
2060         g_object_class_install_property
2061                 (object_class, PROP_WWAN_ENABLED,
2062                  g_param_spec_boolean (NM_CLIENT_WWAN_ENABLED, "", "",
2063                                        FALSE,
2064                                        G_PARAM_READWRITE |
2065                                        G_PARAM_STATIC_STRINGS));
2066
2067         /**
2068          * NMClient:wwan-hardware-enabled:
2069          *
2070          * Whether the WWAN hardware is enabled.
2071          **/
2072         g_object_class_install_property
2073                 (object_class, PROP_WWAN_HARDWARE_ENABLED,
2074                  g_param_spec_boolean (NM_CLIENT_WWAN_HARDWARE_ENABLED, "", "",
2075                                        FALSE,
2076                                        G_PARAM_READABLE |
2077                                        G_PARAM_STATIC_STRINGS));
2078
2079         /**
2080          * NMClient:wimax-enabled:
2081          *
2082          * Whether WiMAX functionality is enabled.
2083          **/
2084         g_object_class_install_property
2085                 (object_class, PROP_WIMAX_ENABLED,
2086                  g_param_spec_boolean (NM_CLIENT_WIMAX_ENABLED, "", "",
2087                                        FALSE,
2088                                        G_PARAM_READWRITE |
2089                                        G_PARAM_STATIC_STRINGS));
2090
2091         /**
2092          * NMClient:wimax-hardware-enabled:
2093          *
2094          * Whether the WiMAX hardware is enabled.
2095          **/
2096         g_object_class_install_property
2097                 (object_class, PROP_WIMAX_HARDWARE_ENABLED,
2098                  g_param_spec_boolean (NM_CLIENT_WIMAX_HARDWARE_ENABLED, "", "",
2099                                        FALSE,
2100                                        G_PARAM_READABLE |
2101                                        G_PARAM_STATIC_STRINGS));
2102
2103         /**
2104          * NMClient:active-connections:
2105          *
2106          * The active connections.
2107          *
2108          * Element-type: NMActiveConnection
2109          **/
2110         g_object_class_install_property
2111                 (object_class, PROP_ACTIVE_CONNECTIONS,
2112                  g_param_spec_boxed (NM_CLIENT_ACTIVE_CONNECTIONS, "", "",
2113                                      G_TYPE_PTR_ARRAY,
2114                                      G_PARAM_READABLE |
2115                                      G_PARAM_STATIC_STRINGS));
2116
2117         /**
2118          * NMClient:connectivity:
2119          *
2120          * The network connectivity state.
2121          */
2122         g_object_class_install_property
2123                 (object_class, PROP_CONNECTIVITY,
2124                  g_param_spec_enum (NM_CLIENT_CONNECTIVITY, "", "",
2125                                     NM_TYPE_CONNECTIVITY_STATE,
2126                                     NM_CONNECTIVITY_UNKNOWN,
2127                                     G_PARAM_READABLE |
2128                                     G_PARAM_STATIC_STRINGS));
2129
2130         /**
2131          * NMClient:primary-connection:
2132          *
2133          * The #NMActiveConnection of the device with the default route;
2134          * see nm_client_get_primary_connection() for more details.
2135          **/
2136         g_object_class_install_property
2137                 (object_class, PROP_PRIMARY_CONNECTION,
2138                  g_param_spec_object (NM_CLIENT_PRIMARY_CONNECTION, "", "",
2139                                       NM_TYPE_ACTIVE_CONNECTION,
2140                                       G_PARAM_READABLE |
2141                                       G_PARAM_STATIC_STRINGS));
2142
2143         /**
2144          * NMClient:activating-connection:
2145          *
2146          * The #NMActiveConnection of the activating connection that is
2147          * likely to become the new #NMClient:primary-connection.
2148          **/
2149         g_object_class_install_property
2150                 (object_class, PROP_ACTIVATING_CONNECTION,
2151                  g_param_spec_object (NM_CLIENT_ACTIVATING_CONNECTION, "", "",
2152                                       NM_TYPE_ACTIVE_CONNECTION,
2153                                       G_PARAM_READABLE |
2154                                       G_PARAM_STATIC_STRINGS));
2155
2156         /**
2157          * NMClient:devices:
2158          *
2159          * List of real network devices.  Does not include placeholder devices.
2160          *
2161          * Element-type: NMDevice
2162          **/
2163         g_object_class_install_property
2164                 (object_class, PROP_DEVICES,
2165                  g_param_spec_boxed (NM_CLIENT_DEVICES, "", "",
2166                                      G_TYPE_PTR_ARRAY,
2167                                      G_PARAM_READABLE |
2168                                      G_PARAM_STATIC_STRINGS));
2169
2170         /**
2171          * NMClient:all-devices:
2172          *
2173          * List of both real devices and device placeholders.
2174          *
2175          * Element-type: NMDevice
2176          * Since: 1.2
2177          **/
2178         g_object_class_install_property
2179                 (object_class, PROP_ALL_DEVICES,
2180                  g_param_spec_boxed (NM_CLIENT_ALL_DEVICES, "", "",
2181                                      G_TYPE_PTR_ARRAY,
2182                                      G_PARAM_READABLE |
2183                                      G_PARAM_STATIC_STRINGS));
2184
2185         /**
2186          * NMClient:connections:
2187          *
2188          * The list of configured connections that are available to the user. (Note
2189          * that this differs from the underlying D-Bus property, which may also
2190          * contain the object paths of connections that the user does not have
2191          * permission to read the details of.)
2192          *
2193          * Element-type: NMRemoteConnection
2194          */
2195         g_object_class_install_property
2196                 (object_class, PROP_CONNECTIONS,
2197                  g_param_spec_boxed (NM_CLIENT_CONNECTIONS, "", "",
2198                                      G_TYPE_PTR_ARRAY,
2199                                      G_PARAM_READABLE |
2200                                      G_PARAM_STATIC_STRINGS));
2201
2202         /**
2203          * NMClient:hostname:
2204          *
2205          * The machine hostname stored in persistent configuration. This can be
2206          * modified by calling nm_client_save_hostname().
2207          */
2208         g_object_class_install_property
2209                 (object_class, PROP_HOSTNAME,
2210                  g_param_spec_string (NM_CLIENT_HOSTNAME, "", "",
2211                                       NULL,
2212                                       G_PARAM_READABLE |
2213                                       G_PARAM_STATIC_STRINGS));
2214
2215         /**
2216          * NMClient:can-modify:
2217          *
2218          * If %TRUE, adding and modifying connections is supported.
2219          */
2220         g_object_class_install_property
2221                 (object_class, PROP_CAN_MODIFY,
2222                  g_param_spec_boolean (NM_CLIENT_CAN_MODIFY, "", "",
2223                                        FALSE,
2224                                        G_PARAM_READABLE |
2225                                        G_PARAM_STATIC_STRINGS));
2226
2227         /**
2228          * NMClient:metered:
2229          *
2230          * Whether the connectivity is metered.
2231          *
2232          * Since: 1.2
2233          **/
2234         g_object_class_install_property
2235                 (object_class, PROP_METERED,
2236                  g_param_spec_uint (NM_CLIENT_METERED, "", "",
2237                                     0, G_MAXUINT32, NM_METERED_UNKNOWN,
2238                                     G_PARAM_READABLE |
2239                                     G_PARAM_STATIC_STRINGS));
2240
2241         /* signals */
2242
2243         /**
2244          * NMClient::device-added:
2245          * @client: the client that received the signal
2246          * @device: (type NMDevice): the new device
2247          *
2248          * Notifies that a #NMDevice is added.  This signal is not emitted for
2249          * placeholder devices.
2250          **/
2251         signals[DEVICE_ADDED] =
2252                 g_signal_new (NM_CLIENT_DEVICE_ADDED,
2253                               G_OBJECT_CLASS_TYPE (object_class),
2254                               G_SIGNAL_RUN_FIRST,
2255                               G_STRUCT_OFFSET (NMClientClass, device_added),
2256                               NULL, NULL, NULL,
2257                               G_TYPE_NONE, 1,
2258                               G_TYPE_OBJECT);
2259
2260         /**
2261          * NMClient::device-removed:
2262          * @client: the client that received the signal
2263          * @device: (type NMDevice): the removed device
2264          *
2265          * Notifies that a #NMDevice is removed.  This signal is not emitted for
2266          * placeholder devices.
2267          **/
2268         signals[DEVICE_REMOVED] =
2269                 g_signal_new (NM_CLIENT_DEVICE_REMOVED,
2270                               G_OBJECT_CLASS_TYPE (object_class),
2271                               G_SIGNAL_RUN_FIRST,
2272                               G_STRUCT_OFFSET (NMClientClass, device_removed),
2273                               NULL, NULL, NULL,
2274                               G_TYPE_NONE, 1,
2275                               G_TYPE_OBJECT);
2276
2277         /**
2278          * NMClient::any-device-added:
2279          * @client: the client that received the signal
2280          * @device: (type NMDevice): the new device
2281          *
2282          * Notifies that a #NMDevice is added.  This signal is emitted for both
2283          * regular devices and placeholder devices.
2284          **/
2285         signals[ANY_DEVICE_ADDED] =
2286                 g_signal_new (NM_CLIENT_ANY_DEVICE_ADDED,
2287                               G_OBJECT_CLASS_TYPE (object_class),
2288                               G_SIGNAL_RUN_FIRST,
2289                               G_STRUCT_OFFSET (NMClientClass, any_device_added),
2290                               NULL, NULL, NULL,
2291                               G_TYPE_NONE, 1,
2292                               G_TYPE_OBJECT);
2293
2294         /**
2295          * NMClient::any-device-removed:
2296          * @client: the client that received the signal
2297          * @device: (type NMDevice): the removed device
2298          *
2299          * Notifies that a #NMDevice is removed.  This signal is emitted for both
2300          * regular devices and placeholder devices.
2301          **/
2302         signals[ANY_DEVICE_REMOVED] =
2303                 g_signal_new (NM_CLIENT_ANY_DEVICE_REMOVED,
2304                               G_OBJECT_CLASS_TYPE (object_class),
2305                               G_SIGNAL_RUN_FIRST,
2306                               G_STRUCT_OFFSET (NMClientClass, any_device_removed),
2307                               NULL, NULL, NULL,
2308                               G_TYPE_NONE, 1,
2309                               G_TYPE_OBJECT);
2310
2311         /**
2312          * NMClient::permission-changed:
2313          * @client: the client that received the signal
2314          * @permission: a permission from #NMClientPermission
2315          * @result: the permission's result, one of #NMClientPermissionResult
2316          *
2317          * Notifies that a permission has changed
2318          **/
2319         signals[PERMISSION_CHANGED] =
2320                 g_signal_new (NM_CLIENT_PERMISSION_CHANGED,
2321                               G_OBJECT_CLASS_TYPE (object_class),
2322                               G_SIGNAL_RUN_FIRST,
2323                               0, NULL, NULL, NULL,
2324                               G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2325         /**
2326          * NMClient::connection-added:
2327          * @client: the settings object that received the signal
2328          * @connection: the new connection
2329          *
2330          * Notifies that a #NMConnection has been added.
2331          **/
2332         signals[CONNECTION_ADDED] =
2333                 g_signal_new (NM_CLIENT_CONNECTION_ADDED,
2334                               G_OBJECT_CLASS_TYPE (object_class),
2335                               G_SIGNAL_RUN_FIRST,
2336                               G_STRUCT_OFFSET (NMClientClass, connection_added),
2337                               NULL, NULL, NULL,
2338                               G_TYPE_NONE, 1,
2339                               NM_TYPE_REMOTE_CONNECTION);
2340
2341         /**
2342          * NMClient::connection-removed:
2343          * @client: the settings object that received the signal
2344          * @connection: the removed connection
2345          *
2346          * Notifies that a #NMConnection has been removed.
2347          **/
2348         signals[CONNECTION_REMOVED] =
2349                 g_signal_new (NM_CLIENT_CONNECTION_REMOVED,
2350                               G_OBJECT_CLASS_TYPE (object_class),
2351                               G_SIGNAL_RUN_FIRST,
2352                               G_STRUCT_OFFSET (NMClientClass, connection_removed),
2353                               NULL, NULL, NULL,
2354                               G_TYPE_NONE, 1,
2355                               NM_TYPE_REMOTE_CONNECTION);
2356 }
2357
2358 static void
2359 nm_client_initable_iface_init (GInitableIface *iface)
2360 {
2361         iface->init = init_sync;
2362 }
2363
2364 static void
2365 nm_client_async_initable_iface_init (GAsyncInitableIface *iface)
2366 {
2367         iface->init_async = init_async;
2368         iface->init_finish = init_finish;
2369 }