D-Bus : Transmit a Data Array in Simple and Useful Form

In lots situation, One would send data via a simple data structure :  a byte array contain real data, and a integer to note this data‘s length. This concept would appear when one uses the D-Bus, of Course.  For D-Bus, D-BUS_TYPE_ARRAY is different from
the others data types, for it is not way to know the data length if there is no additional information. (length of DBUS_TYPE_STRING could be known by seeking where is the null flag.)

In this example, I demonstrate How to send a data array via D-Bus.

server.c :

/* server.c */

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

DBusHandlerResult filter_func(DBusConnection *connection,
      DBusMessage *message, void *usr_data)
{
    DBusMessage *reply;
    dbus_bool_t handled = false;
    char *pReadData;
    int len;
    unsigned char i;

    DBusError dberr;

    dbus_error_init(&dberr);

    printf("pReadData = %x\n", (unsigned int)pReadData);

    if(FALSE == dbus_message_get_args(message, &dberr, DBUS_TYPE_ARRAY,
  DBUS_TYPE_BYTE, &pReadData, &len,  DBUS_TYPE_INVALID) && 0 != len)
 {
  //printf("len = %d\n");
  //printf("receiver data error\n");
  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }

 if(0 == len)
  return DBUS_HANDLER_RESULT_HANDLED;

    printf("len = %d, ", len);

    for( i = 0; i < len; i++)
  printf("%#2x ", (unsigned char)pReadData[i]);
 printf("\n");
    handled = true;

    printf("pReadData = %x\n", (unsigned int)pReadData);

    /*if one free pReadData, it will crash!*/
    //dbus_free_string_array((char**)&pReadData);

    return (handled ? DBUS_HANDLER_RESULT_HANDLED :
  DBUS_HANDLER_RESULT_NOT_YET_HANDLED);

}/*filter_func*/

int main(int argc, char *argv[])
{
    DBusError dberr;
    DBusConnection *dbconn;

    dbus_error_init(&dberr);
    dbconn = dbus_bus_get(DBUS_BUS_SESSION, &dberr);

    if (!dbus_connection_add_filter(dbconn, filter_func, NULL, NULL)) {
        return -1;
    }

    dbus_bus_add_match(dbconn, "type=‘signal‘,interface=‘gaiger.Drstein.Demonstration‘", &dberr);

    while(dbus_connection_read_write_dispatch(dbconn, -1)) {
        /* loop */
    }

    return 0;
}/*main*/

Take a notice: the buffer which containers received data is allocated by D-Bus, you could not release it manually. D-Bus would manage this buffer automatically, it would not occur memory leaking.

client.c :

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

int db_send(DBusConnection *dbconn)
{
    DBusMessage *dbmsg;
    char *pSendData;
    int len;
    unsigned char i;

 pSendData = (char *)malloc(256);

    dbmsg = dbus_message_new_signal("/client/signal/Object",
  "gaiger.Drstein.Demonstration", "Test");

 len = 6;
 for(i = 0; i < len; i++)
  pSendData[i] = (unsigned char)i;

    if (!dbus_message_append_args(dbmsg, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
  &pSendData,  len, DBUS_TYPE_INVALID))
 {
  return -1;
    }

    if (!dbus_connection_send(dbconn, dbmsg, NULL)) {
        return -1;
    }

    dbus_connection_flush(dbconn);
    printf("send message : len = %d, ", len );

 for( i = 0; i < len; i++)
  printf("%#x ", (unsigned char)pSendData[i]);

 printf("\n");
    dbus_message_unref(dbmsg);
    free(pSendData);

    return 0;
}/**/

int main(int argc, char *argv[])
{
 unsigned int i;
    DBusError dberr;
    DBusConnection *dbconn;

    dbus_error_init(&dberr);

    dbconn = dbus_bus_get(DBUS_BUS_SESSION, &dberr);

#if(1)
    for(i = 0; i < 3; i++)
  db_send(dbconn);
#else
    while(dbus_connection_read_write_dispatch(dbconn, -1)) {
        db_send(dbconn);
    }
#endif  

    dbus_connection_unref(dbconn);
    return 0;
}

The two codes are consistent,  client could send data to server. Hope it is useful.

Note the line :

 if(FALSE == dbus_message_get_args(message, &dberr, DBUS_TYPE_ARRAY,
 DBUS_TYPE_BYTE, &pReadData, &len,  DBUS_TYPE_INVALID) && 0 != len)

The type of the length variable should be int, even your data length is as long as int. It is, inside the Dbus library, the lengh pointer has been assume as int*. If you put the other integer types as length,  The values in vicinity of the passed length
may be marred,  it would let to crash.

More detail please ref this post in stack overflow.

If you do not know how to rewrite Makefile for the 2 codes, you could refer tothis post I wrote.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-27 21:24:10

D-Bus : Transmit a Data Array in Simple and Useful Form的相关文章

type setting data array drupal process attached ?

$element['#attached']['js'][] = array( 'type' => 'setting', 'data' => array('ajax' => array('id' => 'settings')), ); drupal_process_attached($element); alert(Druapl.settings.ajax.id)  == settings

HackerRank &quot;Array and simple queries&quot; !

The most interesting, flexible and juicy binary tree problem I have ever seen. I learnt it from here: https://codepair.hackerrank.com/paper/5fIoGg74?b=eyJyb2xlIjoiY2FuZGlkYXRlIiwibmFtZSI6IkJsdWVCaXJkMjI0IiwiZW1haWwiOiJoZWFsdGh5dG9ueUBnbWFpbC5jb20ifQ%

Vue-resource中post请求将data数据以request payload转换为form data的形式

今天在做项目的时候 需要往api中发送一个json格式的对象,但是怎么改都不行,当然,使用的vue 的 http方法. 而且,开始使用时 vue-resource中post请求时的一个坑,vue-resource中post发送的数据默认以request payload的形式,而一般我们使用的都是form data的形式. 后来发现,只需要在main.js中加入: Vue.http.options.emulateJSON = true; Vue.http.options.headers = { '

学习simple.data之基础篇

simple.data是一个轻量级的.动态的数据访问组件,支持.net4.0. 1.必须条件和依赖性: v4.0 or greater of the .NET framework, or v2.10 or greater of the Mono framework 项目中引用 Simple.Data.Core A Simple.Data adaptor A Simple.Data provider 2.PM> Install-Package Simple.Data.Oracle Simple.D

用于Simple.Data的ASP.NET Identity Provider

今天推举的这篇文章,本意不是要推举文章的内容,而是据此介绍一下Simple.Data这个很有意思的类ORM工具. 现在大家在.NET开发中如果需要进行数据访问,那么基本都会使用一些ORM工具,比如微软提供的Entity Framework(现在是6.x版本,马上要发布7.0版本)或者NHibernate.当然可能有些开发人员会使用一些更轻量级的ORM工具,或者一些诸如SqlHelper的非ORM工具.在轻量级ORM工具中,比较有代表性的就是Dapper和Simple.Data. 而Simple.

simple data 安装和使用记录

simple data 安装和使用记录 simple.data是一个轻量级的.动态的数据访问组件,支持.net4.0. simple.data支持以下数据库: SQL Server 2005 and later SQL Server Compact Edition 4.0 oracle vistadb mysql 4.0 and later sqlite 3.0 and later PostgreSQL sqlanywhere informix Microsoft Access 2000, 20

Indexing Sensor Data

In particular embodiments, a method includes, from an indexer in a sensor network, accessing a set of sensor data that includes sensor data aggregated together from sensors in the sensor network, one or more time stamps for the sensor data, and metad

22 Gobs of data

Gobs of data 24 March 2011 Introduction To transmit a data structure across a network or to store it in a file, it must be encoded and then decoded again. There are many encodings available, of course: JSON, XML, Google's protocol buffers, and more.

Interrupt distribution scheme for a computer bus

A method of handling processor to processor interrupt requests in a multiprocessing computer bus environment is described. This method allows a multiple-tiered, increasing priority, interrupt request scheme. This method also allows processor to proce