diff options
author | José Bollo <jose.bollo@iot.bzh> | 2016-05-03 17:05:36 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2016-05-04 11:55:38 +0200 |
commit | 3d705a894b13759904b0601f8cdef1f2c226d8cc (patch) | |
tree | 0db4d06afe4db4877c4268209ef5857e162cc2f4 /plugins | |
parent | 5dd6480727cc1ecb12483fc4d971d73176505748 (diff) |
Removing legacy dbus-1 library
Change-Id: I1c1d17cd702e12ed961ed90d1489bc12b074bd55
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/CMakeLists.txt | 2 | ||||
-rw-r--r-- | plugins/afm-main-plugin/CMakeLists.txt | 2 | ||||
-rw-r--r-- | plugins/afm-main-plugin/afm-main-plugin.c | 27 | ||||
-rw-r--r-- | plugins/afm-main-plugin/utils-jbus.c | 243 | ||||
-rw-r--r-- | plugins/afm-main-plugin/utils-jbus.h | 18 | ||||
-rw-r--r-- | plugins/afm-main-plugin/utils-sbus.c | 1037 | ||||
-rw-r--r-- | plugins/afm-main-plugin/utils-sbus.h | 98 |
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); - |