Re: Trying to communicate with NM over DBus



On Thu, 2007-07-05 at 19:21 +0300, Ohad Lutzky wrote:
> 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?

Actually, I think your problem is that you're not letting dbus get any
time to process the message.  Your main() function doesn't contain a
mainloop at all.  You can do that by adding the glib mainloop
integration, or by doing something like:

while(dbus_connection_read_write_dispatch (connection, -1))
	;

right after the call to printDeviceList(connection);

Dan

> -- 
> 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
> _______________________________________________
> 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]