2015年1月16日 星期五

Dbus : simple sender and receiver


No tedious words, I post code directly:

sender:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus.h>

#define LOCAL      static 

#ifndef TRUE
 #define TRUE      1
 #define FALSE      0
#endif
 
LOCAL void SendData(DBusConnection *connection, char *pData)
{
 DBusMessage *dbmsg;
 DBusPendingCall *pending;
 DBusMessage* reply;
 
 int len;
 
 dbmsg = NULL; pending = NULL; reply = NULL;
 
 dbmsg = dbus_message_new_signal ("/org/share/linux","org.share.linux", "Customize");
  
 len = strlen(pData);
 
    if(FALSE == dbus_message_append_args(dbmsg, 
    DBUS_TYPE_STRING, &pData, 
    DBUS_TYPE_INT32,  &len, 
    DBUS_TYPE_INVALID))
  return;
 
 printf("Message cutomize sending : %s , length = %d\n", pData, len);
 /* Send the signal */
 
    dbus_connection_send(connection, dbmsg, NULL);

 if(NULL != dbmsg)
  dbus_message_unref(dbmsg);
 if(NULL != pending)
  dbus_pending_call_unref(pending);
 
 if(NULL != pending) 
  dbus_message_unref(reply);
  
}/*SendConfig*/

LOCAL void SendQuit(DBusConnection *connection)
{

 DBusMessage *message;

 message = dbus_message_new_signal ("/org/share/linux",

 "org.share.linux",

 "Quit");

 /* Send the signal */

 dbus_connection_send (connection, message, NULL);
 dbus_message_unref (message);
}/*SendQuit*/


int main (int argc, char **argv)
{
 DBusConnection *connection;
 DBusError error;

 dbus_error_init (&error);
 connection = dbus_bus_get(DBUS_BUS_SESSION, &error);

 if(NULL == connection)
 {
  printf ("Failed to connect to the D-BUS daemon: %s", error.message);
  dbus_error_free (&error);
  return 1;
 }

 if( argc == 1)
 {
  printf("errror : no argument !\n");
  return 0;
 }/*if*/
 int i;

 for ( i = 1; i < argc; i++)
 {
 
  if (0 == strncmp(argv[i],"-c", 256) )
  {
   if(i + 1 < argc) 
    SendData(connection, argv[i + 1]);
   else
    SendData(connection, "test string"); 
  }
  else if ( 0 == strncmp(argv[i],"-q", 256) )
  {
   SendQuit(connection);
  }/*if*/
 }
 
 return 0;
}/*main*/

receiver.c :


#include <stdio.h>

#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <glib.h>

#ifndef TRUE
 #define TRUE      1
 #define FALSE      0
#endif

#define LOCAL      static 

LOCAL DBusHandlerResult dbus_filter(DBusConnection *connection, 

                    DBusMessage *message, void *user_data)
{
 if (FALSE != dbus_message_is_signal(message,"org.share.linux","Customize" ) )
 {
  DBusError dberr;
  char *pData;
  int len;
  
  pData = NULL;
  len = 0;
  dbus_error_init(&dberr);
  
  dbus_message_get_args(message, &dberr, 
   DBUS_TYPE_STRING, &pData,
   DBUS_TYPE_INT32 , &len, 
   DBUS_TYPE_INVALID);
  
  if(FALSE != dbus_error_is_set(&dberr)) 
  {
   printf("__LINE__ = %d\n", __LINE__);
   dbus_error_free(&dberr);       
  }
  else
  {
   printf("Message cutomize received : %s , length = %d\n", pData, len);
   return DBUS_HANDLER_RESULT_HANDLED;
  }
 }/*if*/
 

 if( FALSE != dbus_message_is_signal(message,"org.share.linux","Quit" ) )
 {
  printf("Message quit received\n");

  GMainLoop *loop = (GMainLoop*) user_data;
  g_main_loop_quit(loop);
  
  return DBUS_HANDLER_RESULT_HANDLED;
 }

 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}/*dbus_filter*/


int main(int argc, char *argv[])
{
 DBusConnection *connection;
 DBusError error;

 /* glib main loop */

 GMainLoop *loop;

 loop = g_main_loop_new(NULL,FALSE);

 dbus_error_init(&error);

 connection = dbus_bus_get(DBUS_BUS_SESSION, &error);

 if ( dbus_error_is_set(&error) )
 {
  printf("Error connecting to the daemon bus: %s",error.message);

  dbus_error_free(&error);
  return 1;
 }

 dbus_bus_add_match (connection,

 "type='signal',interface='org.share.linux'",NULL);

 dbus_connection_add_filter (connection, dbus_filter, loop, NULL);

 /* dbus-glib call */

 dbus_connection_setup_with_g_main(connection,NULL);

 /* run glib main loop */

 printf("wait receiving data:\n");
 g_main_loop_run(loop);

 return 0;
}/*main*/


Makefile :


CC := gcc
CFLAGS := -g
BITS_PATH  := x86_64-linux-gnu
#BITS_PATH := i386-linux-gnu

INC := -I/usr/include/dbus-1.0 -I/usr/lib/$(BITS_PATH)/dbus-1.0/include
INC += -I/usr/include/glib-2.0 -I/usr/lib/$(BITS_PATH)/glib-2.0/include
LIB :=  -L/usr/lib/$(BITS_PATH) -ldbus-1  -ldbus-glib-1

all:
        $(CC) $(CFLAGS)  receiver.c -o receiver $(INC) $(LIB)   
        $(CC) $(CFLAGS)  sender.c -o sender $(INC) $(LIB)
clean:
        rm -f sender receiver 

To run the 2 examples, you should build it first.
 And open a terminal and type:


gaiger@i5-3210m:~/this_working_folder$ ./receiver 
wait receiving data:

Then open another terminal and type:

gaiger@i5-3210m:~/sandbox/dbus$ ./sender -c AA
Message cutomize sending : AA , length = 2

You would find the string(AA) has been sent to the receiver.

TODO:  If you want a warning in the sender when the sending has fail (for example: the receiver program is not under running), you should use dbus_connection_send_with_reply to replace dbus_connection_send.

沒有留言:

張貼留言