Re: Trying to use the DBus API with QtDBus - does the example work?



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]