On Wed, 2020-04-08 at 09:25 -0500, Romano Pauli wrote:
Hello all, I am looking for some help with using NetworkManager in a c++ application. I am able to use network manager to scan the list of ap's and also go through the list of connections. I think if the network is already listed in the connection list I need to activate it instead of trying to add it.
Your example uses libnm (which is probably a good choice). Note that libnm is basically a wrapper around D-Bus API, so the libnm API usually directly corresponds to a D-Bus call. Then libnm also contains NMConnection and NMSetting* classes, those aim to simplify creating a connection profile. A connection profile is a bunch of settings, and thus NMConnection is merely a dictionary of values. That doesn't directly map to D-Bus, although with nm_connection_to_dbus() and _nm_simple_connection_new_from_dbus(), you can convert a NMConnection to a GVariant that you then may send via D- Bus, as an argument for D-Bus methods like "AddConnection2". The "connection list" oyu mention is the list of connection profiles. A profile is just a bunch of settings (with configuration values for a network). There is a difference between the connection profiles and the Wi-Fi scan list (access points). I would agree to call a Wi-Fi access point a "network", but calling a connection profile a "network" seems confusing to me (of course, a connection profile are the settings for configuring a "network"). So, no, I wouldn't say that "the network is listed in the connection list", but probably you meant the right thing. You can activate an existing connection profile of your choice. Alternatively, you can create a new profile with "AddConnection2" (nm_client_add_connection_async) (and then activate that profile next). Note that doing anything to a profile (modifying it or adding it), often triggers an autoconnect right away (if the profile is configured to autoconnect, and autoconnect is currently possible). So, in those cases you may not need an explicit acitvation after adding the profile. See also the flags NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT and NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT). There is also AddAndActivateConnection2 (nm_client_add_and_activate_connection2()). That is what happens with `nmcli device connect $IFNAME` and `nmcli device wifi connect`. It's not only "AddConnection2 + ActivateConnection" in one step. It allows you to provide an incomplete connection (e.g. only specify the SSID, but omit the WPA settings), then NetworkManager will try to complete the profile depending on the Wi-Fi scan list. With AddConnection2, you always need to provide the full profile. Possibly, if you have an Access Point but not profile for it, you would create one by calling AddAndActivate2. See what happens during `nmcli device wifi connect`: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/1ef894f489ce0fc6e689c6671e50851763321f06/clients/cli/devices.c#L3297
However what I am missing is how do I activate the wireless connection and how do I set the WPA2 key (or other key depending on the security used) I have not found any code examples on how to use ActivateConnection or AddAndActivateConnection2 methods. Below was an attempt I made at setting up the connection (borrowed heavily from https://github.com/lcp/NetworkManager/blob/master/examples/C/glib/add-connection-libnm-glib.c )
I think you need to add a NMSettingWirelessSecurity() and set NM_SETTING_WIRELESS_SECURITY_PSK. You may also want to set NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS accordingly. See `man nm-settings` for the meaning of the properties. You may also omit the PSK, and let NetworkManager prompt for it. But that requires a secret-agent running that can answer the request. If you have nm-applet (or similar) running, it will prompt for a password. You could also implement the secret agent in your own application... Of coures, you can avoid all that, by specifying the secret during nm_client_add_connection*() or nm_remote_connection_update2().
// Ask the settings service to add the new connection; we'll quit the // mainloop and exit when the callback is called. success = nm_remote_settings_add_connection(settings, connection, NetworkSettings::added_cb, loop);
nm_remote_settings_add_connection() is from libnm-glib. That library is deprecated for many years. Don't use it. Use instead libnm. The corresponding function there is called nm_client_add_connection(). Also, if you took this from an example code, then don't base it on examples that are years old. Possibly also refer to the recent API documentation: https://developer.gnome.org/NetworkManager/stable/ best, Thomas
Attachment:
signature.asc
Description: This is a digitally signed message part