RE: Change IP address with libnm



Hi once again :)
I can finally see the print coming from connection_updated(). I added loop = g_main_loop_new(NULL, FALSE) and 
g_main_loop_run(loop) to my networkManager(). 
I still don't understand when you are saying to free GVariant returned from 
nm_remote_connection_commit_changes_finish(). In documentation, this function returns a gboolean.

Sorry for my noobish questions and thanks again for your help.

Code updated:

#include <glib.h>
#include <stdio.h>
#include <stdlib.h>

#include <NetworkManager.h>
#include <networkManagement.h>

static void connection_updated(GObject *connection,
                   GAsyncResult *result,
                   gpointer user_data)
{
    GMainLoop *loop = user_data;
    GError *error = NULL;
    gboolean success = FALSE;

    success = nm_remote_connection_commit_changes_finish(NM_REMOTE_CONNECTION(connection), result, &error);
    
    if (success == TRUE)
    {
        g_print("Connection Updated successfully\n");
    }
    else
    {
        g_print("Error updating connection: %s", error->message);
        g_error_free(error);
    }
    /* Tell the mainloop we're done and we can quit now */
    g_main_loop_quit(loop);
}

static void changeIpAddress(NMConnection *connection, GMainLoop *loop)
{
    GError *error = NULL;
    NMSettingIPConfig *s_ip4;
    NMIPAddress *address;

    /* Build up the 'ipv4' Setting */
    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());

    address = nm_ip_address_new(AF_INET, "192.168.123.2", 24, &error);
    if (address != NULL)
    {
        g_object_set(G_OBJECT(s_ip4),
                     NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
                     NM_SETTING_IP_CONFIG_GATEWAY, "192.168.123.254",
                     NULL);

        nm_setting_ip_config_clear_addresses(s_ip4); //clear all addresses

        printf("%s\n", nm_ip_address_get_address(address));

        nm_setting_ip_config_add_address(s_ip4, address);

        g_object_set(G_OBJECT(s_ip4),
                     NM_SETTING_IP_CONFIG_GATEWAY, "192.168.123.254",
                     NULL);

        nm_connection_add_setting(connection, nm_setting_duplicate(NM_SETTING(s_ip4)));

        nm_remote_connection_commit_changes_async(NM_REMOTE_CONNECTION(connection),
                                                  TRUE, NULL, connection_updated, loop);
        nm_ip_address_unref(address);
    }
}

void networkManager()
{
    GError *error = NULL;
    NMConnection *connection;
    GMainLoop *loop;
    NMClient *client;

    loop = g_main_loop_new(NULL, FALSE);

    if (!(client = nm_client_new(NULL, &error)))
    {
        g_message("Error: Could not connect to NetworkManager: %s.", error->message);
        g_error_free(error);
        return;
    }

    if (!nm_client_get_nm_running(client))
    {
        g_message("Error: Can't obtain connections: NetworkManager is not running.");
        return;
    }

    connection = (NMConnection *)nm_client_get_connection_by_id(client, "Wired connection 2");

    changeIpAddress(connection, loop);

    g_main_loop_run(loop);

    g_object_unref(client);
}
________________________________________
From: Thomas Haller <thaller redhat com>
Sent: 26 February 2020 16:20
To: António Mendes; networkmanager-list gnome org
Subject: Re: Change IP address with libnm

On Wed, 2020-02-26 at 16:02 +0000, António Mendes wrote:
Hello again Thomas.

After read more documentation and follow your guidelines, I achieved
my objective but if you can, I would appreciate a second opinion in
the developed code, if you don't mind...

Hi,


You call nm_remote_connection_commit_changes_async(). That will
basically send the D-Bus request via D-Bus (to Update).

Usually, you would have your application to wait for the response from
commit_changes_async().

NMClient is build around GDBusConnection and thus GMainContext. That
means, when you start an async operation, you need to run/iterate the
maincontext for the response callback to be invoked. I think [1] is a
very good introduction to understand how this works.

From the provided code it's not clear whether you are iterating the
main context (as you have to). However your networkManager() function
doesn't give the caller a way to know when the callback was invoked
(and whether it can stop waiting).


On a minor note, nm_remote_connection_commit_changes_finish() returns a
GVariant on success. You must free that. Also, you don't pass a
user_data argument to nm_remote_connection_commit_changes_async(),
so the g_object_unref(op) is wrong.


[1] https://developer.gnome.org/programming-guidelines/stable/main-contexts.html.en


best,
Thomas
www.eid.pt

EID, S.A.
Capital Social €1.100.000
N° de matricula unico 501 400 699

DISCLAIMER



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]