57a43ca8dc6ad629c55ab471be09a1bac993e5d7
[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 const GPtrArray *
1194 nm_client_get_connections (NMClient *client)
1195 {
1196         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1197
1198         return nm_remote_settings_get_connections (NM_CLIENT_GET_PRIVATE (client)->settings);
1199 }
1200
1201 /**
1202  * nm_client_get_connection_by_id:
1203  * @client: the %NMClient
1204  * @id: the id of the remote connection
1205  *
1206  * Returns the first matching %NMRemoteConnection matching a given @id.
1207  *
1208  * Returns: (transfer none): the remote connection object on success, or %NULL if no
1209  *  matching object was found.
1210  **/
1211 NMRemoteConnection *
1212 nm_client_get_connection_by_id (NMClient *client, const char *id)
1213 {
1214         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1215         g_return_val_if_fail (id != NULL, NULL);
1216
1217         return nm_remote_settings_get_connection_by_id (NM_CLIENT_GET_PRIVATE (client)->settings, id);
1218 }
1219
1220 /**
1221  * nm_client_get_connection_by_path:
1222  * @client: the %NMClient
1223  * @path: the D-Bus object path of the remote connection
1224  *
1225  * Returns the %NMRemoteConnection representing the connection at @path.
1226  *
1227  * Returns: (transfer none): the remote connection object on success, or %NULL if the object was
1228  *  not known
1229  **/
1230 NMRemoteConnection *
1231 nm_client_get_connection_by_path (NMClient *client, const char *path)
1232 {
1233         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1234         g_return_val_if_fail (path != NULL, NULL);
1235
1236         return nm_remote_settings_get_connection_by_path (NM_CLIENT_GET_PRIVATE (client)->settings, path);
1237 }
1238
1239 /**
1240  * nm_client_get_connection_by_uuid:
1241  * @client: the %NMClient
1242  * @uuid: the UUID of the remote connection
1243  *
1244  * Returns the %NMRemoteConnection identified by @uuid.
1245  *
1246  * Returns: (transfer none): the remote connection object on success, or %NULL if the object was
1247  *  not known
1248  **/
1249 NMRemoteConnection *
1250 nm_client_get_connection_by_uuid (NMClient *client, const char *uuid)
1251 {
1252         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1253         g_return_val_if_fail (uuid != NULL, NULL);
1254
1255         return nm_remote_settings_get_connection_by_uuid (NM_CLIENT_GET_PRIVATE (client)->settings, uuid);
1256 }
1257
1258 static void
1259 add_connection_cb (GObject *object,
1260                    GAsyncResult *result,
1261                    gpointer user_data)
1262 {
1263         GSimpleAsyncResult *simple = user_data;
1264         NMRemoteConnection *conn;
1265         GError *error = NULL;
1266
1267         conn = nm_remote_settings_add_connection_finish (NM_REMOTE_SETTINGS (object), result, &error);
1268         if (conn)
1269                 g_simple_async_result_set_op_res_gpointer (simple, conn, g_object_unref);
1270         else
1271                 g_simple_async_result_take_error (simple, error);
1272
1273         g_simple_async_result_complete (simple);
1274         g_object_unref (simple);
1275 }
1276
1277 /**
1278  * nm_client_add_connection_async:
1279  * @client: the %NMClient
1280  * @connection: the connection to add. Note that this object's settings will be
1281  *   added, not the object itself
1282  * @save_to_disk: whether to immediately save the connection to disk
1283  * @cancellable: a #GCancellable, or %NULL
1284  * @callback: (scope async): callback to be called when the add operation completes
1285  * @user_data: (closure): caller-specific data passed to @callback
1286  *
1287  * Requests that the remote settings service add the given settings to a new
1288  * connection.  If @save_to_disk is %TRUE, the connection is immediately written
1289  * to disk; otherwise it is initially only stored in memory, but may be saved
1290  * later by calling the connection's nm_remote_connection_commit_changes()
1291  * method.
1292  *
1293  * @connection is untouched by this function and only serves as a template of
1294  * the settings to add.  The #NMRemoteConnection object that represents what
1295  * NetworkManager actually added is returned to @callback when the addition
1296  * operation is complete.
1297  *
1298  * Note that the #NMRemoteConnection returned in @callback may not contain
1299  * identical settings to @connection as NetworkManager may perform automatic
1300  * completion and/or normalization of connection properties.
1301  **/
1302 void
1303 nm_client_add_connection_async (NMClient *client,
1304                                 NMConnection *connection,
1305                                 gboolean save_to_disk,
1306                                 GCancellable *cancellable,
1307                                 GAsyncReadyCallback callback,
1308                                 gpointer user_data)
1309 {
1310         GSimpleAsyncResult *simple;
1311         GError *error = NULL;
1312
1313         g_return_if_fail (NM_IS_CLIENT (client));
1314         g_return_if_fail (NM_IS_CONNECTION (connection));
1315
1316         if (!_nm_client_check_nm_running (client, &error)) {
1317                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
1318                 return;
1319         }
1320
1321         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
1322                                             nm_client_add_connection_async);
1323         nm_remote_settings_add_connection_async (NM_CLIENT_GET_PRIVATE (client)->settings,
1324                                                  connection, save_to_disk,
1325                                                  cancellable, add_connection_cb, simple);
1326 }
1327
1328 /**
1329  * nm_client_add_connection_finish:
1330  * @client: an #NMClient
1331  * @result: the result passed to the #GAsyncReadyCallback
1332  * @error: location for a #GError, or %NULL
1333  *
1334  * Gets the result of a call to nm_client_add_connection_async().
1335  *
1336  * Returns: (transfer full): the new #NMRemoteConnection on success, %NULL on
1337  *   failure, in which case @error will be set.
1338  **/
1339 NMRemoteConnection *
1340 nm_client_add_connection_finish (NMClient *client,
1341                                  GAsyncResult *result,
1342                                  GError **error)
1343 {
1344         GSimpleAsyncResult *simple;
1345
1346         g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
1347         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
1348
1349         simple = G_SIMPLE_ASYNC_RESULT (result);
1350         if (g_simple_async_result_propagate_error (simple, error))
1351                 return NULL;
1352         else
1353                 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1354 }
1355
1356 /**
1357  * nm_client_load_connections:
1358  * @client: the %NMClient
1359  * @filenames: %NULL-terminated array of filenames to load
1360  * @failures: (out) (transfer full): on return, a %NULL-terminated array of
1361  *   filenames that failed to load
1362  * @cancellable: a #GCancellable, or %NULL
1363  * @error: return location for #GError
1364  *
1365  * Requests that the remote settings service load or reload the given files,
1366  * adding or updating the connections described within.
1367  *
1368  * The changes to the indicated files will not yet be reflected in
1369  * @client's connections array when the function returns.
1370  *
1371  * If all of the indicated files were successfully loaded, the
1372  * function will return %TRUE, and @failures will be set to %NULL. If
1373  * NetworkManager tried to load the files, but some (or all) failed,
1374  * then @failures will be set to a %NULL-terminated array of the
1375  * filenames that failed to load.
1376  *
1377  * Returns: %TRUE if NetworkManager at least tried to load @filenames,
1378  * %FALSE if an error occurred (eg, permission denied).
1379  **/
1380 gboolean
1381 nm_client_load_connections (NMClient *client,
1382                             char **filenames,
1383                             char ***failures,
1384                             GCancellable *cancellable,
1385                             GError **error)
1386 {
1387         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1388         g_return_val_if_fail (filenames != NULL, FALSE);
1389
1390         if (!_nm_client_check_nm_running (client, error))
1391                 return FALSE;
1392
1393         return nm_remote_settings_load_connections (NM_CLIENT_GET_PRIVATE (client)->settings,
1394                                                     filenames, failures,
1395                                                     cancellable, error);
1396 }
1397
1398 static void
1399 load_connections_cb (GObject *object, GAsyncResult *result, gpointer user_data)
1400 {
1401         GSimpleAsyncResult *simple = user_data;
1402         GError *error = NULL;
1403         char **failures = NULL;
1404
1405         if (nm_remote_settings_load_connections_finish (NM_REMOTE_SETTINGS (object),
1406                                                         &failures, result, &error))
1407                 g_simple_async_result_set_op_res_gpointer (simple, failures, (GDestroyNotify) g_strfreev);
1408         else
1409                 g_simple_async_result_take_error (simple, error);
1410
1411         g_simple_async_result_complete (simple);
1412         g_object_unref (simple);
1413 }
1414
1415 /**
1416  * nm_client_load_connections_async:
1417  * @client: the %NMClient
1418  * @filenames: %NULL-terminated array of filenames to load
1419  * @cancellable: a #GCancellable, or %NULL
1420  * @callback: (scope async): callback to be called when the operation completes
1421  * @user_data: (closure): caller-specific data passed to @callback
1422  *
1423  * Requests that the remote settings service asynchronously load or reload the
1424  * given files, adding or updating the connections described within.
1425  *
1426  * See nm_client_load_connections() for more details.
1427  **/
1428 void
1429 nm_client_load_connections_async (NMClient *client,
1430                                   char **filenames,
1431                                   GCancellable *cancellable,
1432                                   GAsyncReadyCallback callback,
1433                                   gpointer user_data)
1434 {
1435         GSimpleAsyncResult *simple;
1436         GError *error = NULL;
1437
1438         g_return_if_fail (NM_IS_CLIENT (client));
1439         g_return_if_fail (filenames != NULL);
1440
1441         if (!_nm_client_check_nm_running (client, &error)) {
1442                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
1443                 return;
1444         }
1445
1446         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
1447                                             nm_client_load_connections_async);
1448         nm_remote_settings_load_connections_async (NM_CLIENT_GET_PRIVATE (client)->settings,
1449                                                    filenames,
1450                                                    cancellable, load_connections_cb, simple);
1451 }
1452
1453 /**
1454  * nm_client_load_connections_finish:
1455  * @client: the %NMClient
1456  * @failures: (out) (transfer full): on return, a %NULL-terminated array of
1457  *   filenames that failed to load
1458  * @result: the result passed to the #GAsyncReadyCallback
1459  * @error: location for a #GError, or %NULL
1460  *
1461  * Gets the result of an nm_client_load_connections_async() call.
1462
1463  * See nm_client_load_connections() for more details.
1464  *
1465  * Returns: %TRUE if NetworkManager at least tried to load @filenames,
1466  * %FALSE if an error occurred (eg, permission denied).
1467  **/
1468 gboolean
1469 nm_client_load_connections_finish (NMClient *client,
1470                                    char ***failures,
1471                                    GAsyncResult *result,
1472                                    GError **error)
1473 {
1474         GSimpleAsyncResult *simple;
1475
1476         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1477         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
1478
1479         simple = G_SIMPLE_ASYNC_RESULT (result);
1480         if (g_simple_async_result_propagate_error (simple, error))
1481                 return FALSE;
1482         else {
1483                 if (failures)
1484                         *failures = g_strdupv (g_simple_async_result_get_op_res_gpointer (simple));
1485                 return TRUE;
1486         }
1487 }
1488
1489 /**
1490  * nm_client_reload_connections:
1491  * @client: the #NMClient
1492  * @cancellable: a #GCancellable, or %NULL
1493  * @error: return location for #GError
1494  *
1495  * Requests that the remote settings service reload all connection
1496  * files from disk, adding, updating, and removing connections until
1497  * the in-memory state matches the on-disk state.
1498  *
1499  * Return value: %TRUE on success, %FALSE on failure
1500  **/
1501 gboolean
1502 nm_client_reload_connections (NMClient *client,
1503                               GCancellable *cancellable,
1504                               GError **error)
1505 {
1506         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1507
1508         if (!_nm_client_check_nm_running (client, error))
1509                 return FALSE;
1510
1511         return nm_remote_settings_reload_connections (NM_CLIENT_GET_PRIVATE (client)->settings,
1512                                                       cancellable, error);
1513 }
1514
1515 static void
1516 reload_connections_cb (GObject *object, GAsyncResult *result, gpointer user_data)
1517 {
1518         GSimpleAsyncResult *simple = user_data;
1519         GError *error = NULL;
1520
1521         if (nm_remote_settings_reload_connections_finish (NM_REMOTE_SETTINGS (object),
1522                                                           result, &error))
1523                 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
1524         else
1525                 g_simple_async_result_take_error (simple, error);
1526
1527         g_simple_async_result_complete (simple);
1528         g_object_unref (simple);
1529 }
1530
1531 /**
1532  * nm_client_reload_connections_async:
1533  * @client: the #NMClient
1534  * @cancellable: a #GCancellable, or %NULL
1535  * @callback: (scope async): callback to be called when the reload operation completes
1536  * @user_data: (closure): caller-specific data passed to @callback
1537  *
1538  * Requests that the remote settings service begin reloading all connection
1539  * files from disk, adding, updating, and removing connections until the
1540  * in-memory state matches the on-disk state.
1541  **/
1542 void
1543 nm_client_reload_connections_async (NMClient *client,
1544                                     GCancellable *cancellable,
1545                                     GAsyncReadyCallback callback,
1546                                     gpointer user_data)
1547 {
1548         GSimpleAsyncResult *simple;
1549         GError *error = NULL;
1550
1551         g_return_if_fail (NM_IS_CLIENT (client));
1552
1553         if (!_nm_client_check_nm_running (client, &error)) {
1554                 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
1555                 return;
1556         }
1557
1558         simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
1559                                             nm_client_reload_connections_async);
1560         nm_remote_settings_reload_connections_async (NM_CLIENT_GET_PRIVATE (client)->settings,
1561                                                      cancellable, reload_connections_cb, simple);
1562 }
1563
1564 /**
1565  * nm_client_reload_connections_finish:
1566  * @client: the #NMClient
1567  * @result: the result passed to the #GAsyncReadyCallback
1568  * @error: return location for #GError
1569  *
1570  * Gets the result of an nm_client_reload_connections_async() call.
1571  *
1572  * Return value: %TRUE on success, %FALSE on failure
1573  **/
1574 gboolean
1575 nm_client_reload_connections_finish (NMClient *client,
1576                                      GAsyncResult *result,
1577                                      GError **error)
1578 {
1579         GSimpleAsyncResult *simple;
1580
1581         g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
1582         g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
1583
1584         simple = G_SIMPLE_ASYNC_RESULT (result);
1585         if (g_simple_async_result_propagate_error (simple, error))
1586                 return FALSE;
1587         else
1588                 return g_simple_async_result_get_op_res_gboolean (simple);
1589 }
1590
1591 /****************************************************************/
1592
1593 /**
1594  * nm_client_new:
1595  * @cancellable: a #GCancellable, or %NULL
1596  * @error: location for a #GError, or %NULL
1597  *
1598  * Creates a new #NMClient.
1599  *
1600  * Note that this will do blocking D-Bus calls to initialize the
1601  * client. You can use nm_client_new_async() if you want to avoid
1602  * that.
1603  *
1604  * Returns: a new #NMClient or NULL on an error
1605  **/
1606 NMClient *
1607 nm_client_new (GCancellable  *cancellable,
1608                GError       **error)
1609 {
1610         return g_initable_new (NM_TYPE_CLIENT, cancellable, error,
1611                                NULL);
1612 }
1613
1614 static void
1615 client_inited (GObject *source, GAsyncResult *result, gpointer user_data)
1616 {
1617         GSimpleAsyncResult *simple = user_data;
1618         GError *error = NULL;
1619
1620         if (!g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, &error))
1621                 g_simple_async_result_take_error (simple, error);
1622         else
1623                 g_simple_async_result_set_op_res_gpointer (simple, source, g_object_unref);
1624         g_simple_async_result_complete (simple);
1625         g_object_unref (simple);
1626 }
1627
1628 /**
1629  * nm_client_new_async:
1630  * @cancellable: a #GCancellable, or %NULL
1631  * @callback: callback to call when the client is created
1632  * @user_data: data for @callback
1633  *
1634  * Creates a new #NMClient and begins asynchronously initializing it.
1635  * @callback will be called when it is done; use
1636  * nm_client_new_finish() to get the result. Note that on an error,
1637  * the callback can be invoked with two first parameters as NULL.
1638  **/
1639 void
1640 nm_client_new_async (GCancellable *cancellable,
1641                      GAsyncReadyCallback callback,
1642                      gpointer user_data)
1643 {
1644         GSimpleAsyncResult *simple;
1645
1646         simple = g_simple_async_result_new (NULL, callback, user_data, nm_client_new_async);
1647
1648         g_async_initable_new_async (NM_TYPE_CLIENT, G_PRIORITY_DEFAULT,
1649                                     cancellable, client_inited, simple,
1650                                     NULL);
1651 }
1652
1653 /**
1654  * nm_client_new_finish:
1655  * @result: a #GAsyncResult
1656  * @error: location for a #GError, or %NULL
1657  *
1658  * Gets the result of an nm_client_new_async() call.
1659  *
1660  * Returns: a new #NMClient, or %NULL on error
1661  **/
1662 NMClient *
1663 nm_client_new_finish (GAsyncResult *result, GError **error)
1664 {
1665         GSimpleAsyncResult *simple;
1666
1667         g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, nm_client_new_async), NULL);
1668         g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1669
1670         simple = G_SIMPLE_ASYNC_RESULT (result);
1671         if (g_simple_async_result_propagate_error (simple, error))
1672                 return NULL;
1673         else
1674                 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1675 }
1676
1677 static void
1678 subobject_notify (GObject *object,
1679                   GParamSpec *pspec,
1680                   gpointer client)
1681 {
1682         if (!g_str_has_suffix (pspec->name, "-internal"))
1683                 g_object_notify (client, pspec->name);
1684 }
1685
1686 static void
1687 manager_device_added (NMManager *manager,
1688                       NMDevice *device,
1689                       gpointer client)
1690 {
1691         g_signal_emit (client, signals[DEVICE_ADDED], 0, device);
1692 }
1693
1694 static void
1695 manager_device_removed (NMManager *manager,
1696                         NMDevice *device,
1697                         gpointer client)
1698 {
1699         g_signal_emit (client, signals[DEVICE_REMOVED], 0, device);
1700 }
1701
1702 static void
1703 manager_any_device_added (NMManager *manager,
1704                           NMDevice *device,
1705                           gpointer client)
1706 {
1707         g_signal_emit (client, signals[ANY_DEVICE_ADDED], 0, device);
1708 }
1709
1710 static void
1711 manager_any_device_removed (NMManager *manager,
1712                             NMDevice *device,
1713                             gpointer client)
1714 {
1715         g_signal_emit (client, signals[ANY_DEVICE_REMOVED], 0, device);
1716 }
1717
1718 static void
1719 manager_permission_changed (NMManager *manager,
1720                             NMClientPermission permission,
1721                             NMClientPermissionResult result,
1722                             gpointer client)
1723 {
1724         g_signal_emit (client, signals[PERMISSION_CHANGED], 0, permission, result);
1725 }
1726
1727 static void
1728 settings_connection_added (NMRemoteSettings *manager,
1729                            NMRemoteConnection *connection,
1730                            gpointer client)
1731 {
1732         g_signal_emit (client, signals[CONNECTION_ADDED], 0, connection);
1733 }
1734 static void
1735 settings_connection_removed (NMRemoteSettings *manager,
1736                              NMRemoteConnection *connection,
1737                              gpointer client)
1738 {
1739         g_signal_emit (client, signals[CONNECTION_REMOVED], 0, connection);
1740 }
1741
1742 static void
1743 constructed (GObject *object)
1744 {
1745         NMClient *client = NM_CLIENT (object);
1746         NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
1747
1748         priv->manager = g_object_new (NM_TYPE_MANAGER,
1749                                       NM_OBJECT_PATH, NM_DBUS_PATH,
1750                                       NULL);
1751         g_signal_connect (priv->manager, "notify",
1752                           G_CALLBACK (subobject_notify), client);
1753         g_signal_connect (priv->manager, "device-added",
1754                           G_CALLBACK (manager_device_added), client);
1755         g_signal_connect (priv->manager, "device-removed",
1756                           G_CALLBACK (manager_device_removed), client);
1757         g_signal_connect (priv->manager, "any-device-added",
1758                           G_CALLBACK (manager_any_device_added), client);
1759         g_signal_connect (priv->manager, "any-device-removed",
1760                           G_CALLBACK (manager_any_device_removed), client);
1761         g_signal_connect (priv->manager, "permission-changed",
1762                           G_CALLBACK (manager_permission_changed), client);
1763
1764         priv->settings = g_object_new (NM_TYPE_REMOTE_SETTINGS,
1765                                        NM_OBJECT_PATH, NM_DBUS_PATH_SETTINGS,
1766                                        NULL);
1767         g_signal_connect (priv->settings, "notify",
1768                           G_CALLBACK (subobject_notify), client);
1769         g_signal_connect (priv->settings, "connection-added",
1770                           G_CALLBACK (settings_connection_added), client);
1771         g_signal_connect (priv->settings, "connection-removed",
1772                           G_CALLBACK (settings_connection_removed), client);
1773
1774         G_OBJECT_CLASS (nm_client_parent_class)->constructed (object);
1775 }
1776
1777 static gboolean
1778 init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
1779 {
1780         NMClient *client = NM_CLIENT (initable);
1781         NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
1782
1783         if (!g_initable_init (G_INITABLE (priv->manager), cancellable, error))
1784                 return FALSE;
1785         if (!g_initable_init (G_INITABLE (priv->settings), cancellable, error))
1786                 return FALSE;
1787
1788         return TRUE;
1789 }
1790
1791 typedef struct {
1792         NMClient *client;
1793         GCancellable *cancellable;
1794         GSimpleAsyncResult *result;
1795         gboolean manager_inited;
1796         gboolean settings_inited;
1797 } NMClientInitData;
1798
1799 static void
1800 init_async_complete (NMClientInitData *init_data)
1801 {
1802         g_simple_async_result_complete (init_data->result);
1803         g_object_unref (init_data->result);
1804         g_clear_object (&init_data->cancellable);
1805         g_slice_free (NMClientInitData, init_data);
1806 }
1807
1808 static void
1809 init_async_inited_manager (GObject *object, GAsyncResult *result, gpointer user_data)
1810 {
1811         NMClientInitData *init_data = user_data;
1812         GError *error = NULL;
1813
1814         if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error))
1815                 g_simple_async_result_take_error (init_data->result, error);
1816
1817         init_data->manager_inited = TRUE;
1818         if (init_data->settings_inited)
1819                 init_async_complete (init_data);
1820 }
1821
1822 static void
1823 init_async_inited_settings (GObject *object, GAsyncResult *result, gpointer user_data)
1824 {
1825         NMClientInitData *init_data = user_data;
1826         GError *error = NULL;
1827
1828         if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error))
1829                 g_simple_async_result_take_error (init_data->result, error);
1830
1831         init_data->settings_inited = TRUE;
1832         if (init_data->manager_inited)
1833                 init_async_complete (init_data);
1834 }
1835
1836 static void
1837 init_async (GAsyncInitable *initable, int io_priority,
1838             GCancellable *cancellable, GAsyncReadyCallback callback,
1839             gpointer user_data)
1840 {
1841         NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (initable);
1842         NMClientInitData *init_data;
1843
1844         init_data = g_slice_new0 (NMClientInitData);
1845         init_data->client = NM_CLIENT (initable);
1846         init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1847         init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback,
1848                                                        user_data, init_async);
1849         g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE);
1850
1851         g_async_initable_init_async (G_ASYNC_INITABLE (priv->manager),
1852                                      G_PRIORITY_DEFAULT, init_data->cancellable,
1853                                      init_async_inited_manager, init_data);
1854         g_async_initable_init_async (G_ASYNC_INITABLE (priv->settings),
1855                                      G_PRIORITY_DEFAULT, init_data->cancellable,
1856                                      init_async_inited_settings, init_data);
1857 }
1858
1859 static gboolean
1860 init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
1861 {
1862         GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1863
1864         if (g_simple_async_result_propagate_error (simple, error))
1865                 return FALSE;
1866         else
1867                 return TRUE;
1868 }
1869
1870 static void
1871 dispose (GObject *object)
1872 {
1873         NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object);
1874
1875         if (priv->manager) {
1876                 g_signal_handlers_disconnect_by_data (priv->manager, object);
1877                 g_clear_object (&priv->manager);
1878         }
1879         if (priv->settings) {
1880                 g_signal_handlers_disconnect_by_data (priv->settings, object);
1881                 g_clear_object (&priv->settings);
1882         }
1883
1884         G_OBJECT_CLASS (nm_client_parent_class)->dispose (object);
1885 }
1886
1887 static void
1888 set_property (GObject *object, guint prop_id,
1889               const GValue *value, GParamSpec *pspec)
1890 {
1891         switch (prop_id) {
1892         case PROP_NETWORKING_ENABLED:
1893         case PROP_WIRELESS_ENABLED:
1894         case PROP_WWAN_ENABLED:
1895         case PROP_WIMAX_ENABLED:
1896                 g_object_set_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager),
1897                                        pspec->name, value);
1898                 break;
1899         default:
1900                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1901                 break;
1902         }
1903 }
1904
1905 static void
1906 get_property (GObject *object, guint prop_id,
1907               GValue *value, GParamSpec *pspec)
1908 {
1909         switch (prop_id) {
1910         case PROP_VERSION:
1911         case PROP_STATE:
1912         case PROP_STARTUP:
1913         case PROP_NM_RUNNING:
1914         case PROP_NETWORKING_ENABLED:
1915         case PROP_WIRELESS_ENABLED:
1916         case PROP_WIRELESS_HARDWARE_ENABLED:
1917         case PROP_WWAN_ENABLED:
1918         case PROP_WWAN_HARDWARE_ENABLED:
1919         case PROP_WIMAX_ENABLED:
1920         case PROP_WIMAX_HARDWARE_ENABLED:
1921         case PROP_ACTIVE_CONNECTIONS:
1922         case PROP_CONNECTIVITY:
1923         case PROP_PRIMARY_CONNECTION:
1924         case PROP_ACTIVATING_CONNECTION:
1925         case PROP_DEVICES:
1926         case PROP_METERED:
1927         case PROP_ALL_DEVICES:
1928                 g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager),
1929                                        pspec->name, value);
1930                 break;
1931         case PROP_CONNECTIONS:
1932         case PROP_HOSTNAME:
1933         case PROP_CAN_MODIFY:
1934                 g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->settings),
1935                                        pspec->name, value);
1936                 break;
1937         default:
1938                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1939                 break;
1940         }
1941 }
1942
1943 static void
1944 nm_client_class_init (NMClientClass *client_class)
1945 {
1946         GObjectClass *object_class = G_OBJECT_CLASS (client_class);
1947
1948         g_type_class_add_private (client_class, sizeof (NMClientPrivate));
1949
1950         /* virtual methods */
1951         object_class->constructed = constructed;
1952         object_class->set_property = set_property;
1953         object_class->get_property = get_property;
1954         object_class->dispose = dispose;
1955
1956         /* properties */
1957
1958         /**
1959          * NMClient:version:
1960          *
1961          * The NetworkManager version.
1962          **/
1963         g_object_class_install_property
1964                 (object_class, PROP_VERSION,
1965                  g_param_spec_string (NM_CLIENT_VERSION, "", "",
1966                                       NULL,
1967                                       G_PARAM_READABLE |
1968                                       G_PARAM_STATIC_STRINGS));
1969
1970         /**
1971          * NMClient:state:
1972          *
1973          * The current daemon state.
1974          **/
1975         g_object_class_install_property
1976                 (object_class, PROP_STATE,
1977                  g_param_spec_enum (NM_CLIENT_STATE, "", "",
1978                                     NM_TYPE_STATE,
1979                                     NM_STATE_UNKNOWN,
1980                                     G_PARAM_READABLE |
1981                                     G_PARAM_STATIC_STRINGS));
1982
1983         /**
1984          * NMClient:startup:
1985          *
1986          * Whether the daemon is still starting up.
1987          **/
1988         g_object_class_install_property
1989                 (object_class, PROP_STARTUP,
1990                  g_param_spec_boolean (NM_CLIENT_STARTUP, "", "",
1991                                        FALSE,
1992                                        G_PARAM_READABLE |
1993                                        G_PARAM_STATIC_STRINGS));
1994
1995         /**
1996          * NMClient:nm-running:
1997          *
1998          * Whether the daemon is running.
1999          **/
2000         g_object_class_install_property
2001                 (object_class, PROP_NM_RUNNING,
2002                  g_param_spec_boolean (NM_CLIENT_NM_RUNNING, "", "",
2003                                        FALSE,
2004                                        G_PARAM_READABLE |
2005                                        G_PARAM_STATIC_STRINGS));
2006
2007         /**
2008          * NMClient:networking-enabled:
2009          *
2010          * Whether networking is enabled.
2011          **/
2012         g_object_class_install_property
2013                 (object_class, PROP_NETWORKING_ENABLED,
2014                  g_param_spec_boolean (NM_CLIENT_NETWORKING_ENABLED, "", "",
2015                                        TRUE,
2016                                        G_PARAM_READWRITE |
2017                                        G_PARAM_STATIC_STRINGS));
2018
2019         /**
2020          * NMClient:wireless-enabled:
2021          *
2022          * Whether wireless is enabled.
2023          **/
2024         g_object_class_install_property
2025                 (object_class, PROP_WIRELESS_ENABLED,
2026                  g_param_spec_boolean (NM_CLIENT_WIRELESS_ENABLED, "", "",
2027                                        FALSE,
2028                                        G_PARAM_READWRITE |
2029                                        G_PARAM_STATIC_STRINGS));
2030
2031         /**
2032          * NMClient:wireless-hardware-enabled:
2033          *
2034          * Whether the wireless hardware is enabled.
2035          **/
2036         g_object_class_install_property
2037                 (object_class, PROP_WIRELESS_HARDWARE_ENABLED,
2038                  g_param_spec_boolean (NM_CLIENT_WIRELESS_HARDWARE_ENABLED, "", "",
2039                                        TRUE,
2040                                        G_PARAM_READABLE |
2041                                        G_PARAM_STATIC_STRINGS));
2042
2043         /**
2044          * NMClient:wwan-enabled:
2045          *
2046          * Whether WWAN functionality is enabled.
2047          **/
2048         g_object_class_install_property
2049                 (object_class, PROP_WWAN_ENABLED,
2050                  g_param_spec_boolean (NM_CLIENT_WWAN_ENABLED, "", "",
2051                                        FALSE,
2052                                        G_PARAM_READWRITE |
2053                                        G_PARAM_STATIC_STRINGS));
2054
2055         /**
2056          * NMClient:wwan-hardware-enabled:
2057          *
2058          * Whether the WWAN hardware is enabled.
2059          **/
2060         g_object_class_install_property
2061                 (object_class, PROP_WWAN_HARDWARE_ENABLED,
2062                  g_param_spec_boolean (NM_CLIENT_WWAN_HARDWARE_ENABLED, "", "",
2063                                        FALSE,
2064                                        G_PARAM_READABLE |
2065                                        G_PARAM_STATIC_STRINGS));
2066
2067         /**
2068          * NMClient:wimax-enabled:
2069          *
2070          * Whether WiMAX functionality is enabled.
2071          **/
2072         g_object_class_install_property
2073                 (object_class, PROP_WIMAX_ENABLED,
2074                  g_param_spec_boolean (NM_CLIENT_WIMAX_ENABLED, "", "",
2075                                        FALSE,
2076                                        G_PARAM_READWRITE |
2077                                        G_PARAM_STATIC_STRINGS));
2078
2079         /**
2080          * NMClient:wimax-hardware-enabled:
2081          *
2082          * Whether the WiMAX hardware is enabled.
2083          **/
2084         g_object_class_install_property
2085                 (object_class, PROP_WIMAX_HARDWARE_ENABLED,
2086                  g_param_spec_boolean (NM_CLIENT_WIMAX_HARDWARE_ENABLED, "", "",
2087                                        FALSE,
2088                                        G_PARAM_READABLE |
2089                                        G_PARAM_STATIC_STRINGS));
2090
2091         /**
2092          * NMClient:active-connections:
2093          *
2094          * The active connections.
2095          *
2096          * Element-type: NMActiveConnection
2097          **/
2098         g_object_class_install_property
2099                 (object_class, PROP_ACTIVE_CONNECTIONS,
2100                  g_param_spec_boxed (NM_CLIENT_ACTIVE_CONNECTIONS, "", "",
2101                                      G_TYPE_PTR_ARRAY,
2102                                      G_PARAM_READABLE |
2103                                      G_PARAM_STATIC_STRINGS));
2104
2105         /**
2106          * NMClient:connectivity:
2107          *
2108          * The network connectivity state.
2109          */
2110         g_object_class_install_property
2111                 (object_class, PROP_CONNECTIVITY,
2112                  g_param_spec_enum (NM_CLIENT_CONNECTIVITY, "", "",
2113                                     NM_TYPE_CONNECTIVITY_STATE,
2114                                     NM_CONNECTIVITY_UNKNOWN,
2115                                     G_PARAM_READABLE |
2116                                     G_PARAM_STATIC_STRINGS));
2117
2118         /**
2119          * NMClient:primary-connection:
2120          *
2121          * The #NMActiveConnection of the device with the default route;
2122          * see nm_client_get_primary_connection() for more details.
2123          **/
2124         g_object_class_install_property
2125                 (object_class, PROP_PRIMARY_CONNECTION,
2126                  g_param_spec_object (NM_CLIENT_PRIMARY_CONNECTION, "", "",
2127                                       NM_TYPE_ACTIVE_CONNECTION,
2128                                       G_PARAM_READABLE |
2129                                       G_PARAM_STATIC_STRINGS));
2130
2131         /**
2132          * NMClient:activating-connection:
2133          *
2134          * The #NMActiveConnection of the activating connection that is
2135          * likely to become the new #NMClient:primary-connection.
2136          **/
2137         g_object_class_install_property
2138                 (object_class, PROP_ACTIVATING_CONNECTION,
2139                  g_param_spec_object (NM_CLIENT_ACTIVATING_CONNECTION, "", "",
2140                                       NM_TYPE_ACTIVE_CONNECTION,
2141                                       G_PARAM_READABLE |
2142                                       G_PARAM_STATIC_STRINGS));
2143
2144         /**
2145          * NMClient:devices:
2146          *
2147          * List of real network devices.  Does not include placeholder devices.
2148          *
2149          * Element-type: NMDevice
2150          **/
2151         g_object_class_install_property
2152                 (object_class, PROP_DEVICES,
2153                  g_param_spec_boxed (NM_CLIENT_DEVICES, "", "",
2154                                      G_TYPE_PTR_ARRAY,
2155                                      G_PARAM_READABLE |
2156                                      G_PARAM_STATIC_STRINGS));
2157
2158         /**
2159          * NMClient:all-devices:
2160          *
2161          * List of both real devices and device placeholders.
2162          *
2163          * Element-type: NMDevice
2164          * Since: 1.2
2165          **/
2166         g_object_class_install_property
2167                 (object_class, PROP_ALL_DEVICES,
2168                  g_param_spec_boxed (NM_CLIENT_ALL_DEVICES, "", "",
2169                                      G_TYPE_PTR_ARRAY,
2170                                      G_PARAM_READABLE |
2171                                      G_PARAM_STATIC_STRINGS));
2172
2173         /**
2174          * NMClient:connections:
2175          *
2176          * The list of configured connections that are available to the user. (Note
2177          * that this differs from the underlying D-Bus property, which may also
2178          * contain the object paths of connections that the user does not have
2179          * permission to read the details of.)
2180          *
2181          * Element-type: NMRemoteConnection
2182          */
2183         g_object_class_install_property
2184                 (object_class, PROP_CONNECTIONS,
2185                  g_param_spec_boxed (NM_CLIENT_CONNECTIONS, "", "",
2186                                      G_TYPE_PTR_ARRAY,
2187                                      G_PARAM_READABLE |
2188                                      G_PARAM_STATIC_STRINGS));
2189
2190         /**
2191          * NMClient:hostname:
2192          *
2193          * The machine hostname stored in persistent configuration. This can be
2194          * modified by calling nm_client_save_hostname().
2195          */
2196         g_object_class_install_property
2197                 (object_class, PROP_HOSTNAME,
2198                  g_param_spec_string (NM_CLIENT_HOSTNAME, "", "",
2199                                       NULL,
2200                                       G_PARAM_READABLE |
2201                                       G_PARAM_STATIC_STRINGS));
2202
2203         /**
2204          * NMClient:can-modify:
2205          *
2206          * If %TRUE, adding and modifying connections is supported.
2207          */
2208         g_object_class_install_property
2209                 (object_class, PROP_CAN_MODIFY,
2210                  g_param_spec_boolean (NM_CLIENT_CAN_MODIFY, "", "",
2211                                        FALSE,
2212                                        G_PARAM_READABLE |
2213                                        G_PARAM_STATIC_STRINGS));
2214
2215         /**
2216          * NMClient:metered:
2217          *
2218          * Whether the connectivity is metered.
2219          *
2220          * Since: 1.2
2221          **/
2222         g_object_class_install_property
2223                 (object_class, PROP_METERED,
2224                  g_param_spec_uint (NM_CLIENT_METERED, "", "",
2225                                     0, G_MAXUINT32, NM_METERED_UNKNOWN,
2226                                     G_PARAM_READABLE |
2227                                     G_PARAM_STATIC_STRINGS));
2228
2229         /* signals */
2230
2231         /**
2232          * NMClient::device-added:
2233          * @client: the client that received the signal
2234          * @device: (type NMDevice): the new device
2235          *
2236          * Notifies that a #NMDevice is added.  This signal is not emitted for
2237          * placeholder devices.
2238          **/
2239         signals[DEVICE_ADDED] =
2240                 g_signal_new (NM_CLIENT_DEVICE_ADDED,
2241                               G_OBJECT_CLASS_TYPE (object_class),
2242                               G_SIGNAL_RUN_FIRST,
2243                               G_STRUCT_OFFSET (NMClientClass, device_added),
2244                               NULL, NULL, NULL,
2245                               G_TYPE_NONE, 1,
2246                               G_TYPE_OBJECT);
2247
2248         /**
2249          * NMClient::device-removed:
2250          * @client: the client that received the signal
2251          * @device: (type NMDevice): the removed device
2252          *
2253          * Notifies that a #NMDevice is removed.  This signal is not emitted for
2254          * placeholder devices.
2255          **/
2256         signals[DEVICE_REMOVED] =
2257                 g_signal_new (NM_CLIENT_DEVICE_REMOVED,
2258                               G_OBJECT_CLASS_TYPE (object_class),
2259                               G_SIGNAL_RUN_FIRST,
2260                               G_STRUCT_OFFSET (NMClientClass, device_removed),
2261                               NULL, NULL, NULL,
2262                               G_TYPE_NONE, 1,
2263                               G_TYPE_OBJECT);
2264
2265         /**
2266          * NMClient::any-device-added:
2267          * @client: the client that received the signal
2268          * @device: (type NMDevice): the new device
2269          *
2270          * Notifies that a #NMDevice is added.  This signal is emitted for both
2271          * regular devices and placeholder devices.
2272          **/
2273         signals[ANY_DEVICE_ADDED] =
2274                 g_signal_new (NM_CLIENT_ANY_DEVICE_ADDED,
2275                               G_OBJECT_CLASS_TYPE (object_class),
2276                               G_SIGNAL_RUN_FIRST,
2277                               G_STRUCT_OFFSET (NMClientClass, any_device_added),
2278                               NULL, NULL, NULL,
2279                               G_TYPE_NONE, 1,
2280                               G_TYPE_OBJECT);
2281
2282         /**
2283          * NMClient::any-device-removed:
2284          * @client: the client that received the signal
2285          * @device: (type NMDevice): the removed device
2286          *
2287          * Notifies that a #NMDevice is removed.  This signal is emitted for both
2288          * regular devices and placeholder devices.
2289          **/
2290         signals[ANY_DEVICE_REMOVED] =
2291                 g_signal_new (NM_CLIENT_ANY_DEVICE_REMOVED,
2292                               G_OBJECT_CLASS_TYPE (object_class),
2293                               G_SIGNAL_RUN_FIRST,
2294                               G_STRUCT_OFFSET (NMClientClass, any_device_removed),
2295                               NULL, NULL, NULL,
2296                               G_TYPE_NONE, 1,
2297                               G_TYPE_OBJECT);
2298
2299         /**
2300          * NMClient::permission-changed:
2301          * @client: the client that received the signal
2302          * @permission: a permission from #NMClientPermission
2303          * @result: the permission's result, one of #NMClientPermissionResult
2304          *
2305          * Notifies that a permission has changed
2306          **/
2307         signals[PERMISSION_CHANGED] =
2308                 g_signal_new (NM_CLIENT_PERMISSION_CHANGED,
2309                               G_OBJECT_CLASS_TYPE (object_class),
2310                               G_SIGNAL_RUN_FIRST,
2311                               0, NULL, NULL, NULL,
2312                               G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2313         /**
2314          * NMClient::connection-added:
2315          * @client: the settings object that received the signal
2316          * @connection: the new connection
2317          *
2318          * Notifies that a #NMConnection has been added.
2319          **/
2320         signals[CONNECTION_ADDED] =
2321                 g_signal_new (NM_CLIENT_CONNECTION_ADDED,
2322                               G_OBJECT_CLASS_TYPE (object_class),
2323                               G_SIGNAL_RUN_FIRST,
2324                               G_STRUCT_OFFSET (NMClientClass, connection_added),
2325                               NULL, NULL, NULL,
2326                               G_TYPE_NONE, 1,
2327                               NM_TYPE_REMOTE_CONNECTION);
2328
2329         /**
2330          * NMClient::connection-removed:
2331          * @client: the settings object that received the signal
2332          * @connection: the removed connection
2333          *
2334          * Notifies that a #NMConnection has been removed.
2335          **/
2336         signals[CONNECTION_REMOVED] =
2337                 g_signal_new (NM_CLIENT_CONNECTION_REMOVED,
2338                               G_OBJECT_CLASS_TYPE (object_class),
2339                               G_SIGNAL_RUN_FIRST,
2340                               G_STRUCT_OFFSET (NMClientClass, connection_removed),
2341                               NULL, NULL, NULL,
2342                               G_TYPE_NONE, 1,
2343                               NM_TYPE_REMOTE_CONNECTION);
2344 }
2345
2346 static void
2347 nm_client_initable_iface_init (GInitableIface *iface)
2348 {
2349         iface->init = init_sync;
2350 }
2351
2352 static void
2353 nm_client_async_initable_iface_init (GAsyncInitableIface *iface)
2354 {
2355         iface->init_async = init_async;
2356         iface->init_finish = init_finish;
2357 }