The principle of Dbus network communication and the key technical points of realizing two-way communication

Dbus network communication technology

1. Overview of Dbus principle

1.1 Overview

DBUS is an advanced inter-process communication mechanism. DBUS supports one-to-one and many-to-many peer-to-peer communication between processes. In many-to-many communication, the role of the background process is required to transfer messages. When one process sends a message to another process, the message is sent to the background first. process, and then forward the information to the destination process through the background process.
The DBUS background process acts as a 路由器role.

The main purpose of D-Bus is 在Linux桌面环境为进程提供通信,同时能将Linux桌面环境和Linux内核事件作为消息传递到进程. Registered processes can receive or transmit messages through the bus, and processes can also register and wait for kernel event responses, such as waiting for network status changes or computer shutdown instructions.

DBUS中主要概念为总线,连接到总线的进程可通过总线接收或传递消息,总线收到消息时,根据不同的消息类型进行不同的处理。DBUS中消息分为四类:

1.  Methodcall消息:将触发一个函数调用 ;

2.  Methodreturn消息:触发函数调用返回的结果;

3.  Error消息:触发的函数调用返回一个异常 ;

4.  Signal消息:通知,可以看作为事件消息。

1.2 Application scenarios

According to the DBUS message type, DBUS provides an efficient inter-process communication mechanism, which is mainly used for inter-process function calls and inter-process signal broadcasts .

1. Function call

DBUS can implement inter-process function calls. Process A sends a function call request (Methodcall message) and forwards it to process B through the bus. Process B will reply with a function return value (Method return message) or an error message (Error message).

2. Message broadcast

Inter-process message broadcast (Signal message) does not require a response. The receiver needs to register the message type of interest to the bus. When the bus receives a message of the "Signal message" type, it will forward the message to the desired process.


Two, use dbus to realize the example of C/V communication

server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus.h>
#include <unistd.h>
 
DBusConnection* init_bus()
{
    
    
	DBusConnection *connection;
	DBusError err;
	int ret = 0;
 
	dbus_error_init(&err);
 
	//与session dbus 建立连接
	//param1:bus type = {DBUS_BUS_SESSION, DBUS_BUS_SYSTEM} 一个系统dbus, 一个普通用户dbus
	//param2:错误信息,包括错误名与错误信息.
	connection = dbus_bus_get(DBUS_BUS_SESSION, &err);
	if(dbus_error_is_set(&err))
	{
    
    
		printf("Connection Error: %s--%s\n", err.name, err.message);
		dbus_error_free(&err);
		return NULL;
	}
 
	//为连接设置一个bus name: bus_name;
	//param 1: 连接描述符
	//param 2: 请求bus要分配的bus name(逻辑上讲,bus name可以是任何字符串,只要符合命名规则)
	//param 3: flags ={DBUS_NAME_FLAG_REPLACE_EXISTING, 
	//					DBUS_NAME_FLAG_ALLOW_REPLACEMENT,
	//					DBUS_NAME_FLAG_DO_NOT_QUEUE
	//					 }
	//param 4: err info
	ret = dbus_bus_request_name(connection, "hello.world.service", DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
	if(dbus_error_is_set(&err))
	{
    
     printf("Name Error: %s--%s\n", err.name, err.message);
		dbus_error_free(&err);
		return NULL;
	}
 
	if(ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
		return NULL;
 
	//注册感兴趣的signal: 来自接口dbus.test.signal.sender
	//param1: 连接描述符
	//param2: match rule (常用的类型: sender=
	//									interface=
	//									type=
	//									member= )
	//param3: err info
	//只设置一个type = signal,表示所有信号都接受.也可以加上接口,发送者bus_name
	dbus_bus_add_match(connection, "type='signal'", &err);
	//阻塞,直到消息发送成功.
	dbus_connection_flush(connection);
	if(dbus_error_is_set(&err))
	{
    
    
		printf("add Match Error %s--%s\n", err.name, err.message);
		dbus_error_free(&err);
		return connection;
	}
	return connection;
}
 
void handle_message(DBusConnection *connection)
{
    
    
	DBusMessage *msg;
	DBusMessageIter arg;
	char *str;
 
	while(1)
	{
    
    
		//param1: 连接描述符
		//param2: 超时时间, -1无限超时时间
		dbus_connection_read_write(connection, 0);
		//从队列中取出一条消息
		msg = dbus_connection_pop_message(connection); 
		if(msg == NULL)
		{
    
    
			sleep(1);
			continue;
		}
		//这里应该过滤path,暂且不做
		//打印出消息对象路径
		printf("path: %s\n", dbus_message_get_path (msg));
		//param1: message
		//param2: interface 这个名字必须与发送那个接口一样.才能处理
		//param3: singal name 方法名也必须一样.
		if(dbus_message_is_signal(msg, "aa.bb.cc", "alarm_test"))
		{
    
    
			//解析message 参数,0为无参数.
			if(!dbus_message_iter_init(msg, &arg))
			{
    
    
				printf("no argument\n");
			}
			//获取第一个参数类型
			if(dbus_message_iter_get_arg_type(&arg) != DBUS_TYPE_INVALID)
			{
    
    
				//获取参数的值
				dbus_message_iter_get_basic(&arg,&str);
				printf("recv param --: %s\n", str);
			}
			
		}
		else if(dbus_message_is_method_call(msg, "hello.world", "add"))
		{
    
    /处理 add 远程调用.
			DBusMessage *rp;
			DBusMessageIter r_arg;
			int a = 0;
			int b = 0;
			int sum = 0;
			printf("service: add  function\n");
 
			if(!dbus_message_iter_init(msg, &arg))
			{
    
    
				printf("no argument!\n");
				goto out;
			}
			if(dbus_message_iter_get_arg_type(&arg) != DBUS_TYPE_INT32)
			{
    
    
				printf("argument error\n");
				goto out;
			}
			dbus_message_iter_get_basic(&arg, &a);
 
			if(!dbus_message_iter_next(&arg))
			{
    
    
				printf("too few argument!\n");
				goto out;
			}
			//check argument type....
			dbus_message_iter_get_basic(&arg, &b);
			sum = a + b;
out:
			//new 一个回应对象
			rp = dbus_message_new_method_return(msg);
			dbus_message_iter_init_append(rp, &r_arg);
			if(!dbus_message_iter_append_basic(&r_arg, DBUS_TYPE_INT32, &sum))
			{
    
    
				printf("no memory!!\n");
				return; 
			}
 
			//param3: 这个跟消息序列有关
			if(!dbus_connection_send(connection, rp, NULL))
			{
    
    
				printf("no memory!!\n");
				return;
			}
			dbus_connection_flush(connection);
			dbus_message_unref(rp);
		}
		//释放空间
		dbus_message_unref(msg);
	}
	//dbus_bus_remove_match();
	
}
 
int main(int argc, char **argv)
{
    
    
	int ret = 0;
	DBusConnection *connection;
 
	connection = init_bus();
	if(connection == NULL)
	{
    
    
		printf("connect the dbus failed...\n");
		return -1;
	}
 
	handle_message(connection);
 
	return 0;
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dbus/dbus.h>
 
 
DBusConnection* init_bus()
{
    
    
	DBusConnection *connection;
	DBusError err;
	int ret;
 
	dbus_error_init(&err);
 
	connection = dbus_bus_get(DBUS_BUS_SESSION, &err);
	if(dbus_error_is_set(&err))
	{
    
    
		printf("connection error: :%s -- %s\n", err.name, err.message);
		dbus_error_free(&err);
		return NULL;
	}
 
	ret = dbus_bus_request_name(connection, "hello.world.client", DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
	if(dbus_error_is_set(&err))
	{
    
    
		printf("Name error: %s -- %s\n", err.name, err.message);
		dbus_error_free(&err);
		return NULL;
	}
	if(ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
		return NULL;
 
	return connection;
}
 
 
void send_signal(DBusConnection *connection)
{
    
    
	DBusMessage *msg;
	DBusMessageIter arg;
	char *str = "hello world!";
 
 
	//创建一个signal对象
	//param1: path (这个逻辑来说,可以是任何字符串,只要符合规则即可)
	//param2: interface (一样)
	//param3: 信号方法名(必须与服务端名匹配)
	if((msg = dbus_message_new_signal("/hello", "aa.bb.cc", "alarm_test")) == NULL)
	{
    
    
		printf("message is NULL\n");
		return;
	}
#if 0
	 //这个看需求添加,一般来说,信号是一种单向广播,加上这一句变单向单播
	 //param2: bus_name
	if(!dbus_message_set_destination(msg, "hello.world.service"))
        {
    
    
                printf("memory error\n");
        }
#endif
 
	//添加参数的一些接口
	dbus_message_iter_init_append(msg, &arg);
	dbus_message_iter_append_basic(&arg, DBUS_TYPE_STRING, &str);
	//入队
	dbus_connection_send(connection, msg, NULL);
	//发送
	dbus_connection_flush(connection);
	//释放内存
	dbus_message_unref(msg);
 
	return;
}
 
void send_method_call(DBusConnection *connection)
{
    
    
	DBusMessage *msg;
	DBusMessageIter arg;
	DBusPendingCall *pending;
	int a = 100;
	int b = 99;
	int sum;
 
	msg = dbus_message_new_method_call("hello.world.service", "/hello/world","hello.world", "add");
	if(msg == NULL)
	{
    
    
		printf("no memory\n");
		return;
	}
 
	dbus_message_iter_init_append(msg, &arg);
    	if(!dbus_message_iter_append_basic (&arg, DBUS_TYPE_INT32,&a)){
    
    
        	printf("no memory!");
        	dbus_message_unref(msg);
        	return;
    	}
   	if(!dbus_message_iter_append_basic (&arg, DBUS_TYPE_INT32,&b)){
    
    
        	printf("no memory!");
        	dbus_message_unref(msg);
        	return;
    	}
 
    //入队message,等待回复
    //param1: 连接描述符
    //param2: message
    //param3: 相当于一个回调的一个描述符,为了获了返回的消息
    //param4: 超时间. -1代表无限
    if(!dbus_connection_send_with_reply (connection, msg, &pending, -1)){
    
    
        printf("no memeory!");
        dbus_message_unref(msg);
        return;
    }
 
    if(pending == NULL){
    
    
        printf("Pending is NULL, may be disconnect...\n");
        dbus_message_unref(msg);
        return;
    }
    //send
    dbus_connection_flush(connection);
    dbus_message_unref(msg);
	
	//阻塞,直到接收到一个响应.
    dbus_pending_call_block (pending);
    msg = dbus_pending_call_steal_reply (pending);
    if (msg == NULL) {
    
    
    	printf("reply is null. error\n");
    	return;
    }
    //释放pending内存 
    dbus_pending_call_unref(pending);
    //解析参数
    if (!dbus_message_iter_init(msg, &arg))
        printf("no argument, error\n");
    if(dbus_message_iter_get_arg_type(&arg) != DBUS_TYPE_INT32)
    {
    
    
    	printf("paramter type error\n");
    }
 
    dbus_message_iter_get_basic(&arg, &sum);
 
    printf(" a(%d) + b(%d) = %d\n",a, b, sum);
    dbus_message_unref(msg);
	
    return;
}
 
 
int main(int argc, char **argv)
{
    
    
	DBusConnection *connection;
 
	connection = init_bus();
	if(connection == NULL)
	{
    
    
		printf("connect to bus failed...\n");
		return -1;
	}
 
	send_signal(connection);
	send_method_call(connection);
	
	return 0;
}

2. Realize two-way communication example

2.1 Use background

When doing projects before, a project needs to be composed of multiple apps, and each app needs to communicate. At that time, sockets were used for communication. However, when sockets are used for communication, the two clients cannot communicate directly, so an additional server needs to be established for forwarding. In this way, a lot of CPU memory resources and energy are wasted to process data forwarding. Later, after learning about Dbus 数据总线, I decided to use dbus to deal with it.

I didn’t want to write this article originally, because there are a lot of information about dbus on the Internet, but most of the communication cases on the Internet are one-way communication, the most is that the receiving end gives a reply after receiving the data, and there is no example of simultaneous two-way communication (at least the author did not find it). The two-way communication mentioned here, such as appA and appB, A can actively send data to B, and at the same time, B can also actively send data to A. The two data streams proceed simultaneously without interfering with each other.

From the information on the Internet, dbus is a data bus, its 内部实现依旧采用socket进行通信. The detailed principle is not introduced here, just understand it by yourself.
Next, it will mainly introduce the compilation of dbus and the c++ packaging of the original dbus into dbus class, and the realization of two-way communication test.


2.2 Implementation code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <ctype.h>
#include <dbus/dbus.h>
#include <iostream>
#include <string>
 
using namespace std;
 
#define DBUS_RECV       1                 //接收
#define DBUS_SEND       2                 //发送
#define RECV_DATA_SIZE  (512 * 20)
 
 
//DBusError dbus_error;	
 
struct recvst
{
    
    
    string bus_name;
	string object_path_name;
	string interface_name;
	string method_name;
	string request_bus_name;
    
	DBusError dbus_error;				//xurc 原来为DBusError &err = *perr;
	DBusConnection *connection;
    DBusMessage *message;
 
    pthread_mutex_t dbus_recv_mutex;
    uint8_t recvdata[RECV_DATA_SIZE];
    int32_t recvpos;
    int32_t recvlen;
};
 
class Dbus
{
    
    
	public:
        pthread_t precv_id;
 
        struct recvst st;
		
		Dbus(string bus_name, string path_namae, string interface_name, string method_name, string request_bus_name, uint8_t dbus_type);
		
		int32_t DbusSend(const void *data, int32_t data_len, int32_t data_type);
		int32_t DbusRecv(void *buff, int32_t buff_len);
 
	//private:
        static DBusHandlerResult ws_dbus_message_handler(DBusConnection *connection, DBusMessage *message, void *user_data)
        {
    
    
            DBusMessageIter recvIter;
	        DBusMessageIter arrayIter;
            int ret = 0;
	        dbus_int32_t len = 0;
            struct recvst *st = (struct recvst *)user_data;
            //DBusMessage *message = st->message;
 
            DBusMessage *reply = NULL;
            const char * path =dbus_message_get_path(message);
            if(NULL==path)
            {
    
    
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
            }
 
            if (strcmp(path, st->object_path_name.c_str()) == 0) 
            {
    
    
        		if (dbus_message_is_method_call(message, st->interface_name.c_str(), st->method_name.c_str())) 
                {
    
    
                    dbus_message_iter_init(message, &recvIter);
                    do 
	                {
    
    
	                	ret = dbus_message_iter_get_arg_type(&recvIter);
	                	if (DBUS_TYPE_STRING == ret)
	                	{
    
    
	                		char *pdata = NULL;
                            dbus_message_iter_get_basic(&recvIter, &pdata);
	                		printf("%s\n", pdata);
                            pthread_mutex_lock(&st->dbus_recv_mutex);
                            memcpy((char *)st->recvdata + st->recvpos, pdata, strlen(pdata));
                            st->recvlen = strlen(pdata);
                            st->recvpos += st->recvlen;
                            pthread_mutex_unlock(&st->dbus_recv_mutex);
	                	}
	                	else if (DBUS_TYPE_ARRAY == ret)
	                	{
    
    
	                		uint8_t *pdata = NULL;
	                		dbus_message_iter_recurse(&recvIter, &arrayIter);
                            dbus_message_iter_get_fixed_array(&arrayIter, &pdata, &len);
	                		if (len > 0)
	                		{
    
    
                                pthread_mutex_lock(&st->dbus_recv_mutex);
	                			memcpy(st->recvdata + st->recvpos, pdata, len);
                                st->recvlen = len;
                                st->recvpos += len;
                                pthread_mutex_unlock(&st->dbus_recv_mutex);
	                		}
	                	}
	                } while (dbus_message_iter_next(&recvIter));
 
        			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;
        	}	
        }
};
 
static void *precv_func(void *arg)
{
    
    
    struct recvst *st = (struct recvst *)arg;
 
    dbus_error_init(&st->dbus_error);
    if (!dbus_connection_add_filter(st->connection, Dbus::ws_dbus_message_handler, st, NULL)) 
    {
    
     
        fprintf(stderr, "dbus_connection_add_filter\n");
        exit(1); 
    }
	while (dbus_connection_read_write_dispatch (st->connection, -1))
    {
    
    
        if (st->recvlen > 0)
        {
    
    
            //printf("555555555st->len = %d\n", st->recvlen);
            //printf("555555555st->recvdata = %s\n", st->recvdata);
            //
            //memset(&st->recvdata, 0x00, sizeof(st->recvdata));
            //st->recvlen = 0;
            printf("get new %d bytes\n", st->recvlen);
            st->recvlen = 0;
        }
        //sleep(1);
   }
}
 
 
Dbus::Dbus(string bus_name, string path_name, string interface_name, string method_name, string request_bus_name, uint8_t dbus_type)
{
    
    
    int32_t ret = 0;
 
    st.bus_name = bus_name;
    st.object_path_name = path_name;
    st.interface_name = interface_name;
    st.method_name = method_name;
    st.request_bus_name = request_bus_name;
    
    //if (st.connection == NULL)
    {
    
    
        dbus_error_init(&st.dbus_error);
        //st.connection = dbus_bus_get (DBUS_BUS_SESSION, &st.dbus_error);          //获取公共的connection
        st.connection = dbus_bus_get_private(DBUS_BUS_SESSION, &st.dbus_error);     //用dbus_bus_get_private获取独立的connection
    }
 
    if (dbus_error_is_set (&st.dbus_error))
        printf("dbus_bus_get\n");
    if (!st.connection) 
        exit (1);
    
    ret = dbus_bus_request_name (st.connection, st.request_bus_name.c_str(), DBUS_NAME_FLAG_DO_NOT_QUEUE, &st.dbus_error);
    if (dbus_error_is_set (&st.dbus_error))
        printf("dbus_bus_get\n");
    if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) 
    {
    
    
        fprintf (stderr, "Dbus: not primary owner, ret = %d\n", ret);
        exit (1);
    }
    //dbus_error_init(&dbus_error);
    //if (!dbus_connection_add_filter (connection, ws_dbus_message_handler, NULL, NULL)) { 
    //    fprintf(stderr, "dbus_connection_add_filter\n");
    //    exit(1); 
    //} 
	//while (dbus_connection_read_write_dispatch (connection, -1));
    if (dbus_type == DBUS_RECV)
    {
    
    
        st.recvpos = 0;
        st.recvlen = 0;
        memset(&st.recvdata, 0x00, RECV_DATA_SIZE);
        pthread_mutex_init(&st.dbus_recv_mutex, NULL);
        pthread_create(&precv_id, NULL, precv_func, &st);
    }
}
 
int32_t Dbus::DbusRecv(void *buff, int32_t buff_len)
{
    
    
    int32_t len = 0;
 
    if ((st.recvpos > 0) && (buff_len >= st.recvpos))
    {
    
    
        pthread_mutex_lock(&st.dbus_recv_mutex);
        memcpy((uint8_t *)buff, st.recvdata, st.recvpos);
        len = st.recvpos;
        st.recvpos = 0;
        pthread_mutex_unlock(&st.dbus_recv_mutex);
    }
 
    return len;
}
 
int32_t Dbus::DbusSend(const void *data, int32_t data_len, int32_t data_type)
{
    
    
    DBusMessage *msg = NULL;
    DBusPendingCall *pending;
    DBusMessageIter sendIter;
	DBusMessageIter arrayIter;
	char buff[2];
	char *ptype = buff;
	dbus_bool_t ret = 0;
 
    //针对目的地地址,请参考图,创建一个method call消息。Constructs a new message to invoke a method on a remote object.
	msg = dbus_message_new_method_call(st.bus_name.c_str(), st.object_path_name.c_str(), st.interface_name.c_str(), st.method_name.c_str());
	if(msg == NULL){
    
    
		fprintf(stderr, "MessageNULL");
		return 0;
	}
 
    //为消息添加参数。Appendarguments
	dbus_message_iter_init_append(msg, &sendIter);
	if (data_type == DBUS_TYPE_STRING)
	{
    
    
		if(!dbus_message_iter_append_basic(&sendIter, DBUS_TYPE_STRING, &data)){
    
    
			fprintf(stderr, "Out of Memory!");
			exit(1);
		}
	}
	else if (data_type == DBUS_TYPE_BYTE)
	{
    
    	
		buff[0] = DBUS_TYPE_BYTE;
		buff[1] = '\0';
		dbus_message_iter_open_container(&sendIter, DBUS_TYPE_ARRAY, ptype, &arrayIter);
		ret = dbus_message_iter_append_fixed_array(&arrayIter, DBUS_TYPE_BYTE, &data, data_len);
		dbus_message_iter_close_container(&sendIter, &arrayIter);
	}
 
    //dbus_connection_send(st.connection, msg, NULL);
    //dbus_connection_flush(st.connection);
	//dbus_message_unref(msg);
 
#if 1
	//发送消息并获得reply的handle。Queues amessage to send, as withdbus_connection_send() , but also returns aDBusPendingCall used to receive a reply to the message.
	if(!dbus_connection_send_with_reply(st.connection, msg, &pending, -1)){
    
    
		fprintf(stderr, "Out of Memory!");
		exit(1);
	}
	
	if(pending == NULL){
    
    
		fprintf(stderr, "Pending CallNULL: connection is disconnected ");
		dbus_message_unref(msg);
		return 0;
	}
	
	dbus_connection_flush(st.connection);
	dbus_message_unref(msg);
    dbus_pending_call_block(pending);
 
    //接收返回数据
    char *s;
	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);
    
	//从服务器端返回一个简单的字符串
    if (dbus_message_get_args (reply, &st.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);
		}
	}
	*******************************************/
#endif
 
   	if (dbus_bus_release_name (st.connection, st.request_bus_name.c_str(), &st.dbus_error) == -1) {
    
    
        fprintf (stderr, "Error in dbus_bus_release_name\n");
        exit (1);
    }
	return 0;
}
 
 
 
#if 0
int32_t main(int32_t argc, char *argv[])
{
    
    
    struct recvst rcst;
    const string recv_bus_name = "in.softprayog.add_server_recv";
    const string recv_object_path_name = "/in/softprayog/adder";
    const string recv_interface_name = "in.softprayog.dbus_example";
    const string recv_methoe_name = "test_dbus_damon";
    const string recv_request_name = "in.softprayog.add_server_recv";
 
    const string send_bus_name = "in.softprayog.add_server_send";
    const string send_object_path_name = "/in/softprayog/adder";
    const string send_interface_name = "in.softprayog.dbus_example";
    const string send_methoe_name = "test_dbus_damon";
    const string send_request_name = "in.softprayog.add_server_send";
 
 
    uint8_t recvbuff[1024];
    int32_t recvlen = 0;
 
    Dbus recv(recv_bus_name, recv_object_path_name, recv_interface_name, recv_methoe_name, recv_request_name, DBUS_RECV);
    Dbus send(send_bus_name, send_object_path_name, send_interface_name, send_methoe_name, send_request_name, DBUS_SEND);
 
 
    while (1)
    {
    
    
        send.DbusSend("hello", strlen("hello"), DBUS_TYPE_STRING);
 
        recvlen = recv.DbusRecv(recvbuff, sizeof(recvbuff));
        for (int i = 0; i < recvlen; i++)
            printf("%x ", recvbuff[i]);
 
        printf("\n");
        sleep(3);
    }
}
#endif
 
#if 1
static void *hardware_send_dataprocess(void *arg)
{
    
    
	string send_BusName = "hardware.dataprocess";
	string send_Path = "/hardware_dataprocess/method/Object";
	string send_InterFace = "hardware_dataprocess.method.Type";
	string send_Method = "Method";
	string send_requestName = "hardware.dataprocess.source";
 
	uint8_t senddata[512];
	uint8_t i = 0;
 
	Dbus dbus_hardware_send_dataprocess(send_BusName, send_Path, send_InterFace, send_Method, send_requestName, DBUS_SEND);
	while (1)
	{
    
    
		memset(senddata, i, sizeof(senddata));
		dbus_hardware_send_dataprocess.DbusSend(senddata, sizeof(senddata), DBUS_TYPE_BYTE);
		i++;
 
        //sleep(1);
		usleep(1000 * 50);
	}
}
 
static void *hardware_recv_dataprocess(void *arg)
{
    
    
	string recv_BusName = "dataprocess.hardware";
	string recv_Path = "/dataprocess_hardware/method/Object";
	string recv_InterFace = "dataprocess_hardware.method.Type";
	string recv_Method = "Method";
	string recv_requestName = recv_BusName;
 
	uint8_t recvdata[8200];
	int32_t recvlen = 0;
 
	Dbus dbus_hardware_recv_dataprocess(recv_BusName, recv_Path, recv_InterFace, recv_Method, recv_requestName, DBUS_RECV);
	while (1)
	{
    
    
		memset(recvdata, 0x00, sizeof(recvdata));
		recvlen = dbus_hardware_recv_dataprocess.DbusRecv(recvdata, sizeof(recvdata));
		if (recvlen > 0)
		{
    
    
			printf("tellen = %d\n", recvlen);
			for (int i = 0; i < 8; i++)
			{
    
    
				printf("%x ", recvdata[i]);
			}
		}
		sleep(1);
	}
}
 
int main(int argc, char *argv[])
{
    
    
    pthread_t hardware_send_dataprocess_id;
	pthread_t hardware_recv_dataprocess_id;
 
	pthread_create(&hardware_send_dataprocess_id, NULL, hardware_send_dataprocess, NULL);
	pthread_create(&hardware_recv_dataprocess_id, NULL, hardware_recv_dataprocess, NULL);
 
    while (1)
    {
    
    
        sleep(1);
    }
}
#endif

Guess you like

Origin blog.csdn.net/weixin_48433164/article/details/126934925