2013-08-09 1 views
0

메서드가 ReadLocalBdAddrReq이고 dbus 저수준 API를 사용하여 dbus에서 해당 신호 ReadLocalBdAddrCfm을 수신하려고합니다.저수준 API를 사용하여 메서드 호출 및 수신

일부 포럼 게시물과 dbus 튜토리얼을 통해 다음 코드를 작성했습니다.

문제는 신호를 다시 수신 할 수 없다는 것입니다. 코드는 내가해야 할 일을 모르기 때문에 어떤 곳에서는 불완전합니다.

그래서 나는 호출 된 메소드에 대한 신호를받을 수 있도록 도와주세요. 여기 제가 작성한 코드입니다. 제 실수를 바로 잡으세요. 나는 그것이 다음과 같은 출력이이 프로그램을 실행 한 후

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

#define OBJ_PATH "/bt/cm" 


static dbus_bool_t add_watch(DBusWatch *watch, void *data) 
{ 
    if (!dbus_watch_get_enabled(watch)) 
    return TRUE; 

int fd = dbus_watch_get_unix_fd(watch); 
unsigned int flags = dbus_watch_get_flags(watch); 
int f = 0;; 

if (flags & DBUS_WATCH_READABLE) { 
    f |= DBUS_WATCH_READABLE; 
    printf("Readable\n"); 
} 
if (flags & DBUS_WATCH_WRITABLE) { 
    printf("Writeable\n"); 
    f |= DBUS_WATCH_WRITABLE; 
} 
/* this should not be here */ 
if (dbus_watch_handle(watch, f) == FALSE) 
     printf("dbus_watch_handle() failed\n"); 
return TRUE; 
} 

static void remove_watch(DBusWatch *watch, void *data) 
{ 
printf("In remove watch with fd = [%d]\n",dbus_watch_get_unix_fd(watch)); 
} 

static void toggel_watch(DBusWatch *watch, void *data) 
{ 
printf("In toggel watch\n"); 
/* 
if (dbus_watch_get_enabled(watch)) 
    add_watch(watch, data); 
else 
    remove_watch(watch, data); 
*/ 
} 


/* timeout functions */ 
static dbus_bool_t add_time(DBusTimeout *timeout, void *data) 
{ 
/* Incomplete */ 
printf("In add_time\n"); 
if (!dbus_timeout_get_enabled(timeout)) 
    return TRUE; 

//dbus_timeout_handle(timeout); 
return 0; 
} 
static void remove_time(DBusTimeout *timeout, void *data) 
{ 
/* Incomplete */ 
printf("In remove_time\n"); 
} 
static void toggel_time(DBusTimeout *timeout, void *data) 
{ 
/* Incomplete */ 
printf("In toggel_time\n"); 
/* 
if (dbus_timeout_get_enabled(timeout)) 
    add_timeout(timeout, data); 
else 
    remove_timeout(timeout, data); 
*/ 
} 

/* message filter -- handlers to run on all incoming messages*/ 
static DBusHandlerResult filter (DBusConnection *connection, DBusMessage *message, void *user_data) 
{ 
printf("In filter\n"); 
char *deviceaddr; 
if (dbus_message_is_signal(message, "com.bluegiga.v2.bt.cm", "ReadLocalBdAddrCfm")) { 
    printf("Signal received is ReadLocalBdAddrCfm\n"); 
    if ((dbus_message_get_args(message,NULL,DBUS_TYPE_STRING, &deviceaddr,DBUS_TYPE_INVALID) == FALSE)) 
    { 
     printf("Could not get the arguments from the message received\n"); 
     return -2; 
    } 
    printf("Got Signal and device address is [%s]\n", deviceaddr); 
} 
return 0; 
} 

/* dispatch function-- simply save an indication that messages should be dispatched later, when the main loop is re-entered*/ 
static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_status, void *data) 
{ 
printf("In dispatch_status\n"); 
if (new_status == DBUS_DISPATCH_DATA_REMAINS) 
{ 
    printf("new dbus dispatch status: DBUS_DISPATCH_DATA_REMAINS [%d]",new_status); 
} 

} 

/* unregister function */ 
void unregister_func(DBusConnection *connection, void *user_data) 
{ 

} 
/* message function - Called when a message is sent to a registered object path. */ 
static DBusHandlerResult message_func(DBusConnection *connection, DBusMessage *message, void *data) 
{ 
printf("Message [%s] is sent to [%s] from interface [%s] on path [%s] \n",dbus_message_get_member(message),dbus_message_get_destination(message), 
dbus_message_get_interface(message),dbus_message_get_path(message));             return 0; 
} 
DBusObjectPathVTable table = { 
    .unregister_function = unregister_func, 
    .message_function = message_func, 
}; 

int main(void) { 
DBusMessage* msg; 
DBusMessageIter args; 
DBusConnection* conn; 
DBusError err; 
DBusPendingCall* pending; 
int ret; 
//unsigned int level; 
char* appHandle = NULL; 
//int *context; 
int msg_serial; 
int open; 
char *deviceaddr; 

dbus_error_init(&err); 

// connect to the system bus and check for errors 
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 (NULL == conn) { 
    exit(1); 
} 


if (!dbus_connection_set_watch_functions(conn, add_watch, remove_watch, toggel_watch, NULL, NULL)) 
{ 
    printf("Error in dbus_set_watch_functions\n"); 
    dbus_connection_unref(conn); 
    return -1; 
} 


/* These functions are responsible for making the application's main loop aware of timeouts */ 
if (!dbus_connection_set_timeout_functions(conn, add_time, remove_time, toggel_time, NULL, NULL)) 
{ 
    printf("Error in dbus_set_timeout_functions\n"); 
    dbus_connection_unref(conn); 
    return -1; 
} 
/* Used to register the handler functions run on incoming messages*/ 
if (!dbus_connection_add_filter(conn, filter, NULL, NULL)) 
{ 
    printf("Error in adding filter\n"); 
    dbus_connection_unref(conn); 
    return -1; 
} 
/* Filter added for incoming messages */ 

/* Set a function to be invoked when the dispatch status changes */ 
dbus_connection_set_dispatch_status_function(conn, dispatch_status, NULL ,NULL); 

/* Register a handler for messages sent to a given path */ 
if(!dbus_connection_register_object_path(conn, OBJ_PATH, &table, NULL)) 
{ 
    printf("Error in registering object\n"); 
    return -1; 
} 


/* sending messages to the outgoing queue */ 
msg = dbus_message_new_method_call("com.bluegiga.v2.bt.cm", // target for the method call 
            OBJ_PATH, // object to call on 
            "com.bluegiga.v2.bt.cm", // interface to call on 
            "ReadLocalBdAddrReq"); // method name 
if (NULL == msg) { 
    fprintf(stderr, "Message Null\n"); 
    exit(1); 
} 
dbus_message_iter_init_append(msg, &args); 
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT16,&appHandle)) { 
    fprintf(stderr, "Out Of Memory!\n"); 
    exit(1); 
} 

fprintf(stderr, "Sending the connections\n"); 
// send message and get a handle for a reply 
if (!dbus_connection_send (conn, msg, &msg_serial)) { 
    fprintf(stderr, "Out Of Memory!\n"); 
    exit(1); 
} 

fprintf(stderr, "Connection sent and the msg serial is %d\n",msg_serial); 
/* Message sent over */ 

/* not sure whether this should be here or above watch */ 
while (dbus_connection_get_dispatch_status(conn) == DBUS_DISPATCH_DATA_REMAINS) 
{ 
    //printf("Entered in dispatch\n"); 
    /* Processes any incoming data. will call the filters registered by add_filer*/ 
     dbus_connection_dispatch(conn); 
} 
    return 0; 
} 

는 : 연결

보내기

읽을 수를

연결 전송하고 MSG의 직렬 2 (DBUS_MESSAGE_TYPE_METHOD_RETURN)

입니다

연결이 객체 경로로 전송 된 경우 message_func이 올바르게 호출되었지만 결코 호출되지 않아야합니다. 메소드 호출을 보낼 때 실수를 저 지르지 않았습니까?

+0

C에서이 작업이 필요 없다고 가정하고 언어 바인딩 중 하나를 사용하십시오. 다음 목록을 참조하십시오 : http://www.freedesktop.org/wiki/Software/DBusBindings/ C를 사용해야 할 경우 고급 바인딩 중 하나를 사용하여 진행 상황을보다 쉽게 ​​이해할 수 있습니다. – rm5248

+0

C 언어로 사용하고 싶습니다. glib 라이브러리를 사용하면 내 작업이 쉬워 질까요 ?? – Kiran

+0

@BilltheLizard. 나는 이미 그 대답을 "대답이 아닌"것으로 표시하기 전에 질문에 추가했습니다. – TRiG

답변

0

바인딩 중 하나를 선택하면 기본적으로 사용할 수있는 이벤트 루프가 누락되었습니다. add_watch를 호출하면 libdbus는 응용 프로그램에 IO 처리기를 연결할 것으로 예상합니다. 어플리케이션에 의해 추가 된 IOHandler는 시계에 대해 질의 된 fd (filedescriptor)에 대한 활동을 감시합니다. 해당 파일 설명자에 대한 활동이있을 때마다 IOHandler는 dbus_watch_handle을 호출하기 전에 DBUS 플래그로 변환해야하는 적절한 플래그를 사용하여 콜백을 트리거합니다.

이벤트 루프를 사용하는 방법을 모르는 경우 glib를 사용하는 것이 좋습니다. libuV 또는 libEV를 사용하여 저 발자국 이벤트 루프로 사용할 수 있습니다.