Re: Trying to use the DBus API with QtDBus - does the example work?
- From: Jirka Klimes <jklimes redhat com>
- To: networkmanager-list gnome org
- Subject: Re: Trying to use the DBus API with QtDBus - does the example work?
- Date: Wed, 21 Dec 2011 14:03:48 +0100
On Wednesday 21 of December 2011 12:14:14 devine-mlist ddevnet net wrote:
> I have hacked up the change-ipv4-address.cpp example in an attempt to
> make it so that the program takes an interface name such as "eth0" and
> changes the IP address instead of a UUID.
> The problem is:
> "Error: could not update connection:
> org.freedesktop.DBus.Error.UnknownMethod Method "Update" with signature
> "a{sa{sv}}" on interface
> "org.freedesktop.NetworkManager.Settings.Connection" doesn't exist"
>
> This comes from a piece of code that I did not change and should work
> the same as the original - unless I have really misunderstood something.
> Surfing around using the qdbus tool I noticed that I could not get to
> the Settings methods. I could only get
> org.freedesktop.NetworkManager.Device.* stuff.
>
> qdbus --system org.freedesktop.NetworkManager
> /org/freedesktop/NetworkManager/Devices/0
> org.freedesktop.NetworkManager.[no Settings methods here!]
>
>
> Example code:
> http://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/C/
> qt/change-ipv4-addresses.cpp
>
>
The example works just fine - it changes IP addresses in a connection profile.
However, you misunderstood the difference between static configuration
parameters and active IP on an interface.
You probably want to change IP address on the interface, and that's another
thing that modifying a static connection profile, which is done in the example.
The connection profile is just a bunch of configuration values and it has no
relation to any device until it is activated. Thus there's no relation between
interface name and the UUID. If the connection is activated on a device, then
the parameters are applied to the device and you can find them under device
path, like /org/freedesktop/NetworkManager/Devices/<n> and IP stuff is under
associated /org/freedesktop/NetworkManager/IP4Config/<n>
So, the problem here is that there's no Update() method on
/org/freedesktop/NetworkManager/Devices/0 object, because it doesn't
represent a connection, but a device. You can only call the method on
/org/freedesktop/NetworkManager/Settings/<n> object to edit
the connection. (You changed conPath.)
If you want to change IP address on an interface, you need to modify the
connection profile (as the example does) and then activate it again on
the interface. Or simply use ifconfig or ip commands.
Useful links:
* NM configuration
http://live.gnome.org/NetworkManagerConfiguration
* D-Bus API specification:
http://projects.gnome.org/NetworkManager/developers/api/09/spec.html#org.freedesktop.NetworkManager.Settings.Connection
http://projects.gnome.org/NetworkManager/developers/api/09/spec.html#org.freedesktop.NetworkManager.Device
You can also use 'd-feet' or 'qdbusviewer' GUI applications, which are nice to
browse D-Bus API and see available objects and supported interfaces.
Jirka
> My code:
> ===================================
>
> #include <QtDBus/QDBusConnection>
> #include <QtDBus/QDBusInterface>
> #include <QtDBus/QDBusMetaType>
> #include <QtDBus/QDBusReply>
> #include <QtCore/QList>
> #include <QtCore/QMap>
> #include <QtCore/QString>
> #include <QtCore/QDebug>
> #include <QtNetwork/QHostAddress>
>
> #include "arpa/inet.h"
>
> #include "NetworkManager.h"
>
> typedef QMap<QString, QMap<QString, QVariant> > Connection;
> Q_DECLARE_METATYPE(Connection)
> Q_DECLARE_METATYPE(QList<uint>);
> Q_DECLARE_METATYPE(QList<QList<uint> >);
>
>
> QString ifaceNameToPath(const QString& iface_name){
> // Set up DBus interface to org.freedesktop.NetworkManager
> QDBusInterface interface(
> NM_DBUS_SERVICE,
> NM_DBUS_PATH,
> NM_DBUS_INTERFACE,
> QDBusConnection::systemBus());
>
> // Call GetDevicesByIpIface using iface_name
> QDBusReply<QDBusObjectPath> path =
> interface.call("GetDeviceByIpIface", iface_name);
> qDebug() << path.value().path();
> // return the path.
> return path.value().path();
> }
>
>
> void changeConnection(const QString& ifname)
> {
> // Register types with D-Bus
> qDBusRegisterMetaType<Connection>();
> qDBusRegisterMetaType<QList<uint> >();
> qDBusRegisterMetaType<QList<QList<uint> > >();
>
> Connection connection;
> QString conPath;
>
> // Find connection by provided UUID
> conPath = ifaceNameToPath(ifname);
> qDebug() << "Derp conPath " << conPath << " ifname was " << ifname;
> if (!conPath.isEmpty()) {
> QList<QList<uint> > addresses;
> QList<uint> addr1, addr2;
>
> // Add some addresses
> addr1 << htonl(QHostAddress("192.168.1.105").toIPv4Address());
> addresses << addr1;
>
> // Set method to "Manual" and put addresses to the connection
> map
> connection["ipv4"]["method"] = "manual";
> connection["ipv4"]["addresses"] =
> QVariant::fromValue(addresses);
>
> QDBusInterface interface(
> NM_DBUS_SERVICE,
> conPath,
> NM_DBUS_IFACE_SETTINGS_CONNECTION,
> QDBusConnection::systemBus());
>
> // Call Update() D-Bus method to update connection
> QDBusReply<void> result = interface.call("Update",
> QVariant::fromValue(connection));
> if (result.isValid()) {
> qDebug() << QString("Connection successfully updated (path
> %1)").arg(conPath);
> } else {
> qDebug() << QString("Error: could not update connection: %1
> %2").arg(result.error().name()).arg(result.error().message());
> }
> } else {
> qDebug() << QString("Error: connection with name '%1' not
> found").arg(ifname);
> }
> }
>
> int main(int argc, char *argv[])
> {
> if (argc != 2) {
> qDebug() << QString("Usage: %1 <UUID>").arg(argv[0]);
> return -1;
> }
>
> changeConnection(argv[1]);
> }
>
> --Daniel Devine
> _______________________________________________
> networkmanager-list mailing list
> networkmanager-list gnome org
> http://mail.gnome.org/mailman/listinfo/networkmanager-list
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]