DBUS를 사용하여 wpa_supplicant와 통신하기위한 코드를 작성하려고합니다. 임베디드 시스템 (ARM)에서 일하기 때문에 파이썬이나 GLib의 사용을 피하고 싶습니다. 나는 D-Bus에 대한 훌륭하고 명확한 문서가 없다는 느낌을 실제로 받기 때문에 바보인지 궁금해하고 있습니다. 공식적인 문서 일지라도 문서가 너무 높은 수준으로 발견되거나 표시된 예제가 Glib을 사용하고 있습니다! http://www.freedesktop.org/wiki/Software/dbusC에서 D-Bus 자습서를 사용하여 wpa_supplicant와 통신하십시오.
내가 C에서 D-버스를 사용에 대한 좋은 기사를 발견 : 문서는 내가 검토 한 http://www.matthew.ath.cx/articles/dbus
그러나이 문서는 꽤 오래 충분히 완료하지! 나는 또한 C++ - dbus API를 발견했다. 그러나 여기에서도 어떤 문서도 찾을 수 없다! 나는 wpa_supplicant와 NetworkManager 소스 코드를 파고 들었지만 꽤 악몽에 빠졌습니다! "저수준 D-Bus API"도 살펴 봤지만 D-Bus 메시지에서 문자열 매개 변수를 추출하는 방법은 알려주지 않았습니다! http://dbus.freedesktop.org/doc/api/html/index.html
다음은 약간의 테스트를 위해 작성한 코드이지만 실제로는 문자열 값을 추출하는 데 어려움이 있습니다. 긴 소스 코드에 대한 죄송하지만 누군가는 "이미"어획량이 wpa_supplicant를에서 신호를 "따라서, stateChanged"있기 때문에 ... 내 D-버스 구성이 잘 보인다 시도하고 싶지만 상태 인쇄 할 수없는 경우 :
#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;
}
모든 포인터를 어떤 멋진, 완전한, 낮은 수준의 C 튜토리얼에 강력하게 감사드립니다! 나는 또한 원격 메소드 호출을 할 계획이기 때문에 튜토리얼에서이 주제를 다루는다면 멋질 것이다. 내가 공식적인 튜토리얼로 얻지 못했기 때문에 나는 똑똑하지 않다라고 말하기도한다 .-p!
wpa_supplicant와 통신하는 또 다른 방법이 있습니까 (wpa_cli 사용 제외).
편집 1 :
'qdbusviewer'과 반성의 capabilty을 사용하여,이 DBUS를 사용하여 무엇을 어떻게 wpa_supplicant를 작품을 발견하는 나에게 많은 도움이되었습니다. 이 호핑은 다른 사람을 도울 것입니다!
편집 2 :
나는 D-버스에 문자열 값을 읽을 수있는 방법을 찾을 때아마 올 것이다!
당신이 D-버스에 문자열 값을 읽을 수있는 방법을 찾았나요? –