Estoy tratando de escribir algún código para comunicarme con wpa_supplicant usando DBUS. Como estoy trabajando en un sistema integrado (ARM), me gustaría evitar el uso de Python o el GLib. Me pregunto si soy estúpido porque realmente tengo la sensación de que no hay documentación buena y clara sobre D-Bus. Incluso con el oficial, o encuentro la documentación de un nivel demasiado alto, o los ejemplos que se muestran están usando Glib! Documentación que he mirado: http://www.freedesktop.org/wiki/Software/dbusTutorial de D-Bus en C para comunicarse con wpa_supplicant
He encontrado un buen artículo sobre el uso de D-Bus en C: http://www.matthew.ath.cx/articles/dbus
Sin embargo, este artículo es bastante viejo y no es lo suficientemente completa! También encontré la API de C++ - dbus, pero también aquí, ¡no encuentro CUALQUIER documentación! ¡He estado investigando el código fuente de wpa_supplicant y NetworkManager, pero es una verdadera pesadilla! También he estado investigando la "API de D-Bus de bajo nivel", pero esto no me dice cómo extraer un parámetro de cadena de un mensaje de D-Bus. http://dbus.freedesktop.org/doc/api/html/index.html
Aquí hay un código que escribí para probar un poco, pero realmente tengo problemas para extraer valores de cadena. Lo siento por el código fuente de largo, pero si alguien quiere probarlo ... Mi configuración de D-Bus parece muy bien porque "ya" capturas "StateChanged" señales de wpa_supplicant, pero no puede imprimir el estado:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <dbus/dbus.h>
//#include "wpa_supp_dbus.h"
/* Content of wpa_supp_dbus.h */
#define WPAS_DBUS_SERVICE "fi.epitest.hostap.WPASupplicant"
#define WPAS_DBUS_PATH "/fi/epitest/hostap/WPASupplicant"
#define WPAS_DBUS_INTERFACE "fi.epitest.hostap.WPASupplicant"
#define WPAS_DBUS_PATH_INTERFACES WPAS_DBUS_PATH "/Interfaces"
#define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface"
#define WPAS_DBUS_NETWORKS_PART "Networks"
#define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network"
#define WPAS_DBUS_BSSIDS_PART "BSSIDs"
#define WPAS_DBUS_IFACE_BSSID WPAS_DBUS_INTERFACE ".BSSID"
int running = 1;
void stopLoop(int sig)
{
running = 0;
}
void sendScan()
{
// TODO !
}
void loop(DBusConnection* conn)
{
DBusMessage* msg;
DBusMessageIter args;
DBusMessageIter subArgs;
int argType;
int i;
int buffSize = 1024;
char strValue[buffSize];
const char* member = 0;
sendScan();
while (running)
{
// non blocking read of the next available message
dbus_connection_read_write(conn, 0);
msg = dbus_connection_pop_message(conn);
// loop again if we haven't read a message
if (!msg)
{
printf("No message received, waiting a little ...\n");
sleep(1);
continue;
}
else printf("Got a message, will analyze it ...\n");
// Print the message member
printf("Got message for interface %s\n",
dbus_message_get_interface(msg));
member = dbus_message_get_member(msg);
if(member) printf("Got message member %s\n", member);
// Check has argument
if (!dbus_message_iter_init(msg, &args))
{
printf("Message has no argument\n");
continue;
}
else
{
// Go through arguments
while(1)
{
argType = dbus_message_iter_get_arg_type(&args);
if (argType == DBUS_TYPE_STRING)
{
printf("Got string argument, extracting ...\n");
/* FIXME : got weird characters
dbus_message_iter_get_basic(&args, &strValue);
*/
/* FIXME : segmentation fault !
dbus_message_iter_get_fixed_array(
&args, &strValue, buffSize);
*/
/* FIXME : segmentation fault !
dbus_message_iter_recurse(&args, &subArgs);
*/
/* FIXME : deprecated!
if(dbus_message_iter_get_array_len(&args) > buffSize)
printf("message content to big for local buffer!");
*/
//printf("String value was %s\n", strValue);
}
else
printf("Arg type not implemented yet !\n");
if(dbus_message_iter_has_next(&args))
dbus_message_iter_next(&args);
else break;
}
printf("No more arguments!\n");
}
// free the message
dbus_message_unref(msg);
}
}
int main(int argc, char* argv[])
{
DBusError err;
DBusConnection* conn;
int ret;
char signalDesc[1024]; // Signal description as string
// Signal handling
signal(SIGKILL, stopLoop);
signal(SIGTERM, stopLoop);
// Initialize err struct
dbus_error_init(&err);
// connect to the bus
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
if (dbus_error_is_set(&err))
{
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (!conn)
{
exit(1);
}
// request a name on the bus
ret = dbus_bus_request_name(conn, WPAS_DBUS_SERVICE, 0, &err);
if (dbus_error_is_set(&err))
{
fprintf(stderr, "Name Error (%s)\n", err.message);
dbus_error_free(&err);
}
/* Connect to signal */
// Interface signal ..
sprintf(signalDesc, "type='signal',interface='%s'",
WPAS_DBUS_IFACE_INTERFACE);
dbus_bus_add_match(conn, signalDesc, &err);
dbus_connection_flush(conn);
if (dbus_error_is_set(&err))
{
fprintf(stderr, "Match Error (%s)\n", err.message);
exit(1);
}
// Network signal ..
sprintf(signalDesc, "type='signal',interface='%s'",
WPAS_DBUS_IFACE_NETWORK);
dbus_bus_add_match(conn, signalDesc, &err);
dbus_connection_flush(conn);
if (dbus_error_is_set(&err))
{
fprintf(stderr, "Match Error (%s)\n", err.message);
exit(1);
}
// Bssid signal ..
sprintf(signalDesc, "type='signal',interface='%s'",
WPAS_DBUS_IFACE_BSSID);
dbus_bus_add_match(conn, signalDesc, &err);
dbus_connection_flush(conn);
if (dbus_error_is_set(&err))
{
fprintf(stderr, "Match Error (%s)\n", err.message);
exit(1);
}
// Do main loop
loop(conn);
// Main loop exited
printf("Main loop stopped, exiting ...\n");
dbus_connection_close(conn);
return 0;
}
Cualquier puntero a cualquier tutorial agradable, completo y de bajo nivel de C es muy apreciada! También estoy planeando hacer una llamada a método remoto, así que si el tutorial cubre este tema sería genial. Decir que no soy muy inteligente porque no lo entiendo con el tutorial oficial también es apreciado: ¡p!
¿O existe otra forma de comunicarse con wpa_supplicant (excepto con wpa_cli)?
EDIT 1:
El uso de 'qdbusviewer' y la capabilty introspección, esto me ayudó mucho descubrir qué y cómo funciona wpa_supplicant usando dbus. ¡Saltando que esto ayudaría a alguien más!
Edición 2:
probablemente vendrá cuando voy a encontrar una manera de leer los valores de cadena de D-Bus!
¿Ha encontrado una manera de leer los valores de cadena de D-Bus? –