Removing legacy dbus-1 library
authorJosé Bollo <jose.bollo@iot.bzh>
Tue, 3 May 2016 15:05:36 +0000 (17:05 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Wed, 4 May 2016 09:55:38 +0000 (11:55 +0200)
Change-Id: I1c1d17cd702e12ed961ed90d1489bc12b074bd55
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
plugins/CMakeLists.txt
plugins/afm-main-plugin/CMakeLists.txt
plugins/afm-main-plugin/afm-main-plugin.c
plugins/afm-main-plugin/utils-jbus.c
plugins/afm-main-plugin/utils-jbus.h
plugins/afm-main-plugin/utils-sbus.c [deleted file]
plugins/afm-main-plugin/utils-sbus.h [deleted file]

index 5d8b26a..c60e352 100644 (file)
@@ -1,4 +1,4 @@
-#ADD_SUBDIRECTORY(afm-main-plugin)
+ADD_SUBDIRECTORY(afm-main-plugin)
 ADD_SUBDIRECTORY(session)
 ADD_SUBDIRECTORY(samples)
 #ADD_SUBDIRECTORY(audio)
index 8aaa134..5ed1d4b 100644 (file)
@@ -1,5 +1,5 @@
 
-ADD_LIBRARY(afm-main-api MODULE afm-main-plugin.c utils-sbus.c utils-jbus.c)
+ADD_LIBRARY(afm-main-api MODULE afm-main-plugin.c utils-jbus.c)
 SET_TARGET_PROPERTIES(afm-main-api PROPERTIES PREFIX "")
 TARGET_LINK_LIBRARIES(afm-main-api ${link_libraries})
 INCLUDE_DIRECTORIES(${include_dirs})
index 21e27e8..c6408a5 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "afb-plugin.h"
 
-#include "utils-sbus.h"
 #include "utils-jbus.h"
 
 static const char _added_[]     = "added";
@@ -331,39 +330,23 @@ static const struct AFB_plugin plug_desc = {
        .apis = plug_apis
 };
 
-static struct sbus_itf sbusitf;
-
 const struct AFB_plugin *pluginRegister(const struct AFB_interface *itf)
 {
        int rc;
-       struct afb_pollmgr pollmgr;
-       struct sbus *sbus;
+       struct sd_bus *sbus;
 
        /* records the interface */
        assert (interface == NULL);
        interface = itf;
        evmgr = afb_daemon_get_evmgr(itf->daemon);
 
-       /* creates the sbus for session */
-       pollmgr = afb_daemon_get_pollmgr(itf->daemon);
-       sbusitf.wait = pollmgr.itf->wait;
-       sbusitf.open = pollmgr.itf->open;
-       sbusitf.on_readable = pollmgr.itf->on_readable;
-       sbusitf.on_writable = pollmgr.itf->on_writable;
-       sbusitf.on_hangup = pollmgr.itf->on_hangup;
-       sbusitf.close = pollmgr.itf->close;
-       sbus = sbus_session(&sbusitf, pollmgr.closure);
-       if (sbus == NULL) {
-               fprintf(stderr, "ERROR: %s:%d: can't connect to DBUS session\n", __FILE__, __LINE__);
-               return NULL;
-       }
-
        /* creates the jbus for accessing afm-user-daemon */
+       sbus = afb_daemon_get_user_bus(itf->daemon);
+       if (sbus == NULL)
+               return NULL;
        jbus = create_jbus(sbus, "/org/AGL/afm/user");
-        if (jbus == NULL) {
-               sbus_unref(sbus);
+        if (jbus == NULL)
                return NULL;
-       }
 
        /* records the signal handler */
        rc = jbus_on_signal_s(jbus, _changed_, application_list_changed, NULL);
index 4872987..d3f2302 100644 (file)
@@ -25,8 +25,8 @@
 #include <assert.h>
 
 #include <json.h>
+#include <systemd/sd-bus.h>
 
-#include "utils-sbus.h"
 #include "utils-jbus.h"
 
 /*
@@ -45,9 +45,9 @@ static const char out_of_memory_string[] = "out of memory";
 struct jservice {
        struct jservice *next;  /* link to the next service */
        char *method;           /* method name for the service */
-       void (*oncall_s) (struct sbusmsg *, const char *, void *);
+       void (*oncall_s) (struct sd_bus_message *, const char *, void *);
                                /* string callback */
-       void (*oncall_j) (struct sbusmsg *, struct json_object *, void *);
+       void (*oncall_j) (struct sd_bus_message *, struct json_object *, void *);
                                /* json callback */
        void *data;             /* closure data for the callbacks */
 };
@@ -70,7 +70,9 @@ struct jsignal {
  */
 struct jrespw {
        struct jbus *jbus;
-       void (*onresp) (int, struct json_object *, void *);
+       void (*onresp_s) (int, const char *, void *);
+                               /* string callback */
+       void (*onresp_j) (int, struct json_object *, void *);
                                /* json callback */
        void *data;             /* closure data for the callbacks */
 };
@@ -80,9 +82,9 @@ struct jrespw {
  */
 struct jbus {
        int refcount;                   /* referenced how many time */
-       struct sbus *sbus;
-       struct sbus_service *sservice;
-       struct sbus_signal *ssignal;
+       struct sd_bus *sdbus;
+       struct sd_bus_slot *sservice;
+       struct sd_bus_slot *ssignal;
        struct json_tokener *tokener;   /* string to json tokenizer */
        struct jservice *services;      /* first service */
        struct jsignal *signals;        /* first signal */
@@ -92,13 +94,21 @@ struct jbus {
 
 /*********************** STATIC COMMON METHODS *****************/
 
+static int mkerrno(int rc)
+{
+       if (rc >= 0)
+               return rc;
+       errno = -rc;
+       return -1;
+}
+
 /*
  * Replies the error "out of memory".
  * This function is intended to be used in services when an
  * allocation fails. Thus, it set errno to ENOMEM and
  * returns -1.
  */
-static inline int reply_out_of_memory(struct sbusmsg *smsg)
+static inline int reply_out_of_memory(struct sd_bus_message *smsg)
 {
        jbus_reply_error_s(smsg, out_of_memory_string);
        errno = ENOMEM;
@@ -124,13 +134,21 @@ static int jparse(struct jbus *jbus, const char *msg, struct json_object **obj)
        return 0;
 }
 
-static void on_service_call(struct sbusmsg *smsg, const char *content, struct jbus *jbus)
+static int on_service_call(struct sd_bus_message *smsg, struct jbus *jbus, sd_bus_error *error)
 {
        struct jservice *service;
-       const char *member;
+       const char *member, *content;
        struct json_object *obj;
 
-       member = sbus_member(smsg);
+       /* check the type */
+       if (!sd_bus_message_has_signature(smsg, "s")
+         || sd_bus_message_read_basic(smsg, 's', &content) < 0) {
+               sd_bus_error_set_const(error, "bad signature", "");
+               return 1;
+       }
+
+       /* dispatch */
+       member = sd_bus_message_get_member(smsg);
        service = jbus->services;
        while (service != NULL) {
                if (!strcmp(service->method, member)) {
@@ -142,9 +160,11 @@ static void on_service_call(struct sbusmsg *smsg, const char *content, struct jb
                                service->oncall_j(smsg, obj, service->data);
                                json_object_put(obj);
                        }
+                       return 1;
                }
                service = service->next;
        }
+       return 0;
 }
 
 /*
@@ -158,19 +178,20 @@ static void on_service_call(struct sbusmsg *smsg, const char *content, struct jb
 static int add_service(
                struct jbus *jbus,
                const char *method,
-               void (*oncall_s) (struct sbusmsg *, const char *, void *),
-               void (*oncall_j) (struct sbusmsg *, struct json_object *, void *),
+               void (*oncall_s) (struct sd_bus_message *, const char *, void *),
+               void (*oncall_j) (struct sd_bus_message *, struct json_object *, void *),
                void *data)
 {
+       int rc;
        struct jservice *srv;
 
        /* connection of the service */
        if (jbus->sservice == NULL) {
-               jbus->sservice = sbus_add_service(jbus->sbus,
-                               NULL, jbus->path, jbus->name, NULL,
-                               (void*)on_service_call, jbus);
-               if (jbus->sservice == NULL)
+               rc = sd_bus_add_object(jbus->sdbus, &jbus->sservice, jbus->path, (void*)on_service_call, jbus);
+               if (rc < 0) {
+                       errno = -rc;
                        goto error;
+               }
        }
 
        /* allocation */
@@ -197,17 +218,22 @@ static int add_service(
  error2:
        free(srv);
  error:
-       errno = ENOMEM;
        return -1;
 }
 
-static void on_signal_event(const struct sbusmsg *smsg, const char *content, struct jbus *jbus)
+static int on_signal_event(struct sd_bus_message *smsg, struct jbus *jbus, sd_bus_error *error)
 {
        struct jsignal *signal;
-       const char *member;
+       const char *member, *content;
        struct json_object *obj;
 
-       member = sbus_member(smsg);
+       /* check the type */
+       if (!sd_bus_message_has_signature(smsg, "s")
+         || sd_bus_message_read_basic(smsg, 's', &content) < 0)
+               return 0;
+
+       /* dispatch */
+       member = sd_bus_message_get_member(smsg);
        signal = jbus->signals;
        while (signal != NULL) {
                if (!strcmp(signal->name, member)) {
@@ -222,6 +248,7 @@ static void on_signal_event(const struct sbusmsg *smsg, const char *content, str
                }
                signal = signal->next;
        }
+       return 0;
 }
 
 /*
@@ -241,24 +268,36 @@ static int add_signal(
                void (*onsignal_j) (struct json_object *, void *),
                void *data)
 {
+       int rc;
        struct jsignal *sig;
+       char *match;
 
        /* connection of the signal */
        if (jbus->ssignal == NULL) {
-               jbus->ssignal = sbus_add_signal(jbus->sbus,
-                               NULL, jbus->path, jbus->name, NULL,
-                               (void*)on_signal_event, jbus);
-               if (jbus->ssignal == NULL)
+               rc = asprintf(&match, "type='signal',path='%s',interface='%s'", jbus->path, jbus->name);
+               if (rc < 0) {
+                       errno = ENOMEM;
                        goto error;
+               }
+               rc = sd_bus_add_match(jbus->sdbus, &jbus->ssignal, match, (void*)on_signal_event, jbus);
+               free(match);
+               if (rc < 0) {
+                       errno = -rc;
+                       goto error;
+               }
        }
 
        /* allocation */
        sig = malloc(sizeof *sig);
-       if (sig == NULL)
+       if (sig == NULL) {
+               errno = ENOMEM;
                goto error;
+       }
        sig->name = strdup(name);
-       if (!sig->name)
+       if (!sig->name) {
+               errno = ENOMEM;
                goto error2;
+       }
 
        /* record the signal */
        sig->onsignal_s = onsignal_s;
@@ -272,19 +311,38 @@ static int add_signal(
  error2:
        free(sig);
  error:
-       errno = ENOMEM;
        return -1;
 }
 
-static void on_reply_j(int status, const char *reply, struct jrespw *jrespw)
+static int on_reply(struct sd_bus_message *smsg, struct jrespw *jrespw, sd_bus_error *error)
 {
        struct json_object *obj;
+       const char *reply;
+       int iserror;
+
+       /* check the type */
+       if (!sd_bus_message_has_signature(smsg, "s")
+         || sd_bus_message_read_basic(smsg, 's', &reply) < 0) {
+               sd_bus_error_set_const(error, "bad signature", "");
+               goto end;
+       }
+       iserror = sd_bus_message_is_method_error(smsg, NULL);
+
+       /* dispatch string? */
+       if (jrespw->onresp_s != NULL) {
+               jrespw->onresp_s(iserror, reply, jrespw->data);
+               goto end;
+       }
 
+       /* dispatch json */
        if (!jparse(jrespw->jbus, reply, &obj))
                obj = json_object_new_string(reply);
-       jrespw->onresp(status, obj, jrespw->data);
+       jrespw->onresp_j(iserror, obj, jrespw->data);
        json_object_put(obj);
+
+ end:
        free(jrespw);
+       return 1;
 }
 
 /*
@@ -304,31 +362,33 @@ static int call(
                void (*onresp_j) (int, struct json_object *, void *),
                void *data)
 {
+       int rc;
        struct jrespw *resp;
 
-       if (onresp_j == NULL)
-               return sbus_call(jbus->sbus, jbus->name, jbus->path, jbus->name,
-                               method, query, onresp_s, data);
-
        /* allocates the response structure */
        resp = malloc(sizeof *resp);
-       if (resp == NULL)
+       if (resp == NULL) {
+               errno = ENOMEM;
                goto error;
+       }
 
        /* fulfill the response structure */
        resp->jbus = jbus;
-       resp->onresp = onresp_j;
+       resp->onresp_s = onresp_s;
+       resp->onresp_j = onresp_j;
        resp->data = data;
-       if (sbus_call(jbus->sbus, jbus->name, jbus->path, jbus->name,
-                               method, query, (void*)on_reply_j, resp))
+
+       rc = sd_bus_call_method_async(jbus->sdbus, NULL, jbus->name, jbus->path, jbus->name, method, (void*)on_reply, resp, "s", query);
+       if (rc < 0) {
+               errno = -rc;
                goto error2;
+       }
 
        return 0;
 
  error2:
        free(resp);
  error:
-       errno = ENOMEM;
        return -1;
 }
 
@@ -351,7 +411,7 @@ static int call(
  *
  * Returns the created jbus or NULL in case of error.
  */
-struct jbus *create_jbus(struct sbus *sbus, const char *path)
+struct jbus *create_jbus(struct sd_bus *sdbus, const char *path)
 {
        struct jbus *jbus;
        char *name;
@@ -400,7 +460,7 @@ struct jbus *create_jbus(struct sbus *sbus, const char *path)
        }
 
        /* connect and init */
-       jbus->sbus = sbus;
+       jbus->sdbus = sd_bus_ref(sdbus);
 
        return jbus;
 
@@ -438,12 +498,12 @@ void jbus_unref(struct jbus *jbus)
                        free(sig);
                }
                if (jbus->sservice != NULL)
-                       sbus_remove_service(jbus->sbus, jbus->sservice);
+                       sd_bus_slot_unref(jbus->sservice);
                if (jbus->ssignal != NULL)
-                       sbus_remove_signal(jbus->sbus, jbus->ssignal);
+                       sd_bus_slot_unref(jbus->ssignal);
                if (jbus->tokener != NULL)
                        json_tokener_free(jbus->tokener);
-               sbus_unref(jbus->sbus);
+               sd_bus_unref(jbus->sdbus);
                free(jbus->name);
                free(jbus->path);
                free(jbus);
@@ -456,9 +516,9 @@ void jbus_unref(struct jbus *jbus)
  *
  * Returns 0 in case of success or -1 in case of error.
  */
-int jbus_reply_error_s(struct sbusmsg *smsg, const char *error)
+int jbus_reply_error_s(struct sd_bus_message *smsg, const char *error)
 {
-       return sbus_reply_error(smsg, error);
+       return mkerrno(sd_bus_reply_method_errorf(smsg, "error", "%s", error));
 }
 
 /*
@@ -467,7 +527,7 @@ int jbus_reply_error_s(struct sbusmsg *smsg, const char *error)
  *
  * Returns 0 in case of success or -1 in case of error.
  */
-int jbus_reply_error_j(struct sbusmsg *smsg, struct json_object *reply)
+int jbus_reply_error_j(struct sd_bus_message *smsg, struct json_object *reply)
 {
        const char *str = json_object_to_json_string(reply);
        return str ? jbus_reply_error_s(smsg, str) : reply_out_of_memory(smsg);
@@ -479,9 +539,9 @@ int jbus_reply_error_j(struct sbusmsg *smsg, struct json_object *reply)
  *
  * Returns 0 in case of success or -1 in case of error.
  */
-int jbus_reply_s(struct sbusmsg *smsg, const char *reply)
+int jbus_reply_s(struct sd_bus_message *smsg, const char *reply)
 {
-       return sbus_reply(smsg, reply);
+       return mkerrno(sd_bus_reply_method_return(smsg, "s", reply));
 }
 
 /*
@@ -490,7 +550,7 @@ int jbus_reply_s(struct sbusmsg *smsg, const char *reply)
  *
  * Returns 0 in case of success or -1 in case of error.
  */
-int jbus_reply_j(struct sbusmsg *smsg, struct json_object *reply)
+int jbus_reply_j(struct sd_bus_message *smsg, struct json_object *reply)
 {
        const char *str = json_object_to_json_string(reply);
        return str ? jbus_reply_s(smsg, str) : reply_out_of_memory(smsg);
@@ -503,7 +563,7 @@ int jbus_reply_j(struct sbusmsg *smsg, struct json_object *reply)
  */
 int jbus_send_signal_s(struct jbus *jbus, const char *name, const char *content)
 {
-       return sbus_send_signal(jbus->sbus, jbus->name, jbus->path, jbus->name, name, content);
+       return mkerrno(sd_bus_emit_signal(jbus->sdbus, jbus->path, jbus->name, name, "s", content));
 }
 
 /*
@@ -528,7 +588,7 @@ int jbus_send_signal_j(struct jbus *jbus, const char *name,
  *
  * The callback 'oncall' is invoked for handling incoming method
  * calls. It receives 3 parameters:
- *   1. struct sbusmsg *: a handler to data to be used for replying
+ *   1. struct sd_bus_message *: a handler to data to be used for replying
  *   2. const char *: the received string
  *   3. void *: the closure 'data' set by this function
  *
@@ -537,7 +597,7 @@ int jbus_send_signal_j(struct jbus *jbus, const char *name,
 int jbus_add_service_s(
                struct jbus *jbus,
                const char *method,
-               void (*oncall) (struct sbusmsg *, const char *, void *),
+               void (*oncall) (struct sd_bus_message *, const char *, void *),
                void *data)
 {
        return add_service(jbus, method, oncall, NULL, data);
@@ -549,7 +609,7 @@ int jbus_add_service_s(
  *
  * The callback 'oncall' is invoked for handling incoming method
  * calls. It receives 3 parameters:
- *   1. struct sbusmsg *: a handler to data to be used for replying
+ *   1. struct sd_bus_message *: a handler to data to be used for replying
  *   2. struct json_object *: the received json
  *   3. void *: the closure 'data' set by this function
  *
@@ -558,7 +618,7 @@ int jbus_add_service_s(
 int jbus_add_service_j(
                struct jbus *jbus,
                const char *method,
-               void (*oncall) (struct sbusmsg *, struct json_object *, void *),
+               void (*oncall) (struct sd_bus_message *, struct json_object *, void *),
                void *data)
 {
        return add_service(jbus, method, NULL, oncall, data);
@@ -575,7 +635,7 @@ int jbus_add_service_j(
  */
 int jbus_start_serving(struct jbus *jbus)
 {
-       return sbus_add_name(jbus->sbus, jbus->name);
+       return mkerrno(sd_bus_request_name(jbus->sdbus, jbus->name, 0));
 }
 
 /*
@@ -683,8 +743,31 @@ char *jbus_call_ss_sync(
                const char *method,
                const char *query)
 {
-       return sbus_call_sync(jbus->sbus, jbus->name, jbus->path, jbus->name,
-                       method, query);
+       sd_bus_message *smsg = NULL;
+        sd_bus_error error = SD_BUS_ERROR_NULL;
+       char *result = NULL;
+       const char *reply;
+
+       /* makes the call */
+       if (mkerrno(sd_bus_call_method(jbus->sdbus, jbus->name, jbus->path, jbus->name, method, &error, &smsg, "s", query)) < 0)
+               goto error;
+
+       /* check if error */
+       if (sd_bus_message_is_method_error(smsg, NULL))
+               goto error;
+
+       /* check the returned type */
+       if (!sd_bus_message_has_signature(smsg, "s")
+         || sd_bus_message_read_basic(smsg, 's', &reply) < 0)
+               goto error;
+
+       /* get the result */
+       result = strdup(reply);
+
+error:
+       sd_bus_message_unref(smsg);
+       sd_bus_error_free(&error);
+       return result;
 }
 
 /*
@@ -788,33 +871,37 @@ int jbus_on_signal_j(
 #if defined(SERVER)||defined(CLIENT)
 #include <stdio.h>
 #include <unistd.h>
-#include "utils-upoll.h"
 
-static int mwait(int timeout, void *closure)
+static struct sd_bus *msbus()
 {
-       upoll_wait(-1);
-       return 0;
+       static struct sd_bus *r = NULL;
+       if (r == NULL) {
+               static sd_event *e;
+               sd_event_default(&e);
+               sd_bus_open_user(&r);
+               sd_bus_attach_event(r, e, 0);
+       }
+       return r;
 }
 
-static const struct sbus_itf uitf = {
-       .wait = (void*)mwait,
-       .open = (void*)upoll_open,
-       .on_readable = (void*)upoll_on_readable,
-       .on_writable = (void*)upoll_on_writable,
-       .on_hangup = (void*)upoll_on_hangup,
-       .close = (void*)upoll_close
-};
-
-static struct sbus *sbus;
-static struct jbus *jbus;
+static sd_event *events()
+{
+       static sd_event *ev = NULL;
+       if (ev == NULL)
+               ev = sd_bus_get_event(msbus());
+       return ev;
+}
 
-static struct sbus *msbus()
+static int mwait(int timeout, void *closure)
 {
-       return sbus ? : (sbus = sbus_session(&uitf, NULL));
+       sd_event_run(events(), -1);
+       return 0;
 }
 
+static struct jbus *jbus;
+
 #ifdef SERVER
-void ping(struct sbusmsg *smsg, struct json_object *request, void *unused)
+void ping(struct sd_bus_message *smsg, struct json_object *request, void *unused)
 {
        printf("ping(%s) -> %s\n", json_object_to_json_string(request),
               json_object_to_json_string(request));
@@ -822,7 +909,7 @@ void ping(struct sbusmsg *smsg, struct json_object *request, void *unused)
        json_object_put(request);
 }
 
-void incr(struct sbusmsg *smsg, struct json_object *request, void *unused)
+void incr(struct sd_bus_message *smsg, struct json_object *request, void *unused)
 {
        static int counter = 0;
        struct json_object *res = json_object_new_int(++counter);
@@ -862,7 +949,7 @@ void signaled(const char *content, void *data)
 
 int main()
 {
-       int i = 10;
+       int i = 1;
        jbus = create_jbus(msbus(), "/bzh/iot/jdbus");
        jbus_on_signal_s(jbus, "incremented", signaled, "closure-signal");
        while (i--) {
index d85b8af..ff4c8fa 100644 (file)
 
 #pragma once
 
-struct sbusmsg;
+struct sd_bus;
+
+struct sd_bus_message;
 struct jbus;
 
-extern struct jbus *create_jbus(struct sbus *sbus, const char *path);
+extern struct jbus *create_jbus(struct sd_bus *sdbus, const char *path);
 
 extern void jbus_addref(struct jbus *jbus);
 extern void jbus_unref(struct jbus *jbus);
@@ -89,31 +91,31 @@ extern int jbus_on_signal_j(
 
 /* verbs for servers */
 extern int jbus_reply_s(
-               struct sbusmsg *smsg,
+               struct sd_bus_message *smsg,
                const char *reply);
 
 extern int jbus_reply_j(
-               struct sbusmsg *smsg,
+               struct sd_bus_message *smsg,
                struct json_object *reply);
 
 extern int jbus_reply_error_s(
-               struct sbusmsg *smsg,
+               struct sd_bus_message *smsg,
                const char *reply);
 
 extern int jbus_reply_error_j(
-               struct sbusmsg *smsg,
+               struct sd_bus_message *smsg,
                struct json_object *reply);
 
 extern int jbus_add_service_s(
                struct jbus *jbus,
                const char *method,
-               void (*oncall) (struct sbusmsg *, const char *, void *),
+               void (*oncall) (struct sd_bus_message *, const char *, void *),
                void *data);
 
 extern int jbus_add_service_j(
                struct jbus *jbus,
                const char *method,
-               void (*oncall) (struct sbusmsg *, struct json_object *, void *),
+               void (*oncall) (struct sd_bus_message *, struct json_object *, void *),
                void *data);
 
 extern int jbus_start_serving(
diff --git a/plugins/afm-main-plugin/utils-sbus.c b/plugins/afm-main-plugin/utils-sbus.c
deleted file mode 100644 (file)
index a5c63c6..0000000
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- Copyright 2015 IoT.bzh
-
- author: José Bollo <jose.bollo@iot.bzh>
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-#define _GNU_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <poll.h>
-#include <assert.h>
-
-#include <dbus/dbus.h>
-
-#include "utils-sbus.h"
-
-/*
- * errors messages generated by sbus
- */
-static const char invalid_request_string[] = "invalid request";
-static const char out_of_memory_string[] = "out of memory";
-
-/*
- * structure for handled messages
- */
-struct sbusmsg {
-       DBusMessage *message;       /* message of the message */
-       DBusConnection *connection; /* connection of the message */
-};
-
-/*
- * structure for services
- */
-struct sbus_service {
-       struct sbus_service *next;      /* link to the next service */
-       char *destination;              /* destination for the service */
-       char *path;             /* path for the service */
-       char *iface;            /* iface for the service */
-       char *member;           /* member for the service */
-       void (*oncall) (struct sbusmsg *, const char *, void *);
-                               /* callback */
-       void *closure;          /* closure for the callbacks */
-};
-
-/*
- * structure for signals
- */
-struct sbus_signal {
-       struct sbus_signal *next;       /* link to the next signal */
-       char *sender;           /* expected sender of the signal */
-       char *path;             /* expected path of the signal */
-       char *iface;            /* expected iface of the signal */
-       char *member;           /* expected member of the signal */
-       void (*onsignal) (const struct sbusmsg *, const char *, void *);
-                               /* callback */
-       void *closure;          /* closure for the callbacks */
-};
-
-/*
- * structure for asynchronous requests (resp-onse w-aiter)
- */
-struct srespw {
-       struct srespw *next;    /* next asynchronous */
-       dbus_uint32_t serial;   /* serial dbus number */
-       void *closure;          /* closure for the callbacks */
-       void (*onresp) (int, const char *, void *);
-                               /* callback */
-};
-
-/*
- * structure for synchronous calls
- */
-struct respsync {
-       int replied;    /* boolean flag indicating reply */
-       int status;     /* received status */
-       char *value;    /* copy of the returned value */
-};
-
-/*
- * structure for handling either client or server sbus on dbus
- */
-struct sbus {
-       int refcount;                   /* referenced how many time */
-       DBusConnection *connection;     /* connection to DBU */
-       const struct sbus_itf *itf;     /* interface to the main loop */
-       void *itfclo;
-       struct sbus_service *services;  /* first service */
-       struct sbus_signal *signals;    /* first signal */
-       struct srespw *waiters;         /* first response waiter */
-       
-};
-
-static struct sbus system_sbus;
-static struct sbus session_sbus;
-
-/*********************** STATIC COMMON METHODS *****************/
-
-/*
- * Frees the ressources attached to a message
- */
-static inline void free_sbusmsg(struct sbusmsg *smsg)
-{
-       dbus_message_unref(smsg->message);
-       dbus_connection_unref(smsg->connection);
-       free(smsg);
-}
-
-/*
- * Replies the error "out of memory".
- * This function is intended to be used in services when an
- * allocation fails. Thus, it set errno to ENOMEM and
- * returns -1.
- */
-static inline int reply_out_of_memory(struct sbusmsg *smsg)
-{
-       sbus_reply_error(smsg, out_of_memory_string);
-       errno = ENOMEM;
-       return -1;
-}
-
-/*
- * Checks if the incoming 'message' matches the interface
- * linked to 'sbus'.
- *
- * Returns 1 if it matches or 0 wether it does not matches.
- */
-/*
-static int matchitf(struct sbus *sbus, DBusMessage * message)
-{
-       const char *itf = dbus_message_get_interface(message);
-       return itf != NULL && !strcmp(itf, sbus->name);
-}
-*/
-
-/*
- * Callback function for synchronous calls.
- * This function fills the respsync structure pointed by 'data'
- * with the copy of the answer.
- */
-static void sync_of_replies(int status, const char *value, struct respsync *s)
-{
-       s->status = status;
-       s->value = status ? NULL : strdup(value ? value : "");
-       s->replied = 1;
-}
-
-/*
- * Creates and returns the rule for 'signal'.
- */
-static char *rule_of_signal(struct sbus_signal *signal)
-{
-       char *rule;
-       return asprintf(&rule,
-                       "type='signal%s%s%s%s%s%s%s%s'",
-                       signal->sender ? "',sender='" : "",
-                               signal->sender ? signal->sender : "",
-                       signal->path   ? "',path='" : "",
-                               signal->path   ? signal->path : "",
-                       signal->iface  ? "',interface='" : "",
-                               signal->iface  ? signal->iface : "",
-                       signal->member  ? "',member='" : "",
-                               signal->member  ? signal->member : ""
-               ) < 0 ? NULL : rule;
-}
-
-/*********************** STATIC DBUS MESSAGE HANDLING *****************/
-
-/*
- * Handles incomming responses 'message' on 'sbus'. Response are
- * either expected if 'iserror' == 0 or errors if 'iserror' != 0.
- *
- * Returns DBUS_HANDLER_RESULT_HANDLED or DBUS_HANDLER_RESULT_NOT_YET_HANDLED
- * as defined by the dbus function 'dbus_connection_add_filter'.
- */
-static DBusHandlerResult incoming_resp(
-               struct sbus *sbus,
-               DBusMessage * message,
-               int iserror)
-{
-       int status;
-       const char *str;
-       struct srespw *jrw, **prv;
-       dbus_uint32_t serial;
-
-       /* search for the waiter */
-       serial = dbus_message_get_reply_serial(message);
-       prv = &sbus->waiters;
-       while ((jrw = *prv) != NULL) {
-               if (jrw->serial == serial)
-                       goto found;
-               prv = &jrw->next;
-       }
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-       /* treat it */
- found:
-       *prv = jrw->next;
-       if (jrw->onresp) {
-               /* retrieve the string value */
-               if (dbus_message_get_args
-                   (message, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID))
-                       status = 0;
-               else {
-                       status = -1;
-                       str = NULL;
-               }
-               /* call now */
-               jrw->onresp(iserror ? -1 : status, str, jrw->closure);
-       }
-       free(jrw);
-       return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-/*
- * Handles incomming on 'sbus' method calls for 'message'.
- *
- * Returns DBUS_HANDLER_RESULT_HANDLED or DBUS_HANDLER_RESULT_NOT_YET_HANDLED
- * as defined by the dbus function 'dbus_connection_add_filter'.
- */
-static DBusHandlerResult incoming_call(
-               struct sbus *sbus,
-               DBusMessage * message)
-{
-       struct sbus_service *service;
-       struct sbusmsg *smsg;
-       const char *str;
-
-       /* search for the service */
-       service = sbus->services;
-       while (service != NULL) {
-               if ((service->destination == NULL || !strcmp(service->destination, dbus_message_get_destination(message)))
-                && (service->path == NULL || !strcmp(service->path, dbus_message_get_path(message)))
-                && (service->iface == NULL || !strcmp(service->iface, dbus_message_get_interface(message)))
-                && (service->member == NULL || !strcmp(service->member, dbus_message_get_member(message))))
-                       goto found;
-               service = service->next;
-       }
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- found:
-       /* creates and init the smsg structure */
-       smsg = malloc(sizeof *smsg);
-       if (smsg == NULL)
-               return DBUS_HANDLER_RESULT_NEED_MEMORY;
-       smsg->message = dbus_message_ref(message);
-       smsg->connection = dbus_connection_ref(sbus->connection);
-
-       /* retrieve the string parameter of the message */
-       if (!dbus_message_get_args
-           (message, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID))
-               goto invalid_request;
-
-       /* handling strings only */
-       service->oncall(smsg, str, service->closure);
-       return DBUS_HANDLER_RESULT_HANDLED;
-
-invalid_request:
-       sbus_reply_error(smsg, invalid_request_string);
-       return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-/*
- * Handles incomming on 'sbus' signal propagated with 'message'.
- *
- * This is a design choice to ignore invalid signals.
- *
- * Returns DBUS_HANDLER_RESULT_HANDLED or DBUS_HANDLER_RESULT_NOT_YET_HANDLED
- * as defined by the dbus function 'dbus_connection_add_filter'.
- */
-static DBusHandlerResult incoming_signal(
-               struct sbus *sbus,
-               DBusMessage * message)
-{
-       DBusHandlerResult result;
-       struct sbus_signal *signal;
-       struct sbusmsg smsg;
-       const char *str;
-
-       /* retrieve the string value */
-       result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-       if (!dbus_message_get_args(message, NULL,
-                               DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID))
-               goto end;
-
-       /* search a handler */
-       smsg.message = message;
-       smsg.connection = NULL;
-       signal = sbus->signals;
-       while (signal != NULL) {
-               if ((signal->path == NULL || !strcmp(signal->path, dbus_message_get_path(message)))
-                && (signal->iface == NULL || !strcmp(signal->iface, dbus_message_get_interface(message)))
-                && (signal->member == NULL || !strcmp(signal->member, dbus_message_get_member(message)))) {
-                       signal->onsignal(&smsg, str, signal->closure);
-                       result = DBUS_HANDLER_RESULT_HANDLED;
-               }
-               signal = signal->next;
-       }
- end:
-       return result;
-}
-
-/*
- * Filters incomming messages as defined by the dbus function
- * 'dbus_connection_add_filter'.
- * Returns DBUS_HANDLER_RESULT_HANDLED or DBUS_HANDLER_RESULT_NOT_YET_HANDLED.
- */
-static DBusHandlerResult incoming(
-               DBusConnection * connection,
-               DBusMessage * message,
-               struct sbus *sbus)
-{
-       switch (dbus_message_get_type(message)) {
-       case DBUS_MESSAGE_TYPE_METHOD_CALL:
-               return incoming_call(sbus, message);
-       case DBUS_MESSAGE_TYPE_METHOD_RETURN:
-               return incoming_resp(sbus, message, 0);
-       case DBUS_MESSAGE_TYPE_ERROR:
-               return incoming_resp(sbus, message, 1);
-       case DBUS_MESSAGE_TYPE_SIGNAL:
-               return incoming_signal(sbus, message);
-       }
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-/*********************** STATIC DBUS WATCH/POLLING INTERFACE **********/
-
-struct swatch {
-       DBusConnection *connection;
-       DBusWatch *watch;
-       void *hndl;
-};
-
-static void on_hangup(struct swatch *s)
-{
-       dbus_watch_handle(s->watch, DBUS_WATCH_HANGUP);
-       while (dbus_connection_dispatch(s->connection) == DBUS_DISPATCH_DATA_REMAINS);
-}
-
-static void on_readable(struct swatch *s)
-{
-       dbus_watch_handle(s->watch, DBUS_WATCH_READABLE);
-       while (dbus_connection_dispatch(s->connection) == DBUS_DISPATCH_DATA_REMAINS);
-}
-
-static void on_writable(struct swatch *s)
-{
-       dbus_watch_handle(s->watch, DBUS_WATCH_WRITABLE);
-       while (dbus_connection_dispatch(s->connection) == DBUS_DISPATCH_DATA_REMAINS);
-}
-
-/*
- * DBUS Callback for removing a 'watch'.
- * See function 'dbus_connection_set_watch_functions'
- */
-static void watchdel(DBusWatch *watch, struct sbus *sbus)
-{
-       struct swatch *s = dbus_watch_get_data(watch);
-       sbus->itf->close(s->hndl);
-       free(s);
-}
-
-/*
- * DBUS Callback for changing a 'watch'.
- * See function 'dbus_connection_set_watch_functions'
- */
-static void watchtoggle(DBusWatch *watch, struct sbus *sbus)
-{
-       struct swatch *s = dbus_watch_get_data(watch);
-       int enabled = (int)dbus_watch_get_enabled(watch);
-       unsigned int flags = dbus_watch_get_flags(watch);
-       if (flags & DBUS_WATCH_READABLE)
-               sbus->itf->on_readable(s->hndl, enabled ? (void*)on_readable : NULL);
-       if (flags & DBUS_WATCH_WRITABLE)
-               sbus->itf->on_writable(s->hndl, enabled ? (void*)on_writable : NULL);
-}
-
-
-/*
- * DBUS Callback for adding a 'watch'.
- * See function 'dbus_connection_set_watch_functions'
- */
-static dbus_bool_t watchadd(DBusWatch *watch, struct sbus *sbus)
-{
-       int fd;
-       struct swatch *s;
-
-       s = malloc(sizeof *s);
-       if (s == NULL)
-               goto error;
-       fd = dbus_watch_get_unix_fd(watch);
-       s->hndl = sbus->itf->open(fd, s, sbus->itfclo);
-       if (s->hndl == NULL)
-               goto error2;
-       s->watch = watch;
-       s->connection = sbus->connection;
-       dbus_watch_set_data(watch, s, NULL);
-       sbus->itf->on_hangup(s->hndl, (void*)on_hangup);
-       watchtoggle(watch, sbus);
-       return TRUE;
- error2:
-       free(s);
- error:
-       return FALSE;
-}
-
-/*
- * Creates a 'sbus' bound the 'path' and it derived names and linked
- * either to the DBUS SYSTEM when 'session' is nul or to the DBUS SESSION
- * if 'session' is not nul.
- *
- * The parameter 'path' is intended to be the path of a DBUS single object.
- * Single means that it exists only one instance of the object on the
- * given bus. That path implies 2 derived DBUS names:
- *   1. the destination name of the program that handles the object
- *   2. the interface name of the object
- * These names are derived by removing the heading slash (/) and
- * by replacing all occurences of slashes by dots.
- * For example, passing path = /a/b/c means that the object /a/b/c is
- * handled by the destination a.b.c and replies to the interface a.b.c
- *
- * Returns the created sbus or NULL in case of error.
- */
-static struct sbus *get_sbus(const struct sbus_itf *itf, void *itfclo, struct sbus *sbus)
-{
-       /* create the sbus object */
-       if (sbus->refcount > 0) {
-               if (itf != sbus->itf)
-                       goto error;
-               goto success;
-       }
-
-       /* connect and init */
-       sbus->connection = dbus_bus_get(sbus == &session_sbus ? DBUS_BUS_SESSION
-                                               : DBUS_BUS_SYSTEM, NULL);
-       if (sbus->connection == NULL)
-               goto error;
-
-       sbus->itf = itf;
-       sbus->itfclo = itfclo;
-       if (!dbus_connection_add_filter(sbus->connection, (void*)incoming, sbus, NULL)
-        || !dbus_connection_set_watch_functions(sbus->connection, (void*)watchadd,
-                                       (void*)watchdel, (void*)watchtoggle, sbus, NULL)) 
-               goto error2;
-
- success:
-       sbus->refcount++;
-       return sbus;
-
- error2:
-       dbus_connection_unref(sbus->connection);
-       sbus->connection = NULL;
- error:
-       return NULL;
-}
-
-/********************* MAIN FUNCTIONS *****************************************/
-
-/*
- * Creates a 'sbus' bound to DBUS system using 'path' and returns it.
- * See 'create_sbus'
- */
-struct sbus *sbus_system(const struct sbus_itf *itf, void *itfclo)
-{
-       return get_sbus(itf, itfclo, &system_sbus);
-}
-
-/*
- * Creates a 'sbus' bound to DBUS session using 'path' and returns it.
- * See 'create_sbus'
- */
-struct sbus *sbus_session(const struct sbus_itf *itf, void *itfclo)
-{
-       return get_sbus(itf, itfclo, &session_sbus);
-}
-
-/*
- * Adds one reference to 'sbus'.
- */
-void sbus_addref(struct sbus *sbus)
-{
-       sbus->refcount++;
-}
-
-/*
- * Removes one reference to 'sbus'. Destroys 'sbus' and it related
- * data if the count of references decrease to zero.
- */
-void sbus_unref(struct sbus *sbus)
-{
-       struct srespw *w;
-       if (!--sbus->refcount) {
-               while (sbus->services != NULL)
-                       sbus_remove_service(sbus, sbus->services);
-               while (sbus->signals != NULL)
-                       sbus_remove_signal(sbus, sbus->signals);
-               if (sbus->connection != NULL) {
-                       dbus_connection_unref(sbus->connection);
-                       sbus->connection = NULL;
-               }
-               while ((w = sbus->waiters)) {
-                       sbus->waiters = w->next;
-                       if (w->onresp)
-                               w->onresp(-1, "cancelled", w->closure);
-                       free(w);
-               }
-       }
-}
-
-/*
- * Sends from 'sbus' the signal of 'member' handling the string 'content'.
- *
- * Returns 0 in case of success or -1 in case of error.
- */
-int sbus_send_signal(struct sbus *sbus, const char *sender, const char *path, const char *iface, const char *member, const char *content)
-{
-       int rc = -1;
-       DBusMessage *message;
-
-       message = dbus_message_new_signal(path, iface, member);
-       if (message == NULL)
-               goto error;
-
-       if (sender != NULL && !dbus_message_set_sender(message, sender))
-               goto error2;
-
-       if (!dbus_message_append_args(message, DBUS_TYPE_STRING, &content,
-                                        DBUS_TYPE_INVALID))
-               goto error2;
-
-       if (dbus_connection_send(sbus->connection, message, NULL))
-               rc = 0;
-
-       dbus_message_unref(message);
-       return rc;
-
- error2:
-       dbus_message_unref(message);
-
- error:
-       errno = ENOMEM;
-       return -1;
-}
-
-/*
- * Asynchronous call to 'method' of 'sbus' passing the string 'query'.
- * On response, the function 'onresp' is called with the returned string
- * value and the closure 'closure'.
- * The function 'onresp' is invoked with 3 parameters:
- *   1. int: 0 if no error or -1 if error.
- *   2. const char *: the returned string (might be NULL if error)
- *   3. void *: the closure 'closure'
- *
- * Returns 0 in case of success or -1 in case of error.
- */
-int sbus_call(
-               struct sbus *sbus,
-               const char *destination,
-               const char *path,
-               const char *iface,
-               const char *method,
-               const char *query,
-               void (*onresp) (int, const char *, void *),
-               void *closure)
-{
-       DBusMessage *msg;
-       struct srespw *resp;
-
-       /* allocates the response structure */
-       resp = malloc(sizeof *resp);
-       if (resp == NULL) {
-               errno = ENOMEM;
-               goto error;
-       }
-
-       /* creates the message */
-       msg = dbus_message_new_method_call(destination, path, iface, method);
-       if (msg == NULL) {
-               errno = ENOMEM;
-               goto error2;
-       }
-
-       /* fill it */
-       if (!dbus_message_append_args
-           (msg, DBUS_TYPE_STRING, &query, DBUS_TYPE_INVALID)) {
-               errno = ENOMEM;
-               goto error3;
-       }
-
-       /* send it */
-       if (!dbus_connection_send(sbus->connection, msg, &resp->serial)) {
-               /* TODO: which error? */
-               goto error3;
-       }
-
-       /* release the message that is not more used */
-       dbus_message_unref(msg);
-
-       /* fulfill the response structure */
-       resp->closure = closure;
-       resp->onresp = onresp;
-
-       /* links the response to list of reponse waiters */
-       resp->next = sbus->waiters;
-       sbus->waiters = resp;
-       return 0;
-
- error3:
-       dbus_message_unref(msg);
- error2:
-       free(resp);
- error:
-       return -1;
-}
-
-/*
- * Synchronous call to 'method' of 'sbus' passing the string 'query'.
- * The returned string response is returned.
- *
- * Returns the string response or NULL in case of error.
- */
-char *sbus_call_sync(
-               struct sbus *sbus,
-               const char *destination,
-               const char *path,
-               const char *iface,
-               const char *method,
-               const char *query)
-{
-       struct respsync synchro;
-       synchro.value = NULL;
-       synchro.replied = sbus_call(sbus, destination, path,
-                                   iface, method, query,
-                                   (void*)sync_of_replies, &synchro);
-       while (!synchro.replied)
-               if (sbus->itf->wait(-1, sbus->itfclo) != 0)
-                       return NULL;
-       return synchro.value;
-}
-
-
-/*
- * Records for 'sbus' the string signal handler 'onsig' with closure 'closure'
- * for the signal of 'member'.
- * The callback handler is called with 2 arguments:
- *   1. char *: the string parameter associated to the signal
- *   2. void *: the closure closure.
- *
- * Returns 0 in case of success or -1 otherwise.
- */
-struct sbus_signal *sbus_add_signal(
-               struct sbus *sbus,
-               const char *sender,
-               const char *path,
-               const char *iface,
-               const char *member,
-               void (*onsignal) (const struct sbusmsg *, const char *, void *),
-               void *closure)
-{
-       char *rule;
-       struct sbus_signal *signal;
-
-       /* allocation */
-       signal = calloc(1, sizeof *signal);
-       if (signal == NULL)
-               goto error;
-       if (sender != NULL) {
-               signal->sender = strdup(sender);
-               if (!signal->sender)
-                       goto error2;
-       }
-       if (path != NULL) {
-               signal->path = strdup(path);
-               if (!signal->path)
-                       goto error2;
-       }
-       if (iface != NULL) {
-               signal->iface = strdup(iface);
-               if (!signal->iface)
-                       goto error2;
-       }
-       if (member != NULL) {
-               signal->member = strdup(member);
-               if (!signal->member)
-                       goto error2;
-       }
-
-       /* record the signal */
-       rule = rule_of_signal(signal);
-       if (rule == NULL)
-               goto error2;
-       dbus_bus_add_match(sbus->connection, rule, NULL);
-       free(rule);
-
-       /* record the signal */
-       signal->onsignal = onsignal;
-       signal->closure = closure;
-       signal->next = sbus->signals;
-       sbus->signals = signal;
-
-       return signal;
-
- error2:
-       free(signal->sender);
-       free(signal->path);
-       free(signal->iface);
-       free(signal->member);
-       free(signal);
- error:
-       errno = ENOMEM;
-       return NULL;
-}
-
-/*
- * Removes the 'signal' handler from 'sbus'
- * Returns 0 in case of success or -1 in case of error.
- */
-int sbus_remove_signal(struct sbus *sbus, struct sbus_signal *signal)
-{
-       char *rule;
-       struct sbus_signal **it;
-
-       it = &sbus->signals;
-       while (*it != NULL) {
-               if (*it == signal)
-                       goto found;
-               it = &(*it)->next;
-       }
-       errno = EINVAL;
-       return -1;
-
-found:
-       rule = rule_of_signal(signal);
-       if (rule != NULL) {
-               dbus_bus_remove_match(sbus->connection, rule, NULL);
-               free(rule);
-       }
-       *it = signal->next;
-       free(signal->sender);
-       free(signal->path);
-       free(signal->iface);
-       free(signal->member);
-       free(signal);
-       return 0;
-}
-
-/*
- * Start to serve: activate services declared for 'sbus'.
- * This function, in fact, declares 'sbus' as the receiver
- * for calls to the destination derived from the path set at
- * 'sbus' creation.
- * It also allows 'sbus' to emit signals of that origin.
- *
- * Returns 0 in case of success or -1 in case of error.
- */
-int sbus_add_name(struct sbus *sbus, const char *name)
-{
-       int status = dbus_bus_request_name(sbus->connection, name,
-                                       DBUS_NAME_FLAG_DO_NOT_QUEUE, NULL);
-       switch (status) {
-       case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
-       case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
-               return 0;
-       case DBUS_REQUEST_NAME_REPLY_EXISTS:
-       case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
-       default:
-               errno = EADDRINUSE;
-               return -1;
-       }
-}
-
-/*
- * Adds to 'sbus' a service handling calls to the 'method' using
- * the callback 'oncall' and the closure value 'closure'.
- *
- * The callback 'oncall' is invoked for handling incoming method
- * calls. It receives 3 parameters:
- *   1. struct sbusmsg *: a handler to data to be used for replying
- *   2. const char *: the received string
- *   3. void *: the closure 'closure' set by this function
- *
- * Returns 0 in case of success or -1 in case of error.
- */
-struct sbus_service *sbus_add_service(
-               struct sbus *sbus,
-               const char *destination,
-               const char *path,
-               const char *iface,
-               const char *member,
-               void (*oncall) (struct sbusmsg *, const char *, void *),
-               void *closure)
-{
-       struct sbus_service *service;
-
-       /* allocation */
-       service = calloc(1, sizeof *service);
-       if (service == NULL)
-               goto error;
-       if (destination != NULL) {
-               service->destination = strdup(destination);
-               if (!service->destination)
-                       goto error2;
-       }
-       if (path != NULL) {
-               service->path = strdup(path);
-               if (!service->path)
-                       goto error2;
-       }
-       if (iface != NULL) {
-               service->iface = strdup(iface);
-               if (!service->iface)
-                       goto error2;
-       }
-       if (member != NULL) {
-               service->member = strdup(member);
-               if (!service->member)
-                       goto error2;
-       }
-
-       /* record the service */
-       service->oncall = oncall;
-       service->closure = closure;
-       service->next = sbus->services;
-       sbus->services = service;
-
-       return service;
-
- error2:
-       free(service->destination);
-       free(service->path);
-       free(service->iface);
-       free(service->member);
-       free(service);
- error:
-       errno = ENOMEM;
-       return NULL;
-}
-
-/*
- * Removes the 'service' handler from 'sbus'
- * Returns 0 in case of success or -1 in case of error.
- */
-int sbus_remove_service(struct sbus *sbus, struct sbus_service *service)
-{
-       struct sbus_service **it;
-
-       it = &sbus->services;
-       while (*it != NULL) {
-               if (*it == service)
-                       goto found;
-               it = &(*it)->next;
-       }
-       errno = EINVAL;
-       return -1;
-
-found:
-       *it = service->next;
-       free(service->destination);
-       free(service->path);
-       free(service->iface);
-       free(service->member);
-       free(service);
-       return 0;
-}
-
-const char *sbus_sender(const struct sbusmsg *smsg)
-{
-       return dbus_message_get_sender(smsg->message);
-}
-
-const char *sbus_destination(const struct sbusmsg *smsg)
-{
-       return dbus_message_get_destination(smsg->message);
-}
-
-const char *sbus_path(const struct sbusmsg *smsg)
-{
-       return dbus_message_get_path(smsg->message);
-}
-
-const char *sbus_interface(const struct sbusmsg *smsg)
-{
-       return dbus_message_get_interface(smsg->message);
-}
-
-const char *sbus_member(const struct sbusmsg *smsg)
-{
-       return dbus_message_get_member(smsg->message);
-}
-
-/*
- * Replies an error of string 'error' to the request handled by 'smsg'.
- * Also destroys the request 'smsg' that must not be used later.
- *
- * Returns 0 in case of success or -1 in case of error.
- */
-int sbus_reply_error(struct sbusmsg *smsg, const char *error)
-{
-       int rc = -1;
-       DBusMessage *message;
-
-       message = dbus_message_new_error(smsg->message, DBUS_ERROR_FAILED,
-                                                               error);
-       if (message == NULL)
-               errno = ENOMEM;
-       else {
-               if (dbus_connection_send(smsg->connection, message, NULL))
-                       rc = 0;
-               dbus_message_unref(message);
-       }
-       free_sbusmsg(smsg);
-       return rc;
-}
-
-/*
- * Replies normally the string 'reply' to the request handled by 'smsg'.
- * Also destroys the request 'smsg' that must not be used later.
- *
- * Returns 0 in case of success or -1 in case of error.
- */
-int sbus_reply(struct sbusmsg *smsg, const char *reply)
-{
-       int rc = -1;
-       DBusMessage *message;
-
-       message = dbus_message_new_method_return(smsg->message);
-       if (message == NULL)
-               return reply_out_of_memory(smsg);
-
-       if (!dbus_message_append_args
-           (message, DBUS_TYPE_STRING, &reply, DBUS_TYPE_INVALID)) {
-               dbus_message_unref(message);
-               return reply_out_of_memory(smsg);
-       }
-
-       if (dbus_connection_send(smsg->connection, message, NULL))
-               rc = 0;
-       dbus_message_unref(message);
-       free_sbusmsg(smsg);
-       return rc;
-}
-
-/****************** FEW LITTLE TESTS *****************************************/
-
-#if defined(SERVER)||defined(CLIENT)
-#include <stdio.h>
-#include <unistd.h>
-#include "utils-upoll.h"
-
-static int mwait(int timeout, void *closure)
-{
-       upoll_wait(timeout);
-       return 0;
-}
-
-static const struct sbus_itf uitf = {
-       .wait = (void*)mwait,
-       .open = (void*)upoll_open,
-       .on_readable = (void*)upoll_on_readable,
-       .on_writable = (void*)upoll_on_writable,
-       .on_hangup = (void*)upoll_on_hangup,
-       .close = (void*)upoll_close
-};
-
-static const char name[] = "org.toto";
-static const char path[] = "/org/toto";
-static const char iface[] = "org.toto";
-static struct sbus *sbus;
-
-#ifdef SERVER
-void ping(struct sbusmsg *smsg, const char *request, void *unused)
-{
-       printf("ping(%s) -> %s\n", request, request);
-       sbus_reply(smsg, request);
-}
-
-void incr(struct sbusmsg *smsg, const char *request, void *unused)
-{
-       static int counter = 0;
-       char res[150];
-       sprintf(res, "%d", ++counter);
-       printf("incr(%s) -> %s\n", request, res);
-       sbus_reply(smsg, res);
-       sbus_send_signal(sbus, name, path, iface, "incremented", res);
-}
-
-int main()
-{
-       int s1, s2, s3;
-       sbus = sbus_session(&uitf, NULL);
-       s3 = !sbus_add_name(sbus, name);
-       s1 = !!sbus_add_service(sbus, name, path, iface, "ping", ping, NULL);
-       s2 = !!sbus_add_service(sbus, name, path, iface, "incr", incr, NULL);
-       printf("started %d %d %d\n", s1, s2, s3);
-       while (1) upoll_wait(-1);
-}
-#endif
-
-#ifdef CLIENT
-void onresp(int status, const char *response, void *closure)
-{
-       printf("resp: %d, %s, %s\n", status, (const char *)closure, response);
-}
-
-void signaled(const struct sbusmsg *req, const char *data, void *closure)
-{
-       printf("signaled with {%s}/%s\n", data, (const char*)closure);
-}
-
-int main()
-{
-       int i = 10;
-       sbus = sbus_session(&uitf, NULL);
-       sbus_add_signal(sbus, name, path, iface, "incremented", signaled, "signal");
-       while (i--) {
-               sbus_call(sbus, name, path, iface, "ping", "{'toto':[1,2,3,4,true,'toto']}", onresp, "ping");
-               sbus_call(sbus, name, path, iface, "incr", "{'doit':'for-me'}", onresp, "incr");
-               upoll_wait(1);
-       }
-       printf("[[[%s]]]\n", sbus_call_sync(sbus, name, path, iface, "ping", "formidable!"));
-       while (1) upoll_wait(-1);
-}
-#endif
-#endif
diff --git a/plugins/afm-main-plugin/utils-sbus.h b/plugins/afm-main-plugin/utils-sbus.h
deleted file mode 100644 (file)
index 8a9dfc5..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- Copyright 2015 IoT.bzh
-
- author: José Bollo <jose.bollo@iot.bzh>
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-#pragma once
-
-struct sbus;
-struct sbusmsg;
-struct sbus_signal;
-struct sbus_service;
-
-struct sbus_itf
-{
-       int (*wait)(int timeout, void *itfclo);
-       void *(*open)(int fd, void *closure, void *itfclo);
-       int (*on_readable)(void *hndl, void (*callback)(void *closure));
-       int (*on_writable)(void *hndl, void (*callback)(void *closure));
-       void (*on_hangup)(void *hndl, void (*callback)(void *closure));
-       void (*close)(void *hndl);
-};
-
-extern struct sbus *sbus_session(const struct sbus_itf *itf, void *itfclo);
-extern struct sbus *sbus_system(const struct sbus_itf *itf, void *itfclo);
-
-extern void sbus_addref(struct sbus *sbus);
-extern void sbus_unref(struct sbus *sbus);
-
-extern int sbus_send_signal(struct sbus *sbus, const char *sender, const char *path, const char *iface, const char *name, const char *content);
-
-extern int sbus_call(
-               struct sbus *sbus,
-               const char *destination,
-               const char *path,
-               const char *iface,
-               const char *method,
-               const char *query,
-               void (*onresp) (int, const char *, void *),
-               void *closure);
-
-extern char *sbus_call_sync(
-               struct sbus *sbus,
-               const char *destination,
-               const char *path,
-               const char *iface,
-               const char *method,
-               const char *query);
-
-extern struct sbus_signal *sbus_add_signal(
-               struct sbus *sbus,
-               const char *sender,
-               const char *path,
-               const char *iface,
-               const char *name,
-               void (*onsignal) (const struct sbusmsg *, const char *, void *),
-               void *closure);
-
-extern int sbus_remove_signal(struct sbus *sbus, struct sbus_signal *signal);
-
-extern int sbus_add_name(struct sbus *sbus, const char *name);
-
-extern struct sbus_service *sbus_add_service(
-               struct sbus *sbus,
-               const char *destination,
-               const char *path,
-               const char *iface,
-               const char *member,
-               void (*oncall) (struct sbusmsg *, const char *, void *),
-               void *closure);
-
-extern int sbus_remove_service(struct sbus *sbus, struct sbus_service *service);
-
-extern const char *sbus_sender(const struct sbusmsg *smsg);
-
-extern const char *sbus_destination(const struct sbusmsg *smsg);
-
-extern const char *sbus_path(const struct sbusmsg *smsg);
-
-extern const char *sbus_interface(const struct sbusmsg *smsg);
-
-extern const char *sbus_member(const struct sbusmsg *smsg);
-
-extern int sbus_reply_error(struct sbusmsg *smsg, const char *error);
-extern int sbus_reply(struct sbusmsg *smsg, const char *reply);
-