dbus example

  我们继续学习D-Bus,参考http://dbus.freedesktop.org/doc/dbus/libdbus-tutorial.html  ,相关的API接口reference参考http://dbus.freedesktop.org/doc/dbus/api/html/modules.html  。从底层,即libdbus学习如何发送Method以及如何等待应答,在上上次学习中,给出了同步的方式  ,这是更为高层的处理方式,建议使用。监听method和监听signal的方式非常相似。在给出例子之前,我希望和上次学习一样给出一个示意图,更好地了解D-Bus的各个概念。

 

 

监听Method call消息,并返回Method reply消息


  Method的监听和signal的监听的处理时一样,但是信号是不需要答复,而Method需要。在下面的例子中,我们将学习如何在消息中加入多个参数(在D-Bus学习(四)中,我们加入了一个参数)的情况。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus.h>
#include <unistd.h>

/*读取消息的参数,并且返回两个参数,一个是bool值stat,一个是整数level*/  
void reply_to_method_call(DBusMessage * msg, DBusConnection * conn){
    DBusMessage * reply;
    DBusMessageIter arg;
    char * param = NULL;
    dbus_bool_t stat = TRUE;
    dbus_uint32_t level = 2010;
    dbus_uint32_t serial = 0;  
    
    //从msg中读取参数,这个在上一次学习中学过  
    if(!dbus_message_iter_init(msg,&arg))
        printf("Message has no args/n");
    else if(dbus_message_iter_get_arg_type(&arg) != DBUS_TYPE_STRING)
        printf("Arg is not string!/n");
    else
        dbus_message_iter_get_basic(&arg,& param);
    if(param == NULL) return;


    //创建返回消息reply  
    reply = dbus_message_new_method_return(msg);  
    //在返回消息中填入两个参数,和信号加入参数的方式是一样的。这次我们将加入两个参数。  
     dbus_message_iter_init_append(reply,&arg);  
    if(!dbus_message_iter_append_basic   (&arg,DBUS_TYPE_BOOLEAN,&stat)){
        printf("Out of Memory!/n");
        exit(1);
    }
    if(!dbus_message_iter_append_basic   (&arg,DBUS_TYPE_UINT32,&level)){
        printf("Out of Memory!/n");
        exit(1);
    }  
  //发送返回消息  
      if( !dbus_connection_send   (conn, reply, &serial)){
        printf("Out of Memory/n");
        exit(1);
    }
    dbus_connection_flush  (conn);
    dbus_message_unref  (reply);
}

/* 监听D-Bus消息,我们在上次的例子中进行修改 */  
void listen_dbus()
{
    DBusMessage * msg;
    DBusMessageIter arg;
    DBusConnection * connection;
    DBusError err;
    int ret;
    char * sigvalue;

    dbus_error_init(&err);
    //创建于session D-Bus的连接  
    connection = dbus_bus_get(DBUS_BUS_SESSION, &err);
    if(dbus_error_is_set(&err)){
        fprintf(stderr,"Connection Error %s/n",err.message);
        dbus_error_free(&err);
    }
    if(connection == NULL)
        return;
    //设置一个BUS name:test.wei.dest  
    ret = dbus_bus_request_name(connection,"test.wei.dest",DBUS_NAME_FLAG_REPLACE_EXISTING,&err);
    if(dbus_error_is_set(&err)){
        fprintf(stderr,"Name Error %s/n",err.message);
        dbus_error_free(&err);
    }
    if(ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
        return;

    //要求监听某个singal:来自接口test.signal.Type的信号  
    dbus_bus_add_match(connection,"type='signal',interface='test.signal.Type'",&err);
    dbus_connection_flush(connection);
    if(dbus_error_is_set(&err)){
        fprintf(stderr,"Match Error %s/n",err.message);
        dbus_error_free(&err);
    }  

    while(true){  
        dbus_connection_read_write  (connection,0);
        msg = dbus_connection_pop_message  (connection);

        if(msg == NULL){
            sleep(1);
            continue;
        }  

        if(dbus_message_is_signal(msg,"test.signal.Type","Test")){  
            if(!dbus_message_iter_init(msg,&arg))
                fprintf(stderr,"Message Has no Param");
            else if(dbus_message_iter_get_arg_type(&arg) != DBUS_TYPE_STRING)
                g_printerr("Param is not string");
            else
                dbus_message_iter_get_basic(&arg,&sigvalue);  
        }else if(dbus_message_is_method_call(msg,"test.method.Type","Method")){  
            //我们这里面先比较了接口名字和方法名字,实际上应当现比较路径  
            if(strcmp(dbus_message_get_path  (msg),"/test/method/Object") == NULL)
               reply_to_method_call(msg, connection);  
        }
        dbus_message_unref(msg);  
    }
    
    
}
int main( int argc , char ** argv){
    listen_dbus();  
    return 0;
}

发送Method call消息,并等待Method reply消息

  下面的例子在上次学习信号发送的例子上进行修改。如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus.h>
#include <unistd.h>  
//建立与session D-Bus daemo的连接,并设定连接的名字,相关的代码已经多次使用过了  
DBusConnection *  connect_dbus(){
    DBusError err;
    DBusConnection * connection;
    int ret;

    //Step 1: connecting session bus  
    /* initialise the erroes */  
    dbus_error_init(&err);  
    /* Connect to Bus*/  
    connection = dbus_bus_get(DBUS_BUS_SESSION, &err);  
    if(dbus_error_is_set(&err)){
        fprintf(stderr,"Connection Err : %s/n",err.message);
        dbus_error_free(&err);
    }
    if(connection == NULL)
        return NULL;

    //step 2: 设置BUS name,也即连接的名字。  
    ret = dbus_bus_request_name(connection,"test.wei.source",DBUS_NAME_FLAG_REPLACE_EXISTING,&err);  
    if(dbus_error_is_set(&err)){
        fprintf(stderr,"Name Err : %s/n",err.message);
        dbus_error_free(&err);
    }
    if(ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
        return NULL;

    return connection;    
}  

void send_a_method_call(DBusConnection * connection,char * param)
{
    DBusError err;
    DBusMessage * msg;
    DBusMessageIter    arg;
    DBusPendingCall * pending;
    dbus_bool_t * stat;
    dbus_uint32_t * level;    
    
    dbus_error_init(&err);  

    //针对目的地地址,请参考图,创建一个method call消息。   Constructs a new message to invoke a method on a remote object. 
    msg = dbus_message_new_method_call  ("test.wei.dest","/test/method/Object","test.method.Type","Method");  
    if(msg == NULL){
        g_printerr("Message NULL");
        return;
    }  

    //为消息添加参数。Append arguments  
    dbus_message_iter_init_append(msg, &arg);  
    if(!dbus_message_iter_append_basic  (&arg, DBUS_TYPE_STRING,&param)){
        g_printerr("Out of Memory!");
        exit(1);  
    }

    //发送消息并获得reply的handle  。Queues a message to send, as with dbus_connection_send()  , but also returns a DBusPendingCall  used to receive a reply to the message. 
    if(!dbus_connection_send_with_reply  (connection, msg,&pending, -1)){  
        g_printerr("Out of Memory!");
        exit(1);
    }      

    if(pending == NULL){
        g_printerr("Pending Call NULL: connection is disconnected ");
        dbus_message_unref(msg);
        return;
    }  

    dbus_connection_flush(connection);
    dbus_message_unref(msg);
 
 
    //waiting a reply,在发送的时候,已经获取了method reply的handle,类型为DBusPendingCall。 
    // block until we recieve a reply,   Block until the pending call is completed. 
    dbus_pending_call_block  (pending);  
    // get the reply message,Gets the reply, or returns NULL if none has been received yet. 
    msg = dbus_pending_call_steal_reply  (pending);  
    if (msg == NULL) {
        fprintf(stderr, "Reply Null/n");
         exit(1);
    }
     // free the pending message handle  
     dbus_pending_call_unref(pending);  
    // read the parameters  
     if (!dbus_message_iter_init(msg, &arg))  
        fprintf(stderr, "Message has no arguments!/n");
    else if ( db  us_message_iter_get_arg_type   (&arg) != DBUS_TYPE_BOOLEAN)
        fprintf(stderr, "Argument is not boolean!/n");
    else
        dbus_message_iter_get_basic   (&arg, &stat);
 
    if (!dbus_message_iter_next(&arg))  
        fprintf(stderr, "Message has too few arguments!/n");
    else if ( db  us_message_iter_get_arg_type   (&arg) != DBUS_TYPE_UINT32 )
        fprintf(stderr, "Argument is not int!/n");
    else
        dbus_message_iter_get_basic   (&arg, &level);

    printf("Got Reply: %d, %d/n", stat, level);
    dbus_message_unref(msg);  
}

int main( int argc , char ** argv){
    DBusConnection * connection;
    connection = connect_dbus();
    if(connection == NULL)
        return -1;

    send_a_method_call(connection,"Hello, D-Bus");
    return 0;
}  

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值