Trying to communicate with NM over DBus



Hello, I'm trying to use NetworkManager over DBus, using the C API.
I've tried using the
glib-based one, for the ease-of-use of proxies, but couldn't get it to
work - therefore I tried
going for code similar to the one in the NetworkManager applet itself.

For now I will be satisfied with being able to print the list of
devices NM sees.

For clarification, the following Python code works perfectly, and is
what I want to achieve:

---------------------------------------------

import dbus

def is_wireless(device): return device.getType() == 2

system_bus = dbus.SystemBus()

NM_SERVICE = 'org.freedesktop.NetworkManager'
NM_OBJECT_PATH = '/org/freedesktop/NetworkManager'
NM_DEVICE_IFACE = 'org.freedesktop.NetworkManager.Devices'
NM_NETWORK_IFACE = 'org.freedesktop.NetworkManager.Networks'

nm = system_bus.get_object(NM_SERVICE, NM_OBJECT_PATH)

device_interfaces = [
       dbus.Interface(system_bus.get_object(NM_SERVICE, devicename),
           NM_DEVICE_IFACE) for devicename in nm.getDevices() ]

print 'All devices:', ', '.join([ d.getName() for d in device_interfaces ])

---------------------------------------------

The C code I wrote is the following:

---------------------------------------------

#include <dbus/dbus.h>
#include <stdio.h>

#define DBUS_SERVICE_NM "org.freedesktop.NetworkManager"
#define DBUS_PATH_NM "/org/freedesktop/NetworkManager"
#define DBUS_INTERFACE_NM "org.freedesktop.NetworkManager"

#define report_error(error_message) fprintf(stderr, "[%s:%d
%s()]\t%s\n", __FILE__, __LINE__, __func__, (error_message));

DBusConnection * getSystemBus() {
       DBusConnection * connection;
       DBusError error;

       dbus_error_init(&error);
       connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
       if (connection == NULL) {
               report_error("Error connection to system bus:");
               report_error(error.message);
               dbus_error_free(&error);
               return NULL;
       }

       return connection;
}

void print_a_device_name(DBusPendingCall * pcall, void * user_data) {
       printf("Hello, this is print_a_device_name\n");

       dbus_pending_call_unref(pcall);
}

void printDeviceList(DBusConnection * connection) {
       DBusMessage * message = NULL;
       DBusPendingCall * pcall = NULL;

       if (message = dbus_message_new_method_call(DBUS_SERVICE_NM,
                               DBUS_PATH_NM, DBUS_INTERFACE_NM, "getDevices"))
       {
               dbus_connection_send_with_reply(connection, message,
&pcall, -1);
               if (pcall)
                       dbus_pending_call_set_notify(pcall,
print_a_device_name, NULL, NULL);
               dbus_message_unref(message);
       }
}

int main(int argc, char **argv) {
       DBusConnection * connection = NULL;

       connection = getSystemBus();

       if (!connection) {
               report_error("Couldn't get system bus.");
               return 1;
       }

       printDeviceList(connection);

       /* dbus_connection_close(connection);
       dbus_connection_unref(connection); */

       return 0;
}

---------------------------------------------

The code compiles correctly, with no warnings, on Ubuntu Feisty 7.04
(same machine as I ran the Python code on). However - it prints
absolutely nothing. Going over it with DDD seems to show everything is
okay (the pcall_set_notify bit gets run), but print_a_device_name does
not get run, and there is no output.
If, furthermore, I uncomment the connection_close and connection_unref
lines, I get the
following error as the only output of the program:

process 24668: Applications must not close shared connections - see
dbus_connection_close() docs. This is a bug in the application.

Any advice?

--
Man is the only animal that laughs and weeps, for he is the only
animal that is struck with the difference between what things are and
what they ought to be.
- William Hazlitt

Ohad Lutzky



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