Dbus网络通信原理与实现双向通信的关键技术点

Dbus网络通信技术

一、 Dbus原理概述

1.1概述

DBUS是一种高级的进程间通信机制。DBUS支持进程间一对一和多对多的对等通信,在多对多的通讯时,需要后台进程的角色去分转消息,当一个进程发消息给另外一个进程时,先发消息到后台进程,再通过后台进程将信息转发到目的进程。
DBUS后台进程充当着一个路由器的角色。

D-Bus最主要的用途是在Linux桌面环境为进程提供通信,同时能将Linux桌面环境和Linux内核事件作为消息传递到进程。注册后的进程可通过总线接收或传递消息,进程也可注册后等待内核事件响应,例如等待网络状态的转变或者计算机发出关机指令。

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

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

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

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

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

1.2 应用场景

根据DBUS消息类型可知,DBUS提供一种高效的进程间通信机制,主要用于进程间函数调用以及进程间信号广播

1 . 函数调用

DBUS可以实现进程间函数调用,进程A发送函数调用的请求(Methodcall消息),经过总线转发至进程B。进程B将应答函数返回值(Method return消息)或者错误消息(Error消息)。

2 . 消息广播

进程间消息广播(Signal消息)不需要响应,接收方需要向总线注册感兴趣的消息类型,当总线接收到“Signal消息”类型的消息时,会将消息转发至希望接收的进程。


二、用dbus实现C/V通信的实例

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.1 使用背景

由于之前做项目时,一个项目需要由多个app组成,各个app还需要进行通信,当时所采用的是利用socket进行通信。但是采用socket进行通信时,两个客户端无法直接进行通信,导致还需要额外再建立一个server端进行转发,如此一来,浪费了大量的cpu内存资源以及精力来处理数据转发。后来了解到Dbus这个数据总线后,果断采用dbus来处理。

本来是不想写这篇文章的,因为网上关于dbus的资料很多,但是网上的通信案例大多是单向通信的,最多的也就是接收端收到数据后给个应答,并没有同时双向通信的例子(至少笔者是没找到的)。这里所说的双向通信,比如appA和appB,A可以主动向B发送数据,同时,B也可以主动向A发送数据。两个数据流同时进行,互不干扰。

从网上的资料来看,dbus是一个数据总线,其内部实现依旧采用socket进行通信。详细的原理这里不做介绍,自行了解即可。
接下来,将主要介绍dbus的编译以及对原有的dbus进行c++封装成dbus类,并进行双向通信测试的实现。


2.2 实现代码

#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

猜你喜欢

转载自blog.csdn.net/weixin_48433164/article/details/126934925