aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/CMakeLists.txt2
-rw-r--r--plugins/afm-main-plugin/CMakeLists.txt2
-rw-r--r--plugins/afm-main-plugin/afm-main-plugin.c27
-rw-r--r--plugins/afm-main-plugin/utils-jbus.c243
-rw-r--r--plugins/afm-main-plugin/utils-jbus.h18
-rw-r--r--plugins/afm-main-plugin/utils-sbus.c1037
-rw-r--r--plugins/afm-main-plugin/utils-sbus.h98
7 files changed, 182 insertions, 1245 deletions
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index 5d8b26ac..c60e3527 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -1,4 +1,4 @@
-#ADD_SUBDIRECTORY(afm-main-plugin)
+ADD_SUBDIRECTORY(afm-main-plugin)
ADD_SUBDIRECTORY(session)
ADD_SUBDIRECTORY(samples)
#ADD_SUBDIRECTORY(audio)
diff --git a/plugins/afm-main-plugin/CMakeLists.txt b/plugins/afm-main-plugin/CMakeLists.txt
index 8aaa1344..5ed1d4b2 100644
--- a/plugins/afm-main-plugin/CMakeLists.txt
+++ b/plugins/afm-main-plugin/CMakeLists.txt
@@ -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})
diff --git a/plugins/afm-main-plugin/afm-main-plugin.c b/plugins/afm-main-plugin/afm-main-plugin.c
index 21e27e82..c6408a51 100644
--- a/plugins/afm-main-plugin/afm-main-plugin.c
+++ b/plugins/afm-main-plugin/afm-main-plugin.c
@@ -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);
diff --git a/plugins/afm-main-plugin/utils-jbus.c b/plugins/afm-main-plugin/utils-jbus.c
index 4872987f..d3f23021 100644
--- a/plugins/afm-main-plugin/utils-jbus.c
+++ b/plugins/afm-main-plugin/utils-jbus.c
@@ -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--) {
diff --git a/plugins/afm-main-plugin/utils-jbus.h b/plugins/afm-main-plugin/utils-jbus.h
index d85b8aff..ff4c8fab 100644
--- a/plugins/afm-main-plugin/utils-jbus.h
+++ b/plugins/afm-main-plugin/utils-jbus.h
@@ -18,10 +18,12 @@
#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
index a5c63c65..00000000
--- a/plugins/afm-main-plugin/utils-sbus.c
+++ /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
index 8a9dfc59..00000000
--- a/plugins/afm-main-plugin/utils-sbus.h
+++ /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);
-