From 00236ef97726f6bc30f439fdc41314cdf18997aa Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 26 Oct 2018 13:44:38 +0200 Subject: [PATCH] libnm: Add support to pass options to AddAndActivateConnection This adds the new methods nm_client_add_and_activate_connection_options_* and ports the existing methods to use the new AddAndActivateConnection2 call rather than AddAndActivateConnection, allowing further parameters to be passed in. --- libnm/libnm.ver | 2 + libnm/nm-client.c | 110 ++++++++++++++++++++++++++- libnm/nm-client.h | 12 +++ libnm/nm-manager.c | 16 ++-- libnm/nm-manager.h | 1 + tools/test-networkmanager-service.py | 6 ++ 6 files changed, 140 insertions(+), 7 deletions(-) diff --git a/libnm/libnm.ver b/libnm/libnm.ver index cf57b1240..269f406cd 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1447,5 +1447,7 @@ global: libnm_1_16_0 { global: + nm_client_add_and_activate_connection_options_async; + nm_client_add_and_activate_connection_options_finish; nm_device_get_connectivity; } libnm_1_14_0; diff --git a/libnm/nm-client.c b/libnm/nm-client.c index a669f3c5a..576fbacbc 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -1233,7 +1233,7 @@ nm_client_add_and_activate_connection_async (NMClient *client, if (cancellable) g_simple_async_result_set_check_cancellable (simple, cancellable); nm_manager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager, - partial, device, specific_object, + partial, device, specific_object, NULL, cancellable, add_activate_cb, simple); } @@ -1268,6 +1268,114 @@ nm_client_add_and_activate_connection_finish (NMClient *client, return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); } +/** + * nm_client_add_and_activate_connection_options_async: + * @client: a #NMClient + * @partial: (allow-none): an #NMConnection to add; the connection may be + * partially filled (or even %NULL) and will be completed by NetworkManager + * using the given @device and @specific_object before being added + * @device: the #NMDevice + * @specific_object: (allow-none): the object path of a connection-type-specific + * object this activation should use. This parameter is currently ignored for + * wired and mobile broadband connections, and the value of %NULL should be used + * (ie, no specific object). For Wi-Fi or WiMAX connections, pass the object + * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can + * get using nm_object_get_path(), and which will be used to complete the + * details of the newly added connection. + * @options: a #GVariant containing a dictionary with options, or %NULL + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the activation has started + * @user_data: caller-specific data passed to @callback + * + * Adds a new connection using the given details (if any) as a template, + * automatically filling in missing settings with the capabilities of the given + * device and specific object. The new connection is then asynchronously + * activated as with nm_client_activate_connection_async(). Cannot be used for + * VPN connections at this time. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can used the returned + * #NMActiveConnection object (in particular, #NMActiveConnection:state) to + * track the activation to its completion. + * + * This is identitcal to nm_client_add_and_activate_connection_async() but takes + * a further @options parameter. Currently the following options are supported + * by the daemon: + * * "persist": A string describing how the connection should be stored. + * The default is "disk", but it can be modified to "memory" (until + * the daemon quits) or "volatile" (will be deleted on disconnect). + * * "bind": Bind the connection lifetime to something. The default is "none", + * meaning an explicit disconnect is needed. The value "dbus-client" + * means the connection will automatically be closed when the calling + * DBus client disappears from the system bus. + * A non-default "bind" option must always be used together with + * "persist" set to "volatile". + * + * Since: 1.16 + **/ +void +nm_client_add_and_activate_connection_options_async (NMClient *client, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + GVariant *options, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + g_return_if_fail (NM_IS_DEVICE (device)); + if (partial) + g_return_if_fail (NM_IS_CONNECTION (partial)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_add_and_activate_connection_options_async); + if (cancellable) + g_simple_async_result_set_check_cancellable (simple, cancellable); + nm_manager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager, + partial, device, specific_object, options, + cancellable, add_activate_cb, simple); +} + +/** + * nm_client_add_and_activate_connection_options_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_add_and_activate_connection_options_async(). + * + * You can call nm_active_connection_get_connection() on the returned + * #NMActiveConnection to find the path of the created #NMConnection. + * + * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMActiveConnection * +nm_client_add_and_activate_connection_options_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + /** * nm_client_deactivate_connection: * @client: a #NMClient diff --git a/libnm/nm-client.h b/libnm/nm-client.h index 6259b1227..dc5649f3c 100644 --- a/libnm/nm-client.h +++ b/libnm/nm-client.h @@ -339,6 +339,18 @@ NMActiveConnection *nm_client_add_and_activate_connection_finish (NMClient *clie GAsyncResult *result, GError **error); +void nm_client_add_and_activate_connection_options_async (NMClient *client, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + GVariant *options, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMActiveConnection *nm_client_add_and_activate_connection_options_finish (NMClient *client, + GAsyncResult *result, + GError **error); + gboolean nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active, GCancellable *cancellable, diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c index a54251274..235dc4aed 100644 --- a/libnm/nm-manager.c +++ b/libnm/nm-manager.c @@ -1098,6 +1098,7 @@ nm_manager_add_and_activate_connection_async (NMManager *manager, NMConnection *partial, NMDevice *device, const char *specific_object, + GVariant *options, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) @@ -1127,13 +1128,16 @@ nm_manager_add_and_activate_connection_async (NMManager *manager, dict = nm_connection_to_dbus (partial, NM_CONNECTION_SERIALIZE_ALL); if (!dict) dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); + if (!options) + options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0); - nmdbus_manager_call_add_and_activate_connection (priv->proxy, - dict, - nm_object_get_path (NM_OBJECT (device)), - specific_object ?: "/", - cancellable, - add_activate_cb, info); + nmdbus_manager_call_add_and_activate_connection2 (priv->proxy, + dict, + nm_object_get_path (NM_OBJECT (device)), + specific_object ?: "/", + options, + cancellable, + add_activate_cb, info); } NMActiveConnection * diff --git a/libnm/nm-manager.h b/libnm/nm-manager.h index 0a278aee5..26b7ef412 100644 --- a/libnm/nm-manager.h +++ b/libnm/nm-manager.h @@ -163,6 +163,7 @@ void nm_manager_add_and_activate_connection_async (NMManager *ma NMConnection *partial, NMDevice *device, const char *specific_object, + GVariant *options, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); diff --git a/tools/test-networkmanager-service.py b/tools/test-networkmanager-service.py index 9aa44a906..76601d017 100755 --- a/tools/test-networkmanager-service.py +++ b/tools/test-networkmanager-service.py @@ -1341,6 +1341,12 @@ class NetworkManager(ExportedObj): @dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}oo', out_signature='oo') def AddAndActivateConnection(self, con_hash, devpath, specific_object): + return self.AddAndActivateConnection2(con_hash, devpath, specific_object, dict()) + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}ooa{sv}', out_signature='oo') + def AddAndActivateConnection2(self, con_hash, devpath, specific_object, options): + # TODO: Do some processing of the "options" parameter. + device = self.find_device_first(path = devpath, require = BusErr.UnknownDeviceException) conpath = gl.settings.AddConnection(con_hash) return (conpath, self.ActivateConnection(conpath, devpath, specific_object))