linux使用dbus通信-方法测试

强颜欢笑 提交于 2019-11-25 17:03:26

在 D-BUS 中有四种类型的消息:方法调用(method calls)、方法返回(method returns)、信号(signals)和错误(errors)。

1、使用方法调用实现通信

要执行 D-BUS 对象的方法,您需要向对象发送一个方法调用消息。它将完成一些处理(就是执行了对象中的Method,Method是可以带有输入参数的。)并返回,返回消息或者错误消息

client端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

#include <dbus/dbus.h>

const char *const INTERFACE_NAME = "in.softprayog.dbus_example";
const char *const SERVER_BUS_NAME = "in.softprayog.add_server";
const char *const CLIENT_BUS_NAME = "in.softprayog.add_client";
const char *const OBJECT_PATH_NAME = "/in/softprayog/adder";
const char *const METHOD_NAME = "test_dbus_damon";

DBusError dbus_error;
void print_dbus_error (char *str);
bool isinteger (char *ptr);

void print_dbus_error (char *str) 
{
    fprintf (stderr, "%s: %s\n", str, dbus_error.message);
    dbus_error_free (&dbus_error);
}

int main(void)
{
	DBusConnection *conn = NULL;
	DBusMessage     *msg = NULL;
	//DBusMessageIter args;
	DBusPendingCall  *pending = NULL;
    int ret;
    
	dbus_error_init(&dbus_error);
	conn = dbus_bus_get( DBUS_BUS_SYSTEM, &dbus_error);
	if( dbus_error_is_set( &dbus_error ) ){
		print_dbus_error ("dbus_bus_get");
		exit(1);
	}
	if(NULL == conn){
		exit(1);
	}
	// Get a well known name
#if 0
	/****这种方法有可能会停在此处**********/
	while (1) {
		ret = dbus_bus_request_name (conn, CLIENT_BUS_NAME, 0, &dbus_error);
        if (ret == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) 
        	break;
		if (ret == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) {
			fprintf (stderr, "Waiting for the bus ... \n");
			sleep (1);
			continue;
		}
		if (dbus_error_is_set (&dbus_error))
			print_dbus_error ("dbus_bus_get");    
    }
	/*************************************************/	
#endif
#if 1	
 	ret = dbus_bus_request_name(conn, CLIENT_BUS_NAME,DBUS_NAME_FLAG_DO_NOT_QUEUE, &dbus_error);
    if (dbus_error_is_set (&dbus_error))
        print_dbus_error ("dbus_bus_get");

    if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
        fprintf (stderr, "Dbus: not primary owner, ret = %d\n", ret);
      	exit(1);
    }
#endif	

    //创建函数调用
    msg = dbus_message_new_method_call(SERVER_BUS_NAME, OBJECT_PATH_NAME, INTERFACE_NAME, METHOD_NAME);

    if(msg == NULL){
    	fprintf (stderr, "Error in dbus_message_new_method_call\n");
    	exit(1);
    }
    //开始添加发送数据
    
	char *ptr ="hello";
	/******
	dbus_message_iter_init_append(msg, &args);
	dbus_message_append_args(msg, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &mac, 6, //传递数组
													DBUS_TYPE_INT32, &port, DBUS_TYPE_INVALID);
	if (!dbus_message_iter_append_args (msg, DBUS_TYPE_STRING, &ptr,DBUS_TYPE_INVALID)) {
			dbus_message_unref(msg);//free msg
            fprintf (stderr, "Error in dbus_message_iter_append_args\n");
           	exit(1);
	}
	****/
	DBusMessageIter iter;
	dbus_message_iter_init_append(msg, &iter);
	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &ptr)) {
			dbus_message_unref(msg);//free msg
            fprintf (stderr, "Error in dbus_message_iter_append_basic\n");
            exit (1);
     }
     if (!dbus_connection_send_with_reply(conn, msg, &pending, -1))
	{
		dbus_message_unref(msg);
		fprintf (stderr,"dbus_connection_send_with_reply failed");
		exit(1);
	}

	if (NULL == pending)
	{
		dbus_message_unref(msg);
		fprintf (stderr,"pending  == NULL");
		exit(1);
	}
	//发送数据
	dbus_connection_flush(conn);
	dbus_message_unref(msg);
	dbus_pending_call_block(pending);
	
	//接收返回数据
	DBusMessage *reply;
	reply= dbus_pending_call_steal_reply(pending);
	if (reply== NULL)
	{
		fprintf (stderr,"call steal reply failed\n");
		dbus_message_unref(reply);
		exit(1);;
	}
    dbus_pending_call_unref(pending);
	char *s;
	//从服务器端返回一个简单的字符串
    if (dbus_message_get_args (reply, &dbus_error, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
        printf ("Receive from server:  %s\n", s);
    }else{
        fprintf (stderr, "Did not get arguments in reply\n");
        exit (1);
    }
    dbus_message_unref (reply);	
	/****************逐个解析获取信息***********
	dbus_error_init(&err);
	dbus_message_iter_init(msg, &iter);//成功返回1	
	if(DBUS_TYPE_INT32 == dbus_message_iter_get_arg_type(&iter)){
		dbus_message_iter_get_basic(&iter, &status);//获取DBUS_TYPE_INT32类型数据存放到status
	}
	dbus_message_iter_next(&iter);//获取下一数据
	if(DBUS_TYPE_INT32 == dbus_message_iter_get_arg_type(&iter)){
		dbus_message_iter_get_basic(&iter, &count);
	}
	//解析获取的数组数据
	DBusMessageIter sub_iter;
	if(dbus_message_iter_next(&iter){
		if(DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&iter)){
			dbus_message_iter_recurse(&iter, &sub_iter);
			dbus_message_iter_get_fixed_array(&sub_iter, &mac, &mac_len);
		}
	}
	*******************************************/

   	if (dbus_bus_release_name (conn, CLIENT_BUS_NAME, &dbus_error) == -1) {
        fprintf (stderr, "Error in dbus_bus_release_name\n");
        exit (1);
    }
	return 0;
}


server端


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <ctype.h>
#include <dbus/dbus.h>

const char *const INTERFACE_NAME = "in.softprayog.dbus_example";
const char *const SERVER_BUS_NAME = "in.softprayog.add_server";
const char *const OBJECT_PATH_NAME = "/in/softprayog/adder";
const char *const METHOD_NAME = "test_dbus_damon";

DBusError dbus_error;
void print_dbus_error (char *str);
static DBusHandlerResult ws_dbus_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data);

int main (int argc, char **argv)
{
    DBusConnection *conn;
    int ret;

    dbus_error_init (&dbus_error);

    conn = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error);

    if (dbus_error_is_set (&dbus_error))
        print_dbus_error ("dbus_bus_get");

    if (!conn) 
        exit (1);

    // Get a well known name
    ret = dbus_bus_request_name (conn, SERVER_BUS_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE, &dbus_error);

    if (dbus_error_is_set (&dbus_error))
        print_dbus_error ("dbus_bus_get");

    if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
        fprintf (stderr, "Dbus: not primary owner, ret = %d\n", ret);
        exit (1);
    }
#if 1
	dbus_error_init(&dbus_error);
    if (!dbus_connection_add_filter (conn, ws_dbus_message_handler, NULL, NULL)) { 
        fprintf(stderr, "dbus_connection_add_filter\n");
        exit(1); 
    } 
	while (dbus_connection_read_write_dispatch (conn, -1));
    return 0;

#endif

#if 0
    // Handle request from clients
    while (1) {
        // Block for msg from client
        if (!dbus_connection_read_write_dispatch (conn, -1)) {
            fprintf (stderr, "Not connected now.\n");
            exit (1);
        }
     
        DBusMessage *message;

        if ((message = dbus_connection_pop_message (conn)) == NULL) {
            fprintf (stderr, "Did not get message\n");
            continue;
        } 
        
        if (dbus_message_is_method_call (message, INTERFACE_NAME, METHOD_NAME)) {
            char *s;
            bool error = false;

            if (dbus_message_get_args (message, &dbus_error, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
                fprintf (stderr,"Get date from client: %s\n", s);
                
                if (!error) {
                    // send reply
                    DBusMessage *reply;
                    char answer [40];

                    sprintf (answer, "I have get your message!");
                    if ((reply = dbus_message_new_method_return (message)) == NULL) {
                        fprintf (stderr, "Error in dbus_message_new_method_return\n");
                        exit (1);
                    }
    
                    DBusMessageIter iter;
                    dbus_message_iter_init_append (reply, &iter);
                    char *ptr = answer;
                    if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &ptr)) {
                        fprintf (stderr, "Error in dbus_message_iter_append_basic\n");
                        exit (1);
                    }

                    if (!dbus_connection_send (conn, reply, NULL)) {
                        fprintf (stderr, "Error in dbus_connection_send\n");
                        exit (1);
                    }

                    dbus_connection_flush (conn);
                
                    dbus_message_unref (reply);	
                }
                else // There was an error
                {
                    DBusMessage *dbus_error_msg;
                    char error_msg [] = "Error in input";
                    if ((dbus_error_msg = dbus_message_new_error (message, DBUS_ERROR_FAILED, error_msg)) == NULL) {
                         fprintf (stderr, "Error in dbus_message_new_error\n");
                         exit (1);
                    }

                    if (!dbus_connection_send (conn, dbus_error_msg, NULL)) {
                        fprintf (stderr, "Error in dbus_connection_send\n");
                        exit (1);
                    }

                    dbus_connection_flush (conn);
                
                    dbus_message_unref (dbus_error_msg);	
                }
            }
            else
            {
                print_dbus_error ("Error getting message");
            }
        }
    }
    return 0;
#endif
}

static DBusHandlerResult ws_dbus_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
{
	DBusMessage *reply = NULL;
    const char * path =dbus_message_get_path(message);
    if(NULL==path){
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }
	if (strcmp(path,OBJECT_PATH_NAME) == 0) {
		if (dbus_message_is_method_call(message,INTERFACE_NAME,METHOD_NAME)) {
			char *s;
			if (dbus_message_get_args (message, &dbus_error, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
                fprintf (stderr,"Get date from client: %s\n", s);
			}
				
			char answer [40];
			sprintf (answer, "I have get your message!");
			if ((reply = dbus_message_new_method_return (message)) == NULL) {
				fprintf (stderr, "Error in dbus_message_new_method_return\n");
				exit (1);
			}

			DBusMessageIter iter;
			dbus_message_iter_init_append (reply, &iter);
			char *ptr = answer;
			if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &ptr)) {
				fprintf (stderr, "Error in dbus_message_iter_append_basic\n");
				exit (1);
			}
		}
	}
	if(reply){
	// send the reply && flush the connection
	if (!dbus_connection_send(connection, reply, NULL)) {
			return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
		}
		dbus_connection_flush(connection);
		// free the reply
		dbus_message_unref(reply);

		return DBUS_HANDLER_RESULT_HANDLED ;
	}else{
		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
	}	
}

void print_dbus_error (char *str) 
{
    fprintf (stderr, "%s: %s\n", str, dbus_error.message);
    dbus_error_free (&dbus_error);
}
Makefile
CC=gcc
CFLAGS=-Wall `pkg-config --cflags dbus-1`
LIBS=`pkg-config --libs dbus-1`
all: client server t-client

%.o: %.c 
	gcc -c $(CFLAGS) $^ -o $@

t-client: t-client.o
	$(CC) $^ -o $@ $(LIBS)

client: client.o
	$(CC) $^ -o $@ $(LIBS)

server: server.o
	$(CC) $^ -o $@ $(LIBS)

.PHONY: clean
clean:
	rm *.o client server t-client


org.freedesktop.DBus 的12个Methods简要说明

https://blog.csdn.net/MayOuyang/article/details/4566881

这篇文章很好,介绍的很全面

https://www.softprayog.in/programming/d-bus-tutorial

https://blog.csdn.net/eastmoon502136/article/details/10044993
https://blog.csdn.net/Kevin__Mei/article/details/89484314

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!