0

メソッドを呼び出し、dbus 低レベル API を使用して dbus でReadLocalBdAddrReqそのシグナルを受信しようとしています。ReadLocalBdAddrCfm

いくつかのフォーラム投稿と 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;
}

このプログラムを実行すると、次の出力が得られます。

読み取り可能

接続の送信

接続が送信され、メッセージ シリアルは 2 (DBUS_MESSAGE_TYPE_METHOD_RETURN) です。

接続がオブジェクト パスに送信された場合は、message_func正しく呼び出されているはずですが、呼び出されません。メソッド呼び出しの送信に間違いはありませんか?

4

1 に答える 1

0

バインディングのいずれかを使用することを選択した場合、デフォルトで使用できるイベント ループがありません。add_watch への呼び出しを受け取ると、libdbus は、アプリケーションが IO ハンドラーをそれにアタッチすることを期待します。アプリケーションによって追加された IOHandler は、監視のために照会された fd (ファイル記述子) のアクティビティを監視します。そのファイル記述子でアクティビティが発生すると、IOHandler は、dbus_watch_handle を呼び出す前に DBUS フラグに変換する必要がある適切なフラグを使用してコールバックをトリガーします。

イベントループの使い方がわからない場合は、glib を使用することをお勧めします。libUV または libEV を低フットプリントのイベント ループとして使用すると、取得できます。

于 2016-09-29T01:47:48.917 に答える