El principio de la comunicación de la red Dbus y los puntos técnicos clave para realizar la comunicación bidireccional

Tecnología de comunicación de red Dbus

1. Resumen del principio Dbus

1.1 Resumen

DBUS es un mecanismo avanzado de comunicación entre procesos. DBUS admite la comunicación uno a uno y muchos a muchos entre procesos. En la comunicación muchos a muchos, se requiere el papel del proceso en segundo plano para transferir mensajes. Cuando un proceso envía un mensaje a otro proceso, el mensaje se envía primero al proceso de fondo y luego se reenvía la información al proceso de destino a través del proceso de fondo.
El proceso de fondo DBUS actúa como un 路由器rol.

El objetivo principal de D-Bus es 在Linux桌面环境为进程提供通信,同时能将Linux桌面环境和Linux内核事件作为消息传递到进程. Los procesos registrados pueden recibir o transmitir mensajes a través del bus, y los procesos también pueden registrarse y esperar respuestas de eventos del kernel, como esperar cambios de estado de la red o instrucciones de apagado de la computadora.

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

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

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

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

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

1.2 Escenarios de aplicación

De acuerdo con el tipo de mensaje DBUS, DBUS proporciona un mecanismo de comunicación entre procesos eficiente, que se utiliza principalmente para llamadas de funciones entre procesos y transmisiones de señales entre procesos .

1. Llamada de función

DBUS puede implementar llamadas de función entre procesos. El proceso A envía una solicitud de llamada de función (mensaje de llamada de método) y la reenvía al proceso B a través del bus. El proceso B responderá con un valor de retorno de función (mensaje de retorno de método) o un mensaje de error (mensaje de error).

2. Transmisión de mensajes

La transmisión de mensajes entre procesos (Mensaje de señal) no requiere una respuesta. El receptor necesita registrar el tipo de mensaje de interés para el bus. Cuando el bus recibe un mensaje del tipo "Mensaje de señal", reenviará el mensaje al proceso deseado.


Dos, use dbus para realizar el ejemplo de comunicación C/V

servidor.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;
}

cliente.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. Realice un ejemplo de comunicación bidireccional

2.1 Usar fondo

Al hacer proyectos antes, un proyecto debe estar compuesto por varias aplicaciones, y cada aplicación debe comunicarse. En ese momento, los sockets se usaban para la comunicación. Sin embargo, cuando se utilizan sockets para la comunicación, los dos clientes no pueden comunicarse directamente, por lo que es necesario establecer un servidor adicional para el reenvío. De esta manera, se desperdicia una gran cantidad de recursos de memoria y energía de la CPU para procesar el reenvío de datos. Más tarde, después de conocer Dbus 数据总线, decidí usar dbus para solucionarlo.

No quería escribir este artículo originalmente, porque hay mucha información sobre dbus en Internet, pero la mayoría de los casos de comunicación en Internet son comunicaciones unidireccionales, la mayoría es que el extremo receptor responde después recibiendo los datos, y no hay ningún ejemplo de comunicación bidireccional simultánea (al menos el autor no lo encontró). La comunicación bidireccional mencionada aquí, como appA y appB, A puede enviar datos de forma activa a B y, al mismo tiempo, B también puede enviar datos de forma activa a A. Los dos flujos de datos proceden simultáneamente sin interferir entre sí.

De la información en Internet, dbus es un bus de datos, su archivo 内部实现依旧采用socket进行通信. El principio detallado no se presenta aquí, solo entiéndalo usted mismo.
A continuación, introducirá principalmente la compilación de dbus y el empaquetado c++ del dbus original en la clase dbus, y la realización de pruebas de comunicación bidireccional.


2.2 Código de implementación

#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

Supongo que te gusta

Origin blog.csdn.net/weixin_48433164/article/details/126934925
Recomendado
Clasificación