• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Abus at a glance
 

Abus at a glance

on

  • 1,036 views

abus message bus

abus message bus

Statistics

Views

Total Views
1,036
Views on SlideShare
1,036
Embed Views
0

Actions

Likes
0
Downloads
8
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Abus at a glance Abus at a glance Presentation Transcript

      • ABUS at a glance
      • Thierry GAYET - January 2012
    • Introduction
    • 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.
        Overview
    • DBUS ABUS UNIX SOCKETS
        ABUS vs DBUS
      GNU/Linux kernel GNU/Linux kernel DBUS DAEMON libdbus libdbus binary1 binary1 libdbus libdbus binary1 binary1
    • 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
        Licence
    • 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
        Support
    • Build the abus library from sources
    • 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
        Generation & installation
    • 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=/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: gtest Description: The google test framework Requires: Version: 1.6.0 Libs: -lgtest -L${libdir} Cflags: -I${includedir}/gtest/ This file add metadata for the abus package.
        Generation & installation
    • First we need to generate the intermediate autotools templates : $ autoreconf -i --force That will generate: a Makefile.in from the Makefile.am template a 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 install or $ sudo make install DESTDIR=<INSTALL_PATH> Check your package using google/test framework : $ make check ← Everything must be in green (not red )
        Generation & installation
    • /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 :
        Files installed
    • Abus & autotools integration
    • 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 stagingdir dnl If so get the cflags and ldflag from the .pc file dnl -------------------------------------------- LIBABUS_REQUIRED_VERSION=0.2~svn PKG_CHECK_MODULES([ABUS],[abus >= $LIBABUS_REQUIRED_VERSION],[have_abus=yes],[have_abus=no]) if test &quot;$have_libabus&quot; = 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.
        Configure template
    • (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) or myBin _CPPGLAGS = $(ABUS_CPPFLAGS) or myBin _CXXGLAGS = $(ABUS_CXXFLAGS) myBin _LDFLAGS = myBin _LDADD = $(ABUS_LIBS)
        Makefile.am template
    • The abus public API Header : abus.h
    • 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);
        ABUS API 1/3
    • 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); 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 2/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
        ABUS API 3/3
    • The libjson public API Header : json.h
    • 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  J ava S cript O bject N otation, 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 standard
    • { &quot;firstName&quot;: &quot;John&quot;, &quot;lastName&quot; : &quot;Smith&quot;, &quot;age&quot; : 25, &quot;address&quot; : { &quot;streetAddress&quot;: &quot;21 2nd Street&quot;, &quot;city&quot; : &quot;New York&quot;, &quot;state&quot; : &quot;NY&quot;, &quot;postalCode&quot; : &quot;10021&quot; }, &quot;phoneNumber&quot;: [ { &quot;type&quot; : &quot;home&quot;, &quot;number&quot;: &quot;212 555-1234&quot; }, { &quot;type&quot; : &quot;fax&quot;, &quot;number&quot;: &quot;646 555-4567&quot; } ] } Exemple of JSON :
        The json standard
      • The json standard
      • The json standard
    • 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);
        LIBJSON API
    • 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( &quot;n [DBG] JSON init and converted into a DOM : OK &quot; ); printf( &quot;n [DBG] Looking for the parent item ('result') . . .&quot; ); /* --------------------------------------------------------- */ /* First example */ /* --------------------------------------------------------- */ if (NULL != (myParentItem = json_config_lookup(json_dom, &quot;networking&quot; ))) { printf( &quot;n [DBG] Parent item 'networking' (%p) well found&quot; , myParentItem); if (NULL != (myItem = json_config_lookup(myParentItem, &quot; ipaddress &quot; ))) { printf( &quot;n [DBG] Child item ' ipaddress ' (%p) well found &quot; , myItem); if (-1 != (ret = json_config_get_string(myItem, &valItem))) printf( &quot;n [DBG] Item's value = '%s' &quot; , valItem); else printf( &quot;n [ERROR] Problem to get the item's value &quot; ); } else { printf( &quot;n [ERROR] Child item not found &quot; ); } /* IF */
        Example 1/2
    • if (NULL != (myItem = json_config_lookup(myParentItem, &quot;gateway&quot; ))) { printf( &quot;n [DBG] Child item 'gateway' (%p) well found &quot; , myItem); if (-1 != (ret = json_config_get_string(myItem, &valItem2))) printf( &quot;n [DBG] Item's value = '%s' &quot; , valItem2); else printf( &quot;n [ERROR] Problem to get the item's value &quot; ); } else { printf( &quot;n [ERROR] Child item not found &quot; ); } /* IF */ } else { printf( &quot;n [ERROR] Parent item not found &quot; ); } /* IF */ /* --------------------------------------------------------- */ /* Second example */ /* --------------------------------------------------------- */ json_config_get_direct_string(json_dom, &quot;networking&quot; , &quot; ipaddress &quot; , &valItem3); printf( &quot;n [DBG] Item's value = '%s' &quot; , valItem3); /* Cleaning the dom */ if (NULL != json_dom) json_config_cleanup(json_dom); } else { printf( &quot;n [ERROR] JSON init and converted into a DOM : NOK &quot; ); } /* IF */ printf( &quot;n&quot; ); } else { printf( &quot;n [ERROR] Expected parameter to %s !!&quot; , argv[0]); printf( &quot;n [ERROR] Usage: %s <json file> &quot; , argv[0]); } /* IF */ return (ret); }
        Example 2/2
    • Roadmap : - extension with datamodel request
        LIBJSON API
    • local unix sockets First example : simple service and client libabus libabus libabus client service
    • #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include &quot;abus.h&quot; /* 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, &quot;examplesvc&quot;, &quot;sum&quot;, &svc_sum_cb, ABUS_RPC_FLAG_NONE, &quot;sumator cookie&quot;, &quot;Compute summation of two integers&quot;, &quot;a:i:first operand,b:i:second operand&quot;, &quot;res_value:i:summation&quot;); /* Register another methode */ abus_decl_method (&abus, &quot;examplesvc&quot;, &quot;mult&quot;, &svc_mult_cb, ABUS_RPC_FLAG_NONE, &quot;multiply cookie&quot;, &quot;Compute multiplication of two integers&quot;, &quot;a:i:first operand,b:i:second operand&quot;, &quot;res_value:i:multiplication&quot;); /* 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 1/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, &quot;a&quot;, &a); if (ret == 0) ret = json_rpc_get_int (json_rpc, &quot;b&quot;, &b); printf(&quot;## %s: arg=%s, ret=%d, a=%d, b=%d, => result=%dn&quot;, __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, &quot;res_value&quot;, 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, &quot;a&quot;, &a); if (ret == 0) ret = json_rpc_get_int (json_rpc, &quot;b&quot;, &b); printf(&quot;## %s: arg=%s, ret=%d, a=%d, b=%d, => result=%dn&quot;, __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, &quot;res_value&quot;, a*b); } example-service.c
        Simple abus service 2/2
    • #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include &quot;abus.h&quot; #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 = &quot;examplesvc&quot;; if (argc < 4) { printf(&quot;usage: %s METHOD firstvalue secondvaluen&quot;, 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: &quot;a&quot; and &quot;b&quot; */ json_rpc_append_int (&json_rpc, &quot;a&quot;, atoi(argv[2])); json_rpc_append_int (&json_rpc, &quot;b&quot;, atoi(argv[3])); example-client.c
        Simple abus client 1/2
    • ret = abus_request_method_invoke (&abus, &json_rpc, ABUS_RPC_FLAG_NONE, RPC_TIMEOUT); if (ret != 0) { printf(&quot;RPC failed with error %dn&quot;, ret); exit(EXIT_FAILURE); } ret = json_rpc_get_int (&json_rpc, &quot;res_value&quot;, &res_value); if (ret == 0) printf(&quot;res_value=%dn&quot;, res_value); else printf(&quot;No result? error %dn&quot;, ret); abus_request_method_cleanup (&abus, &json_rpc); abus_cleanup (&abus); return EXIT_SUCCESS; } example-client.c
        Simple abus client 2/2
    • local unix sockets Second example : working with array libabus libabus libabus client service
    • #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include &quot;abus.h&quot; 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, &quot;k&quot;, &k); if (ret != 0) { json_rpc_set_error (json_rpc, ret, NULL); return; } count = json_rpc_get_array_count (json_rpc, &quot;my_array&quot;); 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 &quot;my_array&quot; */ ret = json_rpc_get_point_at (json_rpc, &quot;my_array&quot;, i); if (ret != 0) break; /* from that dictionary, get parameter &quot;a&quot; * Rem: expects all array elements to contain at least a param &quot;a&quot; */ ret = json_rpc_get_int (json_rpc, &quot;a&quot;, &ary[i]); if (ret != 0) break; } } example-svc-array.c
        Abus service with array
    • printf(&quot;## %s: arg=%s, ret=%d, k=%d, array count=%dn&quot;, __func__, (const char*)arg, ret, k, count); if (ret) { json_rpc_set_error (json_rpc, ret, NULL); } else { json_rpc_append_int (json_rpc, &quot;res_k&quot;, k); /* begin the array */ json_rpc_append_args (json_rpc, JSON_KEY, &quot;res_array&quot;, -1, JSON_ARRAY_BEGIN, -1); for (i = 0; i<count; i++) { /* each array element *must* be an &quot;OBJECT&quot;, i.e. a dictonary */ json_rpc_append_args (json_rpc, JSON_OBJECT_BEGIN, -1); json_rpc_append_int (json_rpc, &quot;res_a&quot;, 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 with array
    • int main(int argc, char **argv) { abus_t abus; abus_init (&abus); abus_decl_method (&abus, &quot;examplearraysvc&quot;, &quot;sqr&quot;, &svc_array_sqr_cb, ABUS_RPC_FLAG_NONE, &quot;square cookie&quot;, &quot;Compute square value of all the elements of an array. Serves as an example of how to deal with array in A-Bus&quot;, &quot;k:i:some contant,my_array:(a:i:value to be squared,arg_index:i:index of arg for demo):array of stuff&quot;, &quot;res_k:i:same contant,res_array:(res_a:i:squared value):array of squared stuff&quot;); /* do other stuff */ sleep(10000); abus_cleanup (&abus); return EXIT_SUCCESS; } example-svc-array.c
        Abus service with array
    • example-clnt-array.c #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include &quot;abus.h&quot; #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 = &quot;examplearraysvc&quot;; if (argc < 4) { printf(&quot;usage: %s METHOD k values...n&quot;, 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: &quot;k&quot; and &quot;my_array&quot; */ json_rpc_append_int (&json_rpc, &quot;k&quot;, atoi(argv[2])); /* begin the array */ json_rpc_append_args (&json_rpc, JSON_KEY, &quot;my_array&quot;, -1, JSON_ARRAY_BEGIN, -1);
        Abus client with array
    • example-clnt-array.c ret = abus_request_method_invoke (&abus, &json_rpc, ABUS_RPC_FLAG_NONE, RPC_TIMEOUT); if (ret != 0) { printf(&quot;RPC failed with error %dn&quot;, ret); exit(EXIT_FAILURE); } count = json_rpc_get_array_count (&json_rpc, &quot;res_array&quot;); if (count < 0) { printf(&quot;No result? error %dn&quot;, count); exit(EXIT_FAILURE); } ret = json_rpc_get_int (&json_rpc, &quot;res_k&quot;, &res_value); if (ret == 0) printf(&quot;res_k=%dn&quot;, res_value); else printf(&quot;No result? error %dn&quot;, ret); for (i = 0; i<count; i++) { /* Aim at i-th element within array &quot;res_array&quot; */ json_rpc_get_point_at (&json_rpc, &quot;res_array&quot;, i); printf(&quot;res_array[%d]n&quot;, i); ret = json_rpc_get_int (&json_rpc, &quot;res_a&quot;, &res_value); if (ret == 0) printf(&quot;tres_a=%dn&quot;, res_value); else printf(&quot;tNo result? error %dn&quot;, ret); }
        Abus client with array
    • example-clnt-array.c /* Aim back out of array */ json_rpc_get_point_at (&json_rpc, NULL, i); ret = json_rpc_get_int (&json_rpc, &quot;res_k&quot;, &res_value); if (ret == 0) printf(&quot;res_k=%d (should be the same as previously)n&quot;, res_value); else printf(&quot;No result? error %dn&quot;, ret); abus_request_method_cleanup (&abus, &json_rpc); abus_cleanup (&abus); return EXIT_SUCCESS; }
        Abus client with array
    • local unix sockets Third example : exporting objects libabus libabus libabus client service
    • This example is a service named &quot;exampleattrsvc&quot; 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_int abus-send exampleattrsvc.get tree. abus-send exampleattrsvc.set tree.some_int:i:128 abus-send exampleattrsvc.get &quot;&quot; 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
        Abus service with array
    • example-svc-attr.c #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include &quot;abus.h&quot; int main(int argc, char **argv) { abus_t abus; const char *servicename = &quot;exampleattrsvc&quot;; 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, &quot;tree.some_int&quot;, &my_int, ABUS_RPC_FLAG_NONE, &quot;Some integer, for demo purpose&quot;); abus_decl_attr_int (&abus, servicename, &quot;tree.some_other_int&quot;, &my_other_int, ABUS_RPC_FLAG_NONE, &quot;Some other integer, still for demo purpose&quot;); abus_decl_attr_int (&abus, servicename, &quot;tree.auto_count&quot;, &my_auto_count, ABUS_RPC_FLAG_NONE, &quot;Counter incremented every 5 seconds&quot;); /* do other stuff */ for (i = 0; i < 1000; i++) { sleep(5); my_auto_count++; /* trigger event notification */ abus_attr_changed (&abus, servicename, &quot;tree.auto_count&quot;); } abus_cleanup (&abus); return EXIT_SUCCESS; }
        Abus service with array
    • example-clnt-attr.c #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include &quot;abus.h&quot; #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 = &quot;exampleattrsvc&quot;; const char *attr_name; int my_int; if (argc < 2) { printf(&quot;usage: %s ATTR newintegervaluen&quot;, argv[0]); printf(&quot;usage: ATTR: some_int|some_other_intn&quot;, 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(&quot;RPC failed with error %dn&quot;, ret); abus_cleanup (&abus); exit(EXIT_FAILURE); }
        Abus client with array
    • example-clnt-attr.c printf(&quot;Previous value: %s=%dn&quot;, 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(&quot;RPC failed with error %dn&quot;, ret); abus_cleanup (&abus); exit(EXIT_FAILURE); } printf(&quot;New value: %s=%dn&quot;, attr_name, my_int); abus_cleanup (&abus); return EXIT_SUCCESS; }
        Abus client with array
    • local unix sockets Fourth example : working with event libabus libabus libabus client service
    • example-svc-event.c #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <errno.h> #include &quot;abus.h&quot; 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 &quot;examplesvc&quot; #define MYEVTNAME &quot;enter_pressed&quot; abus_decl_event (&abus, MYSVCNAME, MYEVTNAME, &quot;Event sent each time the ENTER key is press. Serves as publish/subscribe example.&quot;, &quot;typed_char:s:keys pressed before the ENTER key&quot;); /* 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, &quot;typed_char&quot;, s); abus_request_event_publish (&abus, &json_rpc, 0); abus_request_event_cleanup (&abus, &json_rpc); } abus_cleanup (&abus); return EXIT_SUCCESS; }
        Abus service with events
    • http://abus.googlecode.com/svn/doc/HEAD/html/examples.html More example available here :
        Want some more examples ?
    • Advance abus
    • 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 &quot;&quot;
        The abus-send tool
    • An abus-monitor should come in the future.
        The abus-monitor
    • 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 {&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;method&quot;:&quot;DmngCoreStub.getConfig&quot;,&quot;id&quot;:1,&quot;params&quot;:{}} ## 4067 -> 00083:2220 {&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;result&quot;:{&quot;device.stateID&quot;:false,&quot;device.actionID&quot;:0,&quot;device.languageID&quot;:0,&quot;device.uptime&quot;:742,&quot;mainPower.isPowerConnected&quot;:0,&quot;mainPower.batteryLevel&quot;:41,&quot;audio.ModeID&quot;:1,&quot;audio.BitRate&quot;:64,&quot;video.ModeType&quot;:0,&quot;video.BitRate&quot;:44,&quot;video.Frequency&quot;:0,&quot;liveProfile&quot;:[{&quot;id&quot;:0,&quot;name&quot;:&quot;INTERVIEW&quot;,&quot;rate&quot;:12,&quot;modeID&quot;:0,&quot;studioID&quot;:0,&quot;resolutionID&quot;:0,&quot;videoInputID&quot;:0,&quot;delay&quot;:12},{&quot;id&quot;:1,&quot;name&quot;:&quot;BALANCED&quot;,&quot;rate&quot;:5,&quot;modeID&quot;:1,&quot;studioID&quot;:4,&quot;resolutionID&quot;:1,&quot;videoInputID&quot;:1,&quot;delay&quot;:14},{&quot;id&quot;:2,&quot;name&quot;:&quot;QUALITY&quot;,&quot;rate&quot;:6,&quot;modeID&quot;:1,&quot;studioID&quot;:3,&quot;resolutionID&quot;:0,&quot;videoInputID&quot;:2,&quot;delay&quot;:20},{&quot;id&quot;:3,&quot;name&quot;:&quot;LOW DELAY&quot;,&quot;rate&quot;:4,&quot;modeID&quot;:1,&quot;studioID&quot;:2,&quot;resolutionID&quot;:0,&quot;videoInputID&quot;:1,&quot;delay&quot;:5},{&quot;id&quot;:4,&quot;name&quot;:&quot;BGAN&quot;,&quot;rate&quot;:2,&quot;modeID&quot;:0,&quot;studioID&quot;:0,&quot;resolutionID&quot;:1,&quot;videoInputID&quot;:2,&quot;delay&quot;:10}],&quot;studioListing&quot;:[{&quot;studioId&quot;:0,&quot;name&quot;:&quot;studio1&quot;,&quot;ipAddress&quot;:&quot;&quot;,&quot;channel&quot;:2,&quot;controlLink&quot;:true},{&quot;studioId&quot;:1,&quot;name&quot;:&quot;studio2&quot;,&quot;ipAddress&quot;:&quot;&quot;,&quot;channel&quot;:4,&quot;controlLink&quot;:false},{&quot;studioId&quot;:2,&quot;name&quot;:&quot;studio3&quot;,&quot;ipAddress&quot;:&quot;&quot;,&quot;channel&quot;:1,&quot;controlLink&quot;:true},{&quot;studioId&quot;:3,&quot;name&quot;:&quot;studio4&quot;,&quot;ipAddress&quot;:&quot;&quot;,&quot;channel&quot;:3,&quot;controlLink&quot;:true}],&quot;massstorageListing&quot;:[{&quot;id&quot;:0,&quot;devname&quot;:&quot;/dev/sda1&quot;,&quot;label&quot;:&quot;toto&quot;,&quot;uuid&quot;:&quot;110E8400-E29B-11D4-A716-446655440000&quot;,&quot;mountPoint&quot;:&quot;/tmp/disk1&quot;,&quot;totalSize&quot;:5000000,&quot;freeSize&quot;:500000,&quot;filesystem&quot;:39,&quot;type&quot;:0,&quot;isWrite&quot;:true},{&quot;id&quot;:1,&quot;devname&quot;:&quot;/dev/sda2&quot;,&quot;label&quot;:&quot;&quot;,&quot;uuid&quot;:&quot;550e8400-e29b-41d4-a716-446655440000&quot;,&quot;mountPoint&quot;:&quot;/tmp/disk2&quot;,&quot;totalSize&quot;:2000000,&quot;freeSize&quot;:20000,&quot;filesystem&quot;:39,&quot;type&quot;:1,&quot;isWrite&quot;:false}],&quot;networkinterfaceListing&quot;:[{&quot;id&quot;:0,&quot;status&quot;:1,&quot;mode&quot;:0,&quot;type&quot;:0,&quot;tx&quot;:30,&quot;rx&quot;:6,&quot;bandwitch&quot;:3,&quot;ifname&quot;:&quot;eth0&quot;,&quot;ipAddress&quot;:&quot;192.168.0.5&quot;,&quot;netmask&quot;:&quot;255.255.255.0&quot;,&quot;gateway&quot;:&quot;192.168.0.1&quot;},{&quot;id&quot;:1,&quot;status&quot;:1,&quot;mode&quot;:1,&quot;type&quot;:0,&quot;tx&quot;:26,&quot;rx&quot;:1,&quot;bandwitch&quot;:10,&quot;ifname&quot;:&quot;eth1&quot;,&quot;ipAddress&quot;:&quot;192.168.2.4&quot;,&quot;netmask&quot;:&quot;255.255.255.0&quot;,&quot;gateway&quot;:&quot;192.168.0.1&quot;},{&quot;id&quot;:2,&quot;status&quot;:1,&quot;mode&quot;:1,&quot;type&quot;:0,&quot;tx&quot;:19,&quot;rx&quot;:30,&quot;bandwitch&quot;:27,&quot;ifname&quot;:&quot;eth2&quot;,&quot;ipAddress&quot;:&quot;10.11.133.4&quot;,&quot;netmask&quot;:&quot;255.255.0.0&quot;,&quot;gateway&quot;:&quot;10.11.133.1&quot;},{&quot;id&quot;:3,&quot;status&quot;:1,&quot;mode&quot;:1,&quot;type&quot;:1,&quot;tx&quot;:48,&quot;rx&quot;:14,&quot;bandwitch&quot;:14,&quot;ifname&quot;:&quot;ath0&quot;,&quot;ipAddress&quot;:&quot;192.168.0.8&quot;,&quot;netmask&quot;:&quot;255.255.255.0&quot;,&quot;gateway&quot;:&quot;192.168.0.1&quot;}]},&quot;id&quot;:1}
        Abus & environment
    • 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
        ABUS ROADMAP
    • Thanks for you attention Any question about ?