Abus at a glance

53
ABUS at a glance Thierry GAYET - January 2012

Transcript of Abus at a glance

ABUS at a glance

Thierry GAYET - January 2012

Introduction

OverviewOverview

Official web site : http://code.google.com/p/abus/

A-Bus is a lightweight message bus system, a simple way for embedded applications to talk to one another, merely in professional world, but not restricted to.

The message bus is built on top of a one-to-one message passing JSON-RPC framework.

There's no daemon involved in the message bus.

Got trapped in the past with a clumsy inter process communication bus?

No sane alternative to propose as a replacement for a stinky legacy middle-ware?

It's now time to stop the hurting and get your chance to escape the wheel of reincarnation.

ABUS vs ABUS vs DBUSDBUS

GNU/Linux kernel GNU/Linux kernel

DBUSDAEM

ON

DBUS ABUS

libdbus

libdbus

binary1

binary1

libdbus

libdbus

binary1

binary1

UNIXSOCKETS

LicenceLicence

This documentation is free; you can redistribute it without any restrictions.

The modification or derived work must retain copyright and list all authors.

This documentation is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;

without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Licence : http://www.gnu.org/licenses/lgpl.html

SupportSupport

Maillist : https://accounts.google.com/ServiceLogin?service=groups2&passive=1209600&continue=http://groups.google.com/group/abus-discuss&followup=http://groups.google.com/group/abus-discuss

Abus issues : http://code.google.com/p/abus/issues/list?can=1&q=&colspec=ID+Type+Status+Priority+Milestone+Owner+Summary&cells=tiles

Build the abus library from sources

Generation & Generation & installationinstallation

Get the latest abus source code from the subversion repository :

$ svn checkout http://abus.googlecode.com/svn/trunk/ abus-read-only

Then go into the directory:

$ cd abus-read-only

If you want to test abus over json-rpc call (for web purpose), you will need this package :

$ sudo apt-get install libfcgi-dev

Abus support unitary test based on the google/test framework.

You can install it on native GNU/linux such as :

$ sudo apt-get install libgtest-dev

However, the google/test ”suck” with its autotools support, that's why we need to add a gtest.pc file in the following path : /usr/lib/pkgconfig/ with the following content :

prefix=/usrexec_prefix=${prefix}libdir=${exec_prefix}/libincludedir=${prefix}/include

Name: gtestDescription: The google test frameworkRequires: Version: 1.6.0Libs: -lgtest -L${libdir}Cflags: -I${includedir}/gtest/

This file add metadata for the abus package.

Generation & Generation & installationinstallation

Generation & Generation & installationinstallation

First we need to generate the intermediate autotools templates :

$ autoreconf -i --force

That will generate:a Makefile.in from the Makefile.am templatea configure script and abus_config.h.in from the configure.ac template

This is possible to see the configure usage: ./configure --help

Configure the abus package :

$ ./configure –prefix=/usr --enable-fcgi --enable-examples –enable-test

Build it :

$ make -j 5

Install it :

$ sudo make installor$ sudo make install DESTDIR=<INSTALL_PATH>

Check your package using google/test framework :

$ make check

← Everything must be in green (not red)

Files installedFiles installed

/usr/include/abus.hpp/usr/include/jsonrpc.h/usr/include/json.h/usr/include/abus.h/usr/include/standard.h/usr/include/hashtab.h

Headers :

/usr/lib/pkgconfig/usr/lib/pkgconfig/abus.pc

/usr/lib/libabus.la/usr/lib/libabus.so.0/usr/lib/libabus.so/usr/lib/libabus.a/usr/lib/libabus.so.0.0.0

Libraries & meta-data :

/usr/share/man/man1/abus-send.1

Online documentation :

/usr/bin/abus-send

Tools :

Abus & autotools integration

Configure Configure templatetemplate

Abus is fully compatible with recent autotools.

That provide the possibility to interract easily with the abus library such as :

(extract from a configure.ac template)

(…)dnl --------------------------------------------dnl Test if the libabus is well available in the stagingdirdnl If so get the cflags and ldflag from the .pc filednl --------------------------------------------LIBABUS_REQUIRED_VERSION=0.2~svnPKG_CHECK_MODULES([ABUS],[abus >= $LIBABUS_REQUIRED_VERSION],[have_abus=yes],[have_abus=no])if test "$have_libabus" = no ; then AC_MSG_ERROR([Missing libgtest library $LIBABUS_REQUIRED_VERSION (http://code.google.com/p/abus/) !!])Fi(…)

The above set the abus library as mandatory dependency.

Makefile.am Makefile.am templatetemplate

(extract from a Makefile.am template)

(...)bin_PROGRAMS = myBin

myBin_SOURCES = $(top_srcdir)/src/myBin.c $(top_srcdir)/src/myBin.h

myBin_CFLAG = -I$(HEADER_DIR) $(ABUS_CFLAGS)ormyBin_CPPGLAGS = $(ABUS_CPPFLAGS) ormyBin_CXXGLAGS = $(ABUS_CXXFLAGS)

myBin_LDFLAGS =

myBin_LDADD = $(ABUS_LIBS)

The abus public API

Header : abus.h

ABUS API 1/3ABUS API 1/3

const char *abus_get_version();const char *abus_get_copyright();

Global :

int abus_init(abus_t *abus);int abus_cleanup(abus_t *abus);

Initialization and clean an abus context

int abus_decl_method(abus_t *abus, const char *service_name, const char *method_name, abus_callback_t method_callback, int flags, void *arg, const char *descr, const char *fmt, const char *result_fmt);

int abus_undecl_method(abus_t *abus, const char *service_name, const char *method_name);

Declare and undeclare a method :

int abus_request_method_init(abus_t *abus, const char *service_name, const char *method_name, json_rpc_t *json_rpc);int abus_request_method_invoke(abus_t *abus, json_rpc_t *json_rpc, int flags, int timeout);int abus_request_method_cleanup(abus_t *abus, json_rpc_t *json_rpc);

Synchronous calls :

int abus_request_method_invoke_async(abus_t *abus, json_rpc_t *json_rpc, int timeout, abus_callback_t callback, int flags, void *arg);int abus_request_method_wait_async(abus_t *abus, json_rpc_t *json_rpc, int timeout);

Asynchronous calls with callback :

typedef void (*abus_callback_t)(json_rpc_t *json_rpc, void *arg);

int abus_decl_event(abus_t *abus, const char *service_name, const char *event_name, const char *descr, const char *fmt);int abus_undecl_event(abus_t *abus, const char *service_name, const char *event_name);int abus_request_event_init(abus_t *abus, const char *service_name, const char *event_name, json_rpc_t *json_rpc);int abus_request_event_publish(abus_t *abus, json_rpc_t *json_rpc, int flags);int abus_request_event_cleanup(abus_t *abus, json_rpc_t *json_rpc);int abus_event_subscribe(abus_t *abus, const char *service_name, const char *event_name, abus_callback_t callback, int flags, void *arg, int timeout);int abus_event_unsubscribe(abus_t *abus, const char *service_name, const char *event_name, abus_callback_t callback, void *arg, int timeout);

ABUS API 2/3ABUS API 2/3

Publish and subscribe :

int abus_decl_attr_int(abus_t *abus, const char *service_name, const char *attr_name, int *val, int flags, const char *descr);int abus_decl_attr_bool(abus_t *abus, const char *service_name, const char *attr_name, bool *val, int flags, const char *descr);int abus_decl_attr_double(abus_t *abus, const char *service_name, const char *attr_name, double *val, int flags, const char *descr);int abus_decl_attr_str(abus_t *abus, const char *service_name, const char *attr_name, char *val, size_t n, int flags, const char *descr);int abus_undecl_attr(abus_t *abus, const char *service_name, const char *attr_name);int abus_attr_changed(abus_t *abus, const char *service_name, const char *attr_name);int abus_append_attr(abus_t *abus, json_rpc_t *json_rpc, const char *service_name, const char *attr_name);

Attributes/data model service side :

int abus_attr_get_int(abus_t *abus, const char *service_name, const char *attr_name, int *val, int timeout);int abus_attr_get_bool(abus_t *abus, const char *service_name, const char *attr_name, bool *val, int timeout);int abus_attr_get_double(abus_t *abus, const char *service_name, const char *attr_name, double *val, int timeout);int abus_attr_get_str(abus_t *abus, const char *service_name, const char *attr_name, char *val, size_t n, int timeout);

Attributes/data model client side :

ABUS API 3/3ABUS API 3/3

int abus_attr_set_int(abus_t *abus, const char *service_name, const char *attr_name, int val, int timeout);int abus_attr_set_bool(abus_t *abus, const char *service_name, const char *attr_name, bool val, int timeout);int abus_attr_set_double(abus_t *abus, const char *service_name, const char *attr_name, double val, int timeout);int abus_attr_set_str(abus_t *abus, const char *service_name, const char *attr_name, const char *val, int timeout);

int abus_attr_subscribe_onchange(abus_t *abus, const char *service_name, const char *attr_name, abus_callback_t callback, int flags, void *arg, int timeout);int abus_attr_unsubscribe_onchange(abus_t *abus, const char *service_name, const char *attr_name, abus_callback_t callback, void *arg, int timeout);

int abus_forward_rpc(abus_t *abus, char *buffer, int *buflen, int flags, int timeout);

Fast/CGI helper :

Latest API available here : http://abus.googlecode.com/svn/doc/HEAD/html/index.html

The libjson public API

Header : json.h

The json The json standardstandard

JSON WIKIPEDIA : http://en.wikipedia.org/wiki/JSON

JSON standard (RFC) : http://www.ietf.org/rfc/rfc4627

Validate a json file : http://jsonlint.com/

JSON beautifier : http://jsonformatter.bugz.fr/

JSON SCHEMA : http://json-schema.org/

Official website : http://www.json.org/

JSON, or JavaScript Object Notation, is a lightweight text-based open standard designed for human-readable data interchange. It is derived from the JavaScript scripting language for representing simple data structures and associative arrays, called objects. Despite its relationship to JavaScript, it is language-independent, with parsers available for most languages.

The JSON format was originally specified by Douglas Crockford, and is described in RFC 4627. The official Internet media type for JSON is application/json. The JSON filename extension is .json.

The JSON format is often used for serializing and transmitting structured data over a network connection. It is used primarily to transmit data between a server and web application, serving as an alternative to XML.

The json The json standardstandard

{ "firstName": "John", "lastName" : "Smith", "age" : 25, "address" : { "streetAddress": "21 2nd Street", "city" : "New York", "state" : "NY", "postalCode" : "10021" }, "phoneNumber": [ { "type" : "home", "number": "212 555-1234" }, { "type" : "fax", "number": "646 555-4567" } ] }

Exemple of JSON :

The json The json standardstandard

The json The json standardstandard

LIBJSON APILIBJSON API

Get the parent's node :

Some function have been implemented to the libjson :

json_dom_val_t* json_config_open(const char* szJsonFilename);

void json_config_cleanup(json_dom_val_t* element);

json_dom_val_t* json_config_lookup(json_dom_val_t* element, const char* szDirectoryNane);

int json_config_get_int(json_dom_val_t* element, int* val);

Extract a node content by type :

int json_config_get_bool(json_dom_val_t* element, bool* val);

int json_config_get_string(json_dom_val_t* element, char** val);

int json_config_get_double(json_dom_val_t* element, double* val);

Locate a node and extract its content by type :int json_config_get_direct_int(json_dom_val_t* root, const char* directoryName, const char* attributeName, int* val);

bool json_config_get_direct_bool(json_dom_val_t* root, const char* directoryName, const char* attributeName, bool* val);

int json_config_get_direct_string(json_dom_val_t* root, const char* directoryName, const char* attributeName, char** val);

int json_config_get_direct_double(json_dom_val_t* root, const char* directoryName, const char* attributeName, double* val);

Example 1/2Example 1/2

int main(int argc, char* argv[], char* env[]){

int ret = -1;char* valItem = NULL;char* valItem2 = NULL;char* valItem3 = NULL;json_dom_val_t* json_dom = NULL;json_dom_val_t* myParentItem = NULL;json_dom_val_t* myItem = NULL;

/* Load and parse the json file */if (argc >=2){

if ( NULL != (json_dom = json_config_open(argv[1]))){

printf("\n [DBG] JSON init and converted into a DOM : OK ");printf("\n [DBG] Looking for the parent item ('result') . . .");

/* --------------------------------------------------------- *//* First example *//* --------------------------------------------------------- */if (NULL != (myParentItem = json_config_lookup(json_dom, "networking"))){

printf("\n [DBG] Parent item 'networking' (%p) well found", myParentItem);if (NULL != (myItem = json_config_lookup(myParentItem, "ipaddress"))){

printf("\n [DBG] Child item 'ipaddress' (%p) well found ", myItem);if (-1 != (ret = json_config_get_string(myItem, &valItem)))

printf("\n [DBG] Item's value = '%s' ", valItem);else

printf("\n [ERROR] Problem to get the item's value ");} else {

printf("\n [ERROR] Child item not found ");} /* IF */

Example 2/2Example 2/2

if (NULL != (myItem = json_config_lookup(myParentItem, "gateway"))){

printf("\n [DBG] Child item 'gateway' (%p) well found ", myItem);if (-1 != (ret = json_config_get_string(myItem, &valItem2)))

printf("\n [DBG] Item's value = '%s' ", valItem2);else

printf("\n [ERROR] Problem to get the item's value ");} else {

printf("\n [ERROR] Child item not found ");} /* IF */

} else {printf("\n [ERROR] Parent item not found ");

} /* IF */

/* --------------------------------------------------------- *//* Second example *//* --------------------------------------------------------- */json_config_get_direct_string(json_dom, "networking", "ipaddress", &valItem3);printf("\n [DBG] Item's value = '%s' ", valItem3);

/* Cleaning the dom */if (NULL != json_dom)

json_config_cleanup(json_dom);} else {

printf("\n [ERROR] JSON init and converted into a DOM : NOK ");} /* IF */printf("\n");

} else {printf("\n [ERROR] Expected parameter to %s !!", argv[0]);printf("\n [ERROR] Usage: %s <json file> ", argv[0]);

} /* IF */

return(ret);}

LIBJSON APILIBJSON API

Roadmap :

- extension with datamodel request

libabuslibabus libabus

client service

local unix sockets

First example : simple service and client

Simple abus service 1/2Simple abus service 1/2

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <errno.h>

#include "abus.h"

/* Main function */int main(int argc, char **argv){

/* Declare the abus context */ abus_t abus;

/* Initialize the abus context */ abus_init(&abus);

/* Register a first method */ abus_decl_method(&abus, "examplesvc", "sum", &svc_sum_cb, ABUS_RPC_FLAG_NONE, "sumator cookie", "Compute summation of two integers", "a:i:first operand,b:i:second operand", "res_value:i:summation");

/* Register another methode */ abus_decl_method(&abus, "examplesvc", "mult", &svc_mult_cb, ABUS_RPC_FLAG_NONE, "multiply cookie", "Compute multiplication of two integers", "a:i:first operand,b:i:second operand", "res_value:i:multiplication");

/* do other stuff */ sleep(10000); /* Clean the abus context – it unregister all methods */ abus_cleanup(&abus);

/* Exit the main function and provide a return code */ return EXIT_SUCCESS;} example-service.c

Simple abus service 2/2Simple abus service 2/2

static void svc_sum_cb(json_rpc_t *json_rpc, void *arg){ int a, b; int ret;

ret = json_rpc_get_int(json_rpc, "a", &a);

if (ret == 0) ret = json_rpc_get_int(json_rpc, "b", &b);

printf("## %s: arg=%s, ret=%d, a=%d, b=%d, => result=%d\n", __func__, (const char*)arg, ret, a, b, a+b);

if (ret) json_rpc_set_error(json_rpc, ret, NULL); else json_rpc_append_int(json_rpc, "res_value", a+b);}

static void svc_mult_cb(json_rpc_t *json_rpc, void *arg){ int a, b; int ret;

ret = json_rpc_get_int(json_rpc, "a", &a);

if (ret == 0) ret = json_rpc_get_int(json_rpc, "b", &b);

printf("## %s: arg=%s, ret=%d, a=%d, b=%d, => result=%d\n", __func__, (const char*)arg, ret, a, b, a*b);

if (ret) json_rpc_set_error(json_rpc, ret, NULL); else json_rpc_append_int(json_rpc, "res_value", a*b);}

example-service.c

Simple abus client 1/2Simple abus client 1/2

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>

#include "abus.h"

#define RPC_TIMEOUT 1000 /* in ms */

int main(int argc, char **argv){ abus_t abus; json_rpc_t json_rpc; int ret;

Int res_value;

const char *service_name = "examplesvc";

if (argc < 4) { printf("usage: %s METHOD firstvalue secondvalue\n", argv[0]); exit(EXIT_FAILURE); }

abus_init(&abus);

/* method name is taken from command line */ ret = abus_request_method_init(&abus, service_name, argv[1], &json_rpc); if (ret) exit(EXIT_FAILURE);

/* pass 2 parameters: "a" and "b" */ json_rpc_append_int(&json_rpc, "a", atoi(argv[2])); json_rpc_append_int(&json_rpc, "b", atoi(argv[3]));

example-client.c

Simple abus client 2/2Simple abus client 2/2

ret = abus_request_method_invoke(&abus, &json_rpc, ABUS_RPC_FLAG_NONE, RPC_TIMEOUT); if (ret != 0) { printf("RPC failed with error %d\n", ret); exit(EXIT_FAILURE); }

ret = json_rpc_get_int(&json_rpc, "res_value", &res_value); if (ret == 0) printf("res_value=%d\n", res_value); else printf("No result? error %d\n", ret);

abus_request_method_cleanup(&abus, &json_rpc);

abus_cleanup(&abus);

return EXIT_SUCCESS;}

example-client.c

libabuslibabus libabus

client service

local unix sockets

Second example : working with array

Abus service Abus service with arraywith array

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <errno.h>

#include "abus.h"

static void svc_array_sqr_cb(json_rpc_t *json_rpc, void *arg){ int k, a; int ret, count, i; int *ary = NULL;

ret = json_rpc_get_int(json_rpc, "k", &k); if (ret != 0) { json_rpc_set_error(json_rpc, ret, NULL); return; }

count = json_rpc_get_array_count(json_rpc, "my_array"); if (count >= 0) { /* first put all the values in an array, in order to not mix json_rpc_get's and json_rpc_append's for readability sake */ ary = malloc(count*sizeof(int)); for (i = 0; i<count; i++) { /* Aim at i-th element within array "my_array" */ ret = json_rpc_get_point_at(json_rpc, "my_array", i); if (ret != 0) break; /* from that dictionary, get parameter "a" * Rem: expects all array elements to contain at least a param "a" */ ret = json_rpc_get_int(json_rpc, "a", &ary[i]); if (ret != 0) break; } } example-svc-array.c

printf("## %s: arg=%s, ret=%d, k=%d, array count=%d\n", __func__, (const char*)arg, ret, k, count); if (ret) { json_rpc_set_error(json_rpc, ret, NULL); } else { json_rpc_append_int(json_rpc, "res_k", k); /* begin the array */ json_rpc_append_args(json_rpc, JSON_KEY, "res_array", -1, JSON_ARRAY_BEGIN, -1); for (i = 0; i<count; i++) { /* each array element *must* be an "OBJECT", i.e. a dictonary */ json_rpc_append_args(json_rpc, JSON_OBJECT_BEGIN, -1); json_rpc_append_int(json_rpc, "res_a", ary[i]*ary[i]); /* more stuff may be appended in there */ json_rpc_append_args(json_rpc, JSON_OBJECT_END, -1); } /* end the array */ json_rpc_append_args(json_rpc, JSON_ARRAY_END, -1); } if (ary) free(ary);}

example-svc-array.c

Abus service Abus service with arraywith array

int main(int argc, char **argv){ abus_t abus; abus_init(&abus); abus_decl_method(&abus, "examplearraysvc", "sqr", &svc_array_sqr_cb, ABUS_RPC_FLAG_NONE, "square cookie", "Compute square value of all the elements of an array. Serves as an example of how to deal with array in A-Bus", "k:i:some contant,my_array:(a:i:value to be squared,arg_index:i:index of arg for demo):array of stuff", "res_k:i:same contant,res_array:(res_a:i:squared value):array of squared stuff"); /* do other stuff */ sleep(10000); abus_cleanup(&abus); return EXIT_SUCCESS;}

example-svc-array.c

Abus service Abus service with arraywith array

example-clnt-array.c

Abus client Abus client with arraywith array

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>

#include "abus.h"

#define RPC_TIMEOUT 1000 /* ms */

int main(int argc, char **argv){ abus_t abus; json_rpc_t json_rpc; int count, i, ret, res_value;

const char *service_name = "examplearraysvc"; if (argc < 4) { printf("usage: %s METHOD k values...\n", argv[0]); exit(EXIT_FAILURE); }

abus_init(&abus);

/* method name is taken from command line */ ret = abus_request_method_init(&abus, service_name, argv[1], &json_rpc); if (ret) exit(EXIT_FAILURE);

/* pass 2 parameters: "k" and "my_array" */ json_rpc_append_int(&json_rpc, "k", atoi(argv[2]));

/* begin the array */ json_rpc_append_args(&json_rpc, JSON_KEY, "my_array", -1, JSON_ARRAY_BEGIN, -1);

example-clnt-array.c

Abus client Abus client with arraywith array

ret = abus_request_method_invoke(&abus, &json_rpc, ABUS_RPC_FLAG_NONE, RPC_TIMEOUT); if (ret != 0) { printf("RPC failed with error %d\n", ret); exit(EXIT_FAILURE); }

count = json_rpc_get_array_count(&json_rpc, "res_array"); if (count < 0) { printf("No result? error %d\n", count); exit(EXIT_FAILURE); }

ret = json_rpc_get_int(&json_rpc, "res_k", &res_value); if (ret == 0) printf("res_k=%d\n", res_value); else printf("No result? error %d\n", ret);

for (i = 0; i<count; i++) { /* Aim at i-th element within array "res_array" */ json_rpc_get_point_at(&json_rpc, "res_array", i);

printf("res_array[%d]\n", i);

ret = json_rpc_get_int(&json_rpc, "res_a", &res_value); if (ret == 0) printf("\tres_a=%d\n", res_value); else printf("\tNo result? error %d\n", ret); }

example-clnt-array.c

Abus client Abus client with arraywith array

/* Aim back out of array */ json_rpc_get_point_at(&json_rpc, NULL, i); ret = json_rpc_get_int(&json_rpc, "res_k", &res_value); if (ret == 0) printf("res_k=%d (should be the same as previously)\n", res_value); else printf("No result? error %d\n", ret);

abus_request_method_cleanup(&abus, &json_rpc);

abus_cleanup(&abus);

return EXIT_SUCCESS;}

libabuslibabus libabus

client service

local unix sockets

Third example : exporting objects

Abus service Abus service with arraywith array

This example is a service named "exampleattrsvc" written in C, dealing with attributes in a data model. To be used with the client example-clnt-attr.

You may also use the abus-send program to test it:

abus-send exampleattrsvc.get tree.some_intabus-send exampleattrsvc.get tree.abus-send exampleattrsvc.set tree.some_int:i:128abus-send exampleattrsvc.get ""

Here is how to play with event emitted upon attribute change (one event every 5 seconds):

abus-send exampleattrsvc.subscribe attr_changed%tree.auto_count

example-svc-attr.c

Abus service Abus service with arraywith array

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <errno.h>

#include "abus.h"

int main(int argc, char **argv){ abus_t abus; const char *servicename = "exampleattrsvc"; int i; int my_int = 42; int my_other_int = -2; int my_auto_count = 0;

abus_init(&abus);

abus_decl_attr_int(&abus, servicename, "tree.some_int", &my_int, ABUS_RPC_FLAG_NONE, "Some integer, for demo purpose"); abus_decl_attr_int(&abus, servicename, "tree.some_other_int", &my_other_int, ABUS_RPC_FLAG_NONE, "Some other integer, still for demo purpose"); abus_decl_attr_int(&abus, servicename, "tree.auto_count", &my_auto_count, ABUS_RPC_FLAG_NONE, "Counter incremented every 5 seconds"); /* do other stuff */ for (i = 0; i < 1000; i++) { sleep(5); my_auto_count++; /* trigger event notification */ abus_attr_changed(&abus, servicename, "tree.auto_count"); } abus_cleanup(&abus);

return EXIT_SUCCESS;}

example-clnt-attr.c

Abus client Abus client with arraywith array

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>

#include "abus.h"

#define RPC_TIMEOUT 1000 /* ms */

int main(int argc, char **argv){ abus_t abus; json_rpc_t json_rpc; int ret; const char *service_name = "exampleattrsvc"; const char *attr_name; int my_int;

if (argc < 2) { printf("usage: %s ATTR newintegervalue\n", argv[0]); printf("usage: ATTR: some_int|some_other_int\n", argv[0]); exit(EXIT_FAILURE); }

abus_init(&abus);

/* attr name is taken from command line */ attr_name = argv[1]; ret = abus_attr_get_int(&abus, service_name, attr_name, &my_int, RPC_TIMEOUT); if (ret) { printf("RPC failed with error %d\n", ret); abus_cleanup(&abus); exit(EXIT_FAILURE); }

example-clnt-attr.c

Abus client Abus client with arraywith array

printf("Previous value: %s=%d\n", attr_name, my_int);

my_int = atoi(argv[2]); ret = abus_attr_set_int(&abus, service_name, attr_name, my_int, RPC_TIMEOUT); if (ret) { printf("RPC failed with error %d\n", ret); abus_cleanup(&abus); exit(EXIT_FAILURE);

}

printf("New value: %s=%d\n", attr_name, my_int);

abus_cleanup(&abus);

return EXIT_SUCCESS;}

libabuslibabus libabus

client service

local unix sockets

Fourth example : working with event

example-svc-event.c

Abus service Abus service with eventswith events

#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <errno.h>

#include "abus.h"

static void chomp(char *s){ int len = strlen(s); if (len > 0 && s[len-1] == '\n') s[len-1] = '\0';}

int main(int argc, char **argv){ abus_t abus; char s[128]; abus_init(&abus);#define MYSVCNAME "examplesvc"#define MYEVTNAME "enter_pressed" abus_decl_event(&abus, MYSVCNAME, MYEVTNAME, "Event sent each time the ENTER key is press. Serves as publish/subscribe example.", "typed_char:s:keys pressed before the ENTER key"); /* cheap event generator: press ENTER key on stdin Attached to the event, the chars typed in before the ENTER key */ while (fgets(s, sizeof(s), stdin) != NULL) { json_rpc_t json_rpc; chomp(s); abus_request_event_init(&abus, MYSVCNAME, MYEVTNAME, &json_rpc); json_rpc_append_str(&json_rpc, "typed_char", s); abus_request_event_publish(&abus, &json_rpc, 0); abus_request_event_cleanup(&abus, &json_rpc); } abus_cleanup(&abus); return EXIT_SUCCESS;}

http://abus.googlecode.com/svn/doc/HEAD/html/examples.html

More example available here :

Want some Want some more more examples ?examples ?

Advance abus

The abus-The abus-send toolsend tool

abus-send [options] SERVICE.METHOD [key:[bfilsae]]=value]... -h, --help this help message -t, --timeout=TIMEOUT timeout in milliseconds (1000) -v, --verbose verbose -V, --version version of A-Bus -y, --async asynchronous query -w, --wait-async wait for asynchronous query, without callback

Some examples:

Global introspection: abus-send myAbusService.\*

Calling a method without parameters: abus-send myAbusService.getDeviceState

Calling a method with parameters: abus-send myAbusService.setDeviceState \ newState:b=false

Getting an object: abus-send myAbusService.get deviceinfo.abus-send myAbusService.get ""

The abus-The abus-monitormonitor

An abus-monitor should come in the future.

Abus & Abus & environmentenvironment

If you want that the libabus dump the json messages to stdout, you just have to export a variable :

export ABUS_MSG_VERBOSE=1

That will generate such trace:

## 4067 <- 00083:70 {"jsonrpc":"2.0","method":"DmngCoreStub.getConfig","id":1,"params":{}}## 4067 -> 00083:2220 {"jsonrpc":"2.0","result":{"device.stateID":false,"device.actionID":0,"device.languageID":0,"device.uptime":742,"mainPower.isPowerConnected":0,"mainPower.batteryLevel":41,"audio.ModeID":1,"audio.BitRate":64,"video.ModeType":0,"video.BitRate":44,"video.Frequency":0,"liveProfile":[{"id":0,"name":"INTERVIEW","rate":12,"modeID":0,"studioID":0,"resolutionID":0,"videoInputID":0,"delay":12},{"id":1,"name":"BALANCED","rate":5,"modeID":1,"studioID":4,"resolutionID":1,"videoInputID":1,"delay":14},{"id":2,"name":"QUALITY","rate":6,"modeID":1,"studioID":3,"resolutionID":0,"videoInputID":2,"delay":20},{"id":3,"name":"LOW DELAY","rate":4,"modeID":1,"studioID":2,"resolutionID":0,"videoInputID":1,"delay":5},{"id":4,"name":"BGAN","rate":2,"modeID":0,"studioID":0,"resolutionID":1,"videoInputID":2,"delay":10}],"studioListing":[{"studioId":0,"name":"studio1","ipAddress":"","channel":2,"controlLink":true},{"studioId":1,"name":"studio2","ipAddress":"","channel":4,"controlLink":false},{"studioId":2,"name":"studio3","ipAddress":"","channel":1,"controlLink":true},{"studioId":3,"name":"studio4","ipAddress":"","channel":3,"controlLink":true}],"massstorageListing":[{"id":0,"devname":"/dev/sda1","label":"toto","uuid":"110E8400-E29B-11D4-A716-446655440000","mountPoint":"/tmp/disk1","totalSize":5000000,"freeSize":500000,"filesystem":39,"type":0,"isWrite":true},{"id":1,"devname":"/dev/sda2","label":"","uuid":"550e8400-e29b-41d4-a716-446655440000","mountPoint":"/tmp/disk2","totalSize":2000000,"freeSize":20000,"filesystem":39,"type":1,"isWrite":false}],"networkinterfaceListing":[{"id":0,"status":1,"mode":0,"type":0,"tx":30,"rx":6,"bandwitch":3,"ifname":"eth0","ipAddress":"192.168.0.5","netmask":"255.255.255.0","gateway":"192.168.0.1"},{"id":1,"status":1,"mode":1,"type":0,"tx":26,"rx":1,"bandwitch":10,"ifname":"eth1","ipAddress":"192.168.2.4","netmask":"255.255.255.0","gateway":"192.168.0.1"},{"id":2,"status":1,"mode":1,"type":0,"tx":19,"rx":30,"bandwitch":27,"ifname":"eth2","ipAddress":"10.11.133.4","netmask":"255.255.0.0","gateway":"10.11.133.1"},{"id":3,"status":1,"mode":1,"type":1,"tx":48,"rx":14,"bandwitch":14,"ifname":"ath0","ipAddress":"192.168.0.8","netmask":"255.255.255.0","gateway":"192.168.0.1"}]},"id":1}

ABUS ABUS ROADMAPROADMAP

Here are some points for the abus evolution in the nearest future :

- event management for web purpose- some security

For more detail : http://code.google.com/p/abus/wiki/ABusNotes

Thanks for you attention

Any question about ?