From: José Bollo Date: Mon, 21 Mar 2016 16:19:20 +0000 (+0100) Subject: utils-jbus: adding comments X-Git-Tag: 2.0.2~32 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?p=src%2Fapp-framework-main.git;a=commitdiff_plain;h=26aaf29a3694750834b9eefb6b6e4553bc5ea83f utils-jbus: adding comments Also add a line in TODO list, minor refactoring, insert a remider about NDEBUG. Change-Id: I3d80dad7b6903df70c0fca2ef7256c158ecb3355 Signed-off-by: José Bollo --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8971edb..4676c66 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,6 +63,7 @@ add_compile_options(-Wno-pointer-sign) # for XmlChar handling add_compile_options(-ffunction-sections -fdata-sections) add_compile_options(-Wl,--gc-sections) add_compile_options(-fPIC) +#add_definitions(-DNDEBUG) set(CMAKE_C_FLAGS_PROFILING "-g -O0 -pg -Wp,-U_FORTIFY_SOURCE") set(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") diff --git a/src/TODO b/src/TODO index f525383..17d1ffc 100644 --- a/src/TODO +++ b/src/TODO @@ -23,3 +23,8 @@ List of things to do for the code - handle permission list at install - allows to check the requested permissions before to install it + +- improve error reporting through dbus in utils-jbus + +- groups the dbus connections to reduce the count of pollfd and watch calback + (in utils-jbus) diff --git a/src/utils-jbus.c b/src/utils-jbus.c index 9d6c1d5..3bea2c2 100644 --- a/src/utils-jbus.c +++ b/src/utils-jbus.c @@ -29,68 +29,99 @@ #include "utils-jbus.h" -#define MAX_JSON_DEPTH 5 +/* + * max depth of json messages + */ +#define MAX_JSON_DEPTH 10 -struct jreq; -struct jservice; -struct jbus; +/* + * errors messages generated by jbus + */ +#if defined(NO_JSON_ERROR_STRING) +static const char invalid_request_string[] = "invalid request"; +static const char out_of_memory_string[] = "out of memory"; +#else +static const char invalid_request_string[] = "\"invalid request\""; +static const char out_of_memory_string[] = "\"out of memory\""; +#endif -/* structure for handled requests */ +/* + * structure for handled requests + */ struct jreq { - DBusConnection *connection; - DBusMessage *request; + DBusConnection *connection; /* connection of the request */ + DBusMessage *request; /* message of the request */ }; -/* structure for recorded services */ +/* + * structure for services + */ struct jservice { - struct jservice *next; - char *method; - void (*oncall_s)(struct jreq *, const char *, void *); - void (*oncall_j)(struct jreq *, struct json_object *, void *); - void *data; + struct jservice *next; /* link to the next service */ + char *method; /* method name for the service */ + void (*oncall_s) (struct jreq *, const char *, void *); + /* string callback */ + void (*oncall_j) (struct jreq *, struct json_object *, void *); + /* json callback */ + void *data; /* closure data for the callbacks */ }; -/* structure for signal handlers */ +/* + * structure for signals + */ struct jsignal { - struct jsignal *next; - char *name; - void (*onsignal_s)(const char *, void *); - void (*onsignal_j)(struct json_object *, void *); - void *data; + struct jsignal *next; /* link to the next signal */ + char *name; /* name of the expected signal */ + void (*onsignal_s) (const char *, void *); + /* string callback */ + void (*onsignal_j) (struct json_object *, void *); + /* json callback */ + void *data; /* closure data for the callbacks */ }; -/* structure for recording asynchronous requests */ +/* + * structure for asynchronous requests (resp-onse w-aiter) + */ struct jrespw { - struct jrespw *next; - dbus_uint32_t serial; - void *data; - void (*onresp_s)(int, const char*, void *); - void (*onresp_j)(int, struct json_object*, void *); + struct jrespw *next; /* next asynchronous */ + dbus_uint32_t serial; /* serial dbus number */ + void *data; /* closure data for the callbacks */ + void (*onresp_s) (int, const char *, void *); + /* string callback */ + void (*onresp_j) (int, struct json_object *, void *); + /* json callback */ }; -/* structure for synchronous requests */ +/* + * structure for synchronous requests + */ struct respsync { - int replied; - char *value; + int replied; /* boolean flag indicating reply */ + char *value; /* copy of the returned value */ }; -/* structure for handling either client or server jbus on dbus */ +/* + * structure for handling either client or server jbus on dbus + */ struct jbus { - int refcount; - struct json_tokener *tokener; - struct jservice *services; - DBusConnection *connection; - struct jsignal *signals; - struct jrespw *waiters; - char *path; - char *name; - int watchnr; - int watchfd; - short watchflags; + int refcount; /* referenced how many time */ + DBusConnection *connection; /* connection to DBU */ + struct json_tokener *tokener; /* string to json tokenizer */ + struct jservice *services; /* first service */ + struct jsignal *signals; /* first signal */ + struct jrespw *waiters; /* first response waiter */ + char *path; /* dbus path */ + char *name; /* dbus name */ + int watchnr; /* counter of watching need */ + int watchfd; /* file to watch */ + short watchflags; /* watched flags */ }; /*********************** STATIC COMMON METHODS *****************/ +/* + * Frees the ressources attached to a request + */ static inline void free_jreq(struct jreq *jreq) { dbus_message_unref(jreq->request); @@ -98,39 +129,50 @@ static inline void free_jreq(struct jreq *jreq) free(jreq); } +/* + * 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 jreq *jreq) { - static const char out_of_memory[] = "out of memory"; - jbus_reply_error_s(jreq, out_of_memory); + jbus_reply_error_s(jreq, out_of_memory_string); errno = ENOMEM; return -1; } -static inline int reply_invalid_request(struct jreq *jreq) -{ - static const char invalid_request[] = "invalid request"; - jbus_reply_error_s(jreq, invalid_request); - return DBUS_HANDLER_RESULT_HANDLED; -} - -static int matchitf(struct jbus *jbus, DBusMessage *message) +/* + * Checks if the incoming 'message' matches the interface + * linked to 'jbus'. + * + * Returns 1 if it matches or 0 wether it does not matches. + */ +static int matchitf(struct jbus *jbus, DBusMessage * message) { const char *itf = dbus_message_get_interface(message); return itf != NULL && !strcmp(itf, jbus->name); } +/* + * Adds to 'jbus' a service of name 'method'. The service is + * performed by one of the callback 'oncall_s' (for string) or + * 'oncall_j' (for json) that will receive the request and the + * closure parameter 'data'. + * + * returns 0 in case of success or -1 in case of error (ENOMEM). + */ static int add_service( struct jbus *jbus, const char *method, - void (*oncall_s)(struct jreq*, const char*, void*), - void (*oncall_j)(struct jreq*, struct json_object*, void*), - void *data -) + void (*oncall_s) (struct jreq *, const char *, void *), + void (*oncall_j) (struct jreq *, struct json_object *, void *), + void *data) { struct jservice *srv; /* allocation */ - srv = malloc(sizeof * srv); + srv = malloc(sizeof *srv); if (srv == NULL) { errno = ENOMEM; goto error; @@ -150,37 +192,44 @@ static int add_service( return 0; -error2: + error2: free(srv); -error: + error: return -1; } +/* + * Adds to 'jbus' a handler for the signal of 'name' emmited by + * the sender and the interface that 'jbus' is linked to. + * The signal is handled by one of the callback 'onsignal_s' + * (for string) or 'onsignal_j' (for json) that will receive + * parameters associated with the signal and the closure + * parameter 'data'. + * + * returns 0 in case of success or -1 in case of error (ENOMEM). + */ static int add_signal( - struct jbus *jbus, - const char *name, - void (*onsignal_s)(const char*, void*), - void (*onsignal_j)(struct json_object*, void*), - void *data -) + struct jbus *jbus, + const char *name, + void (*onsignal_s) (const char *, void *), + void (*onsignal_j) (struct json_object *, void *), + void *data) { char *rule; struct jsignal *sig; /* record the signal */ if (jbus->signals == NULL) { -#if 0 - if (0 >= asprintf(&rule, "type='signal',interface='%s',path='%s'", jbus->name, jbus->path)) -#else - if (0 >= asprintf(&rule, "type='signal',sender='%s',interface='%s',path='%s'", jbus->name, jbus->name, jbus->path)) -#endif + if (0 >= asprintf(&rule, + "type='signal',sender='%s',interface='%s',path='%s'", + jbus->name, jbus->name, jbus->path)) return -1; dbus_bus_add_match(jbus->connection, rule, NULL); free(rule); } /* allocation */ - sig = malloc(sizeof * sig); + sig = malloc(sizeof *sig); if (sig == NULL) goto error; sig->name = strdup(name); @@ -196,62 +245,87 @@ static int add_signal( return 0; -error2: + error2: free(sig); -error: + error: errno = ENOMEM; return -1; } +/* + * Creates a message for 'method' with one string parameter being 'query' + * and sends it to the destination, object and interface linked to 'jbus'. + * + * Adds to 'jbus' the response handler defined by the callbacks 'onresp_s' + * (for string) and 'onresp_j' (for json) and the closure parameter 'data'. + * + * Returns 0 in case of success or -1 in case of error. + */ static int call( - struct jbus *jbus, - const char *method, - const char *query, - void (*onresp_s)(int status, const char *response, void *data), - void (*onresp_j)(int status, struct json_object *response, void *data), - void *data -) + struct jbus *jbus, + const char *method, + const char *query, + void (*onresp_s) (int, const char *, void *), + void (*onresp_j) (int, struct json_object *, void *), + void *data) { DBusMessage *msg; struct jrespw *resp; - resp = malloc(sizeof * resp); + /* allocates the response structure */ + resp = malloc(sizeof *resp); if (resp == NULL) { errno = ENOMEM; goto error; } - msg = dbus_message_new_method_call(jbus->name, jbus->path, jbus->name, method); + /* creates the message */ + msg = dbus_message_new_method_call(jbus->name, jbus->path, jbus->name, + method); if (msg == NULL) { errno = ENOMEM; goto error2; } - if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &query, DBUS_TYPE_INVALID)) { + /* 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(jbus->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->data = data; resp->onresp_s = onresp_s; resp->onresp_j = onresp_j; + + /* links the response to list of reponse waiters */ resp->next = jbus->waiters; jbus->waiters = resp; return 0; -error3: + error3: dbus_message_unref(msg); -error2: + error2: free(resp); -error: + error: return -1; } +/* + * 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, void *data) { struct respsync *s = data; @@ -259,7 +333,15 @@ static void sync_of_replies(int status, const char *value, void *data) s->replied = 1; } -static int parse(struct jbus *jbus, const char *msg, struct json_object **obj) +/* + * Parses the json-string 'msg' to create a json object stored + * in 'obj'. It uses the tokener of 'jbus'. This is a small + * improvement to avoid recreation of tokeners. + * + * Returns 1 in case of success and put the result in *'obj'. + * Returns 0 in case of error and put NULL in *'obj'. + */ +static int jparse(struct jbus *jbus, const char *msg, struct json_object **obj) { json_tokener_reset(jbus->tokener); *obj = json_tokener_parse_ex(jbus->tokener, msg, -1); @@ -270,7 +352,19 @@ static int parse(struct jbus *jbus, const char *msg, struct json_object **obj) return 0; } -static DBusHandlerResult incoming_resp(DBusConnection *connection, DBusMessage *message, struct jbus *jbus, int iserror) +/*********************** STATIC DBUS MESSAGE HANDLING *****************/ + +/* + * Handles incomming responses 'message' on 'jbus'. 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 jbus *jbus, + DBusMessage * message, + int iserror) { int status; const char *str; @@ -288,7 +382,8 @@ static DBusHandlerResult incoming_resp(DBusConnection *connection, DBusMessage * *prv = jrw->next; /* retrieve the string value */ - if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) + if (dbus_message_get_args + (message, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) status = 0; else { status = -1; @@ -300,7 +395,7 @@ static DBusHandlerResult incoming_resp(DBusConnection *connection, DBusMessage * if (jrw->onresp_s) jrw->onresp_s(iserror ? -1 : status, str, jrw->data); else { - status = parse(jbus, str, &reply) - 1; + status = jparse(jbus, str, &reply) - 1; jrw->onresp_j(iserror ? -1 : status, reply, jrw->data); json_object_put(reply); } @@ -309,7 +404,15 @@ static DBusHandlerResult incoming_resp(DBusConnection *connection, DBusMessage * return DBUS_HANDLER_RESULT_HANDLED; } -static DBusHandlerResult incoming_call(DBusConnection *connection, DBusMessage *message, struct jbus *jbus) +/* + * Handles incomming on 'jbus' 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 jbus *jbus, + DBusMessage * message) { struct jservice *srv; struct jreq *jreq; @@ -324,63 +427,79 @@ static DBusHandlerResult incoming_call(DBusConnection *connection, DBusMessage * if (method == NULL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; srv = jbus->services; - while(srv != NULL && strcmp(method, srv->method)) + while (srv != NULL && strcmp(method, srv->method)) srv = srv->next; if (srv == NULL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - /* handle the message */ - jreq = malloc(sizeof * jreq); + /* creates and init the jreq structure */ + jreq = malloc(sizeof *jreq); if (jreq == NULL) return DBUS_HANDLER_RESULT_NEED_MEMORY; jreq->request = dbus_message_ref(message); jreq->connection = dbus_connection_ref(jbus->connection); - - /* retrieve the string value */ - if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) - return reply_invalid_request(jreq); + + /* retrieve the string parameter of the message */ + if (!dbus_message_get_args + (message, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) + goto invalid_request; + + /* send the message to the callback */ if (srv->oncall_s) { /* handling strings only */ srv->oncall_s(jreq, str, srv->data); - } - else { + } else { /* handling json only */ - if (!parse(jbus, str, &query)) - return reply_invalid_request(jreq); + if (!jparse(jbus, str, &query)) + goto invalid_request; srv->oncall_j(jreq, query, srv->data); json_object_put(query); } return DBUS_HANDLER_RESULT_HANDLED; + +invalid_request: + jbus_reply_error_s(jreq, invalid_request_string); + return DBUS_HANDLER_RESULT_HANDLED; } -static DBusHandlerResult incoming_signal(DBusConnection *connection, DBusMessage *message, struct jbus *jbus) +/* + * Handles incomming on 'jbus' 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 jbus *jbus, + DBusMessage * message) { struct jsignal *sig; const char *str; const char *name; struct json_object *obj; - /* search for the service */ + /* search for the signal name */ if (!matchitf(jbus, message)) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; name = dbus_message_get_member(message); if (name == NULL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; sig = jbus->signals; - while(sig != NULL && strcmp(name, sig->name)) + while (sig != NULL && strcmp(name, sig->name)) sig = sig->next; if (sig == NULL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* retrieve the string value */ - if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) { + if (dbus_message_get_args + (message, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) { if (sig->onsignal_s) { /* handling strings only */ sig->onsignal_s(str, sig->data); - } - else { - /* handling json only */ - if (parse(jbus, str, &obj)) { + } else { + /* handling json only (if valid) */ + if (jparse(jbus, str, &obj)) { sig->onsignal_j(obj, sig->data); json_object_put(obj); } @@ -389,22 +508,36 @@ static DBusHandlerResult incoming_signal(DBusConnection *connection, DBusMessage return DBUS_HANDLER_RESULT_HANDLED; } -static DBusHandlerResult incoming(DBusConnection *connection, DBusMessage *message, void *data) +/* + * 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, + void *data) { - switch(dbus_message_get_type(message)) { + struct jbus *jbus = data; + switch (dbus_message_get_type(message)) { case DBUS_MESSAGE_TYPE_METHOD_CALL: - return incoming_call(connection, message, (struct jbus*)data); + return incoming_call(jbus, message); case DBUS_MESSAGE_TYPE_METHOD_RETURN: - return incoming_resp(connection, message, (struct jbus*)data, 0); + return incoming_resp(jbus, message, 0); case DBUS_MESSAGE_TYPE_ERROR: - return incoming_resp(connection, message, (struct jbus*)data, 1); + return incoming_resp(jbus, message, 1); case DBUS_MESSAGE_TYPE_SIGNAL: - return incoming_signal(connection, message, (struct jbus*)data); + return incoming_signal(jbus, message); } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static void watchset(DBusWatch *watch, struct jbus *jbus) +/*********************** STATIC DBUS WATCH/POLLING INTERFACE **********/ + +/* + * Set the watched flags of 'jbus' following what DBUS expects by 'watch' + */ +static void watchset(DBusWatch * watch, struct jbus *jbus) { unsigned int flags; short wf; @@ -416,8 +549,7 @@ static void watchset(DBusWatch *watch, struct jbus *jbus) wf |= POLLIN; if (flags & DBUS_WATCH_WRITABLE) wf |= POLLOUT; - } - else { + } else { if (flags & DBUS_WATCH_READABLE) wf &= ~POLLIN; if (flags & DBUS_WATCH_WRITABLE) @@ -426,7 +558,11 @@ static void watchset(DBusWatch *watch, struct jbus *jbus) jbus->watchflags = wf; } -static void watchdel(DBusWatch *watch, void *data) +/* + * DBUS Callback for removing a 'watch'. + * See function 'dbus_connection_set_watch_functions' + */ +static void watchdel(DBusWatch * watch, void *data) { struct jbus *jbus = data; @@ -435,7 +571,11 @@ static void watchdel(DBusWatch *watch, void *data) jbus->watchnr--; } -static void watchtoggle(DBusWatch *watch, void *data) +/* + * DBUS Callback for changing a 'watch'. + * See function 'dbus_connection_set_watch_functions' + */ +static void watchtoggle(DBusWatch * watch, void *data) { struct jbus *jbus = data; @@ -444,61 +584,96 @@ static void watchtoggle(DBusWatch *watch, void *data) watchset(watch, jbus); } -static dbus_bool_t watchadd(DBusWatch *watch, void *data) +/* + * DBUS Callback for adding a 'watch'. + * See function 'dbus_connection_set_watch_functions' + */ +static dbus_bool_t watchadd(DBusWatch * watch, void *data) { struct jbus *jbus = data; if (jbus->watchnr == 0) { jbus->watchfd = dbus_watch_get_unix_fd(watch); jbus->watchflags = 0; - } - else if (jbus->watchfd != dbus_watch_get_unix_fd(watch)) + } else if (jbus->watchfd != dbus_watch_get_unix_fd(watch)) return FALSE; jbus->watchnr++; watchset(watch, jbus); return TRUE; } -/************************** MAIN FUNCTIONS *****************************************/ +/********************* MAIN FUNCTIONS *****************************************/ +/* + * Creates a 'jbus' bound to DBUS system using 'path' and returns it. + * See 'create_jbus' + */ struct jbus *create_jbus_system(const char *path) { return create_jbus(path, 0); } +/* + * Creates a 'jbus' bound to DBUS session using 'path' and returns it. + * See 'create_jbus' + */ struct jbus *create_jbus_session(const char *path) { return create_jbus(path, 1); } +/* + * Creates a 'jbus' 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 jbus or NULL in case of error. + */ struct jbus *create_jbus(const char *path, int session) { struct jbus *jbus; char *name; - /* create the context and connect */ - jbus = calloc(1, sizeof * jbus); + /* create the jbus object */ + jbus = calloc(1, sizeof *jbus); if (jbus == NULL) { errno = ENOMEM; goto error; } jbus->refcount = 1; + + /* create the tokener */ jbus->tokener = json_tokener_new_ex(MAX_JSON_DEPTH); if (jbus->tokener == NULL) { errno = ENOMEM; goto error2; } + + /* records the path */ jbus->path = strdup(path); if (jbus->path == NULL) { errno = ENOMEM; goto error2; } - while(*path == '/') path++; + + /* makes the name from the path */ + while (*path == '/') + path++; jbus->name = name = strdup(path); if (name == NULL) { errno = ENOMEM; goto error2; } - while(*name) { + while (*name) { if (*name == '/') *name = '.'; name++; @@ -511,33 +686,43 @@ struct jbus *create_jbus(const char *path, int session) goto error2; } - /* connect */ - jbus->connection = dbus_bus_get(session ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, NULL); + /* connect and init */ + jbus->connection = dbus_bus_get(session ? DBUS_BUS_SESSION + : DBUS_BUS_SYSTEM, NULL); if (jbus->connection == NULL - || !dbus_connection_add_filter(jbus->connection, incoming, jbus, NULL) - || !dbus_connection_set_watch_functions(jbus->connection, watchadd, watchdel, watchtoggle, jbus, NULL)) + || !dbus_connection_add_filter(jbus->connection, incoming, jbus, + NULL) + || !dbus_connection_set_watch_functions(jbus->connection, watchadd, + watchdel, watchtoggle, jbus, NULL)) goto error2; return jbus; -error2: + error2: jbus_unref(jbus); -error: + error: return NULL; } +/* + * Adds one reference to 'jbus'. + */ void jbus_addref(struct jbus *jbus) { jbus->refcount++; } +/* + * Removes one reference to 'jbus'. Destroys 'jbus' and it related + * data if the count of references decrease to zero. + */ void jbus_unref(struct jbus *jbus) { struct jservice *srv; if (!--jbus->refcount) { if (jbus->connection != NULL) dbus_connection_unref(jbus->connection); - while((srv = jbus->services) != NULL) { + while ((srv = jbus->services) != NULL) { jbus->services = srv->next; free(srv->method); free(srv); @@ -550,12 +735,19 @@ void jbus_unref(struct jbus *jbus) } } +/* + * Replies an error of string 'error' to the request handled by 'jreq'. + * Also destroys the request 'jreq' that must not be used later. + * + * Returns 0 in case of success or -1 in case of error. + */ int jbus_reply_error_s(struct jreq *jreq, const char *error) { int rc = -1; DBusMessage *message; - message = dbus_message_new_error(jreq->request, DBUS_ERROR_FAILED, error); + message = dbus_message_new_error(jreq->request, DBUS_ERROR_FAILED, + error); if (message == NULL) errno = ENOMEM; else { @@ -567,12 +759,24 @@ int jbus_reply_error_s(struct jreq *jreq, const char *error) return rc; } +/* + * Replies an error of json 'reply' to the request handled by 'jreq'. + * Also destroys the request 'jreq' that must not be used later. + * + * Returns 0 in case of success or -1 in case of error. + */ int jbus_reply_error_j(struct jreq *jreq, struct json_object *reply) { const char *str = json_object_to_json_string(reply); return str ? jbus_reply_error_s(jreq, str) : reply_out_of_memory(jreq); } +/* + * Replies normally the string 'reply' to the request handled by 'jreq'. + * Also destroys the request 'jreq' that must not be used later. + * + * Returns 0 in case of success or -1 in case of error. + */ int jbus_reply_s(struct jreq *jreq, const char *reply) { int rc = -1; @@ -582,7 +786,8 @@ int jbus_reply_s(struct jreq *jreq, const char *reply) if (message == NULL) return reply_out_of_memory(jreq); - if (!dbus_message_append_args(message, DBUS_TYPE_STRING, &reply, DBUS_TYPE_INVALID)) { + if (!dbus_message_append_args + (message, DBUS_TYPE_STRING, &reply, DBUS_TYPE_INVALID)) { dbus_message_unref(message); return reply_out_of_memory(jreq); } @@ -594,12 +799,23 @@ int jbus_reply_s(struct jreq *jreq, const char *reply) return rc; } +/* + * Replies normally the json 'reply' to the request handled by 'jreq'. + * Also destroys the request 'jreq' that must not be used later. + * + * Returns 0 in case of success or -1 in case of error. + */ int jbus_reply_j(struct jreq *jreq, struct json_object *reply) { const char *str = json_object_to_json_string(reply); return str ? jbus_reply_s(jreq, str) : reply_out_of_memory(jreq); } +/* + * Sends from 'jbus' the signal of 'name' handling the string 'content'. + * + * Returns 0 in case of success or -1 in case of error. + */ int jbus_send_signal_s(struct jbus *jbus, const char *name, const char *content) { int rc = -1; @@ -610,7 +826,8 @@ int jbus_send_signal_s(struct jbus *jbus, const char *name, const char *content) goto error; if (!dbus_message_set_sender(message, jbus->name) - || !dbus_message_append_args(message, DBUS_TYPE_STRING, &content, DBUS_TYPE_INVALID)) { + || !dbus_message_append_args(message, DBUS_TYPE_STRING, &content, + DBUS_TYPE_INVALID)) { dbus_message_unref(message); goto error; } @@ -620,12 +837,18 @@ int jbus_send_signal_s(struct jbus *jbus, const char *name, const char *content) dbus_message_unref(message); return rc; -error: + error: errno = ENOMEM; return -1; } -int jbus_send_signal_j(struct jbus *jbus, const char *name, struct json_object *content) +/* + * Sends from 'jbus' the signal of 'name' handling the json 'content'. + * + * Returns 0 in case of success or -1 in case of error. + */ +int jbus_send_signal_j(struct jbus *jbus, const char *name, + struct json_object *content) { const char *str = json_object_to_json_string(content); if (str == NULL) { @@ -635,19 +858,61 @@ int jbus_send_signal_j(struct jbus *jbus, const char *name, struct json_object * return jbus_send_signal_s(jbus, name, str); } -int jbus_add_service_s(struct jbus *jbus, const char *method, void (*oncall)(struct jreq *, const char *, void *), void *data) +/* + * Adds to 'jbus' a service handling calls to the 'method' using + * the "string" callback 'oncall' and the closure value 'data'. + * + * The callback 'oncall' is invoked for handling incoming method + * calls. It receives 3 parameters: + * 1. struct jreq *: a handler to data to be used for replying + * 2. const char *: the received string + * 3. void *: the closure 'data' set by this function + * + * Returns 0 in case of success or -1 in case of error. + */ +int jbus_add_service_s( + struct jbus *jbus, + const char *method, + void (*oncall) (struct jreq *, const char *, void *), + void *data) { return add_service(jbus, method, oncall, NULL, data); } -int jbus_add_service_j(struct jbus *jbus, const char *method, void (*oncall)(struct jreq *, struct json_object *, void *), void *data) +/* + * Adds to 'jbus' a service handling calls to the 'method' using + * the "json" callback 'oncall' and the closure value 'data'. + * + * The callback 'oncall' is invoked for handling incoming method + * calls. It receives 3 parameters: + * 1. struct jreq *: 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 + * + * Returns 0 in case of success or -1 in case of error. + */ +int jbus_add_service_j( + struct jbus *jbus, + const char *method, + void (*oncall) (struct jreq *, struct json_object *, void *), + void *data) { return add_service(jbus, method, NULL, oncall, data); } +/* + * Start to serve: activate services declared for 'jbus'. + * This function, in fact, declares 'jbus' as the receiver + * for calls to the destination derived from the path set at + * 'jbus' creation. + * It also allows 'jbus' to emit signals of that origin. + * + * Returns 0 in case of success or -1 in case of error. + */ int jbus_start_serving(struct jbus *jbus) { - int status = dbus_bus_request_name(jbus->connection, jbus->name, DBUS_NAME_FLAG_DO_NOT_QUEUE, NULL); + int status = dbus_bus_request_name(jbus->connection, jbus->name, + DBUS_NAME_FLAG_DO_NOT_QUEUE, NULL); switch (status) { case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER: @@ -660,11 +925,17 @@ int jbus_start_serving(struct jbus *jbus) } } +/* + * Fills the at least 'njbuses' structures of array 'fds' with data needed + * to poll the 'njbuses' buses pointed by 'jbuses'. + * + * Returns the count of 'fds' structures filled. + */ int jbus_fill_pollfds(struct jbus **jbuses, int njbuses, struct pollfd *fds) { int i, r; - for (r = i = 0 ; i < njbuses ; i++) { + for (r = i = 0; i < njbuses; i++) { if (jbuses[i]->watchnr) { fds[r].fd = jbuses[i]->watchfd; fds[r].events = jbuses[i]->watchflags; @@ -674,18 +945,32 @@ int jbus_fill_pollfds(struct jbus **jbuses, int njbuses, struct pollfd *fds) return r; } -int jbus_dispatch_pollfds(struct jbus **jbuses, int njbuses, struct pollfd *fds, int maxcount) +/* + * Dispatchs a maximum of 'maxcount' events received by poll in 'fds' for the + * 'njbuses' jbuses of the array 'jbuses'. + * + * Returns the count of event dispatched. + */ +int jbus_dispatch_pollfds( + struct jbus **jbuses, + int njbuses, + struct pollfd *fds, + int maxcount) { int i, r, n; DBusDispatchStatus sts; - for (r = n = i = 0 ; i < njbuses && n < maxcount ; i++) { + for (r = n = i = 0; i < njbuses && n < maxcount; i++) { if (jbuses[i]->watchnr && fds[r].fd == jbuses[i]->watchfd) { if (fds[r].revents) { - dbus_connection_read_write(jbuses[i]->connection, 0); - sts = dbus_connection_get_dispatch_status(jbuses[i]->connection); - while(sts == DBUS_DISPATCH_DATA_REMAINS && n < maxcount) { - sts = dbus_connection_dispatch(jbuses[i]->connection); + dbus_connection_read_write( + jbuses[i]->connection, 0); + sts = dbus_connection_get_dispatch_status( + jbuses[i]->connection); + while (sts == DBUS_DISPATCH_DATA_REMAINS + && n < maxcount) { + sts = dbus_connection_dispatch( + jbuses[i]->connection); n++; } } @@ -695,15 +980,22 @@ int jbus_dispatch_pollfds(struct jbus **jbuses, int njbuses, struct pollfd *fds, return n; } +/* + * Dispatches 'maxcount' of buffered data from the 'njbuses' jbuses of the + * array 'jbuses'. + * + * Returns the count of event dispatched. + */ int jbus_dispatch_multiple(struct jbus **jbuses, int njbuses, int maxcount) { int i, r; DBusDispatchStatus sts; - for (i = r = 0 ; i < njbuses && r < maxcount ; i++) { + for (i = r = 0; i < njbuses && r < maxcount; i++) { dbus_connection_read_write(jbuses[i]->connection, 0); - sts = dbus_connection_get_dispatch_status(jbuses[i]->connection); - while(sts == DBUS_DISPATCH_DATA_REMAINS && r < maxcount) { + sts = dbus_connection_get_dispatch_status( + jbuses[i]->connection); + while (sts == DBUS_DISPATCH_DATA_REMAINS && r < maxcount) { sts = dbus_connection_dispatch(jbuses[i]->connection); r++; } @@ -711,7 +1003,17 @@ int jbus_dispatch_multiple(struct jbus **jbuses, int njbuses, int maxcount) return r; } -int jbus_read_write_dispatch_multiple(struct jbus **jbuses, int njbuses, int toms, int maxcount) +/* + * Polls during at most 'toms' milliseconds and dispatches 'maxcount' + * of events from the 'njbuses' jbuses of the array 'jbuses'. + * + * Returns the count of event dispatched or -1 in case of error. + */ +int jbus_read_write_dispatch_multiple( + struct jbus **jbuses, + int njbuses, + int toms, + int maxcount) { int n, r, s; struct pollfd *fds; @@ -720,15 +1022,15 @@ int jbus_read_write_dispatch_multiple(struct jbus **jbuses, int njbuses, int tom errno = EINVAL; return -1; } - fds = alloca((unsigned)njbuses * sizeof * fds); + fds = alloca((unsigned)njbuses * sizeof *fds); assert(fds != NULL); r = jbus_dispatch_multiple(jbuses, njbuses, maxcount); if (r) return r; n = jbus_fill_pollfds(jbuses, njbuses, fds); - for(;;) { - s = poll(fds, (nfds_t)n, toms); + for (;;) { + s = poll(fds, (nfds_t) n, toms); if (s >= 0) break; if (errno != EINTR) @@ -739,23 +1041,77 @@ int jbus_read_write_dispatch_multiple(struct jbus **jbuses, int njbuses, int tom return n >= 0 ? r + n : r ? r : n; } +/* + * Polls during at most 'toms' milliseconds and dispatches + * the events from 'jbus'. + * + * Returns the count of event dispatched or -1 in case of error. + */ int jbus_read_write_dispatch(struct jbus *jbus, int toms) { int r = jbus_read_write_dispatch_multiple(&jbus, 1, toms, 1000); return r < 0 ? r : 0; } -int jbus_call_ss(struct jbus *jbus, const char *method, const char *query, void (*onresp)(int, const char*, void*), void *data) +/* + * Asynchronous call to 'method' of 'jbus' passing the string 'query'. + * On response, the function 'onresp' is called with the returned string + * value and the closure 'data'. + * 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 'data' + * + * Returns 0 in case of success or -1 in case of error. + */ +int jbus_call_ss( + struct jbus *jbus, + const char *method, + const char *query, + void (*onresp) (int, const char *, void *), + void *data) { return call(jbus, method, query, onresp, NULL, data); } -int jbus_call_sj(struct jbus *jbus, const char *method, const char *query, void (*onresp)(int, struct json_object*, void*), void *data) +/* + * Asynchronous call to 'method' of 'jbus' passing the string 'query'. + * On response, the function 'onresp' is called with the returned json + * value and the closure 'data'. + * The function 'onresp' is invoked with 3 parameters: + * 1. int: 0 if no error or -1 if error. + * 2. const char *: the returned json (might be NULL if error) + * 3. void *: the closure 'data' + * + * Returns 0 in case of success or -1 in case of error. + */ +int jbus_call_sj( + struct jbus *jbus, + const char *method, + const char *query, + void (*onresp) (int, struct json_object *, void *), + void *data) { return call(jbus, method, query, NULL, onresp, data); } -int jbus_call_js(struct jbus *jbus, const char *method, struct json_object *query, void (*onresp)(int, const char*, void*), void *data) +/* + * Asynchronous call to 'method' of 'jbus' passing the json 'query'. + * On response, the function 'onresp' is called with the returned string + * value and the closure 'data'. + * 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 'data' + * + * Returns 0 in case of success or -1 in case of error. + */ +int jbus_call_js( + struct jbus *jbus, + const char *method, + struct json_object *query, + void (*onresp) (int, const char *, void *), + void *data) { const char *str = json_object_to_json_string(query); if (str == NULL) { @@ -765,7 +1121,23 @@ int jbus_call_js(struct jbus *jbus, const char *method, struct json_object *quer return call(jbus, method, str, onresp, NULL, data); } -int jbus_call_jj(struct jbus *jbus, const char *method, struct json_object *query, void (*onresp)(int, struct json_object*, void*), void *data) +/* + * Asynchronous call to 'method' of 'jbus' passing the json 'query'. + * On response, the function 'onresp' is called with the returned json + * value and the closure 'data'. + * The function 'onresp' is invoked with 3 parameters: + * 1. int: 0 if no error or -1 if error. + * 2. const char *: the returned json (might be NULL if error) + * 3. void *: the closure 'data' + * + * Returns 0 in case of success or -1 in case of error. + */ +int jbus_call_jj( + struct jbus *jbus, + const char *method, + struct json_object *query, + void (*onresp) (int, struct json_object *, void *), + void *data) { const char *str = json_object_to_json_string(query); if (str == NULL) { @@ -775,29 +1147,57 @@ int jbus_call_jj(struct jbus *jbus, const char *method, struct json_object *quer return call(jbus, method, str, NULL, onresp, data); } -char *jbus_call_ss_sync(struct jbus *jbus, const char *method, const char *query) +/* + * Synchronous call to 'method' of 'jbus' passing the string 'query'. + * The returned string response is returned. + * + * Returns the string response or NULL in case of error. + */ +char *jbus_call_ss_sync( + struct jbus *jbus, + const char *method, + const char *query) { struct respsync synchro; synchro.value = NULL; - synchro.replied = jbus_call_ss(jbus, method, query, sync_of_replies, &synchro); - while (!synchro.replied && !jbus_read_write_dispatch(jbus, -1)); + synchro.replied = + jbus_call_ss(jbus, method, query, sync_of_replies, &synchro); + while (!synchro.replied && !jbus_read_write_dispatch(jbus, -1)) ; return synchro.value; } -struct json_object *jbus_call_sj_sync(struct jbus *jbus, const char *method, const char *query) +/* + * Synchronous call to 'method' of 'jbus' passing the string 'query'. + * The returned json response is returned. + * + * Returns the json response or NULL in case of error. + */ +struct json_object *jbus_call_sj_sync( + struct jbus *jbus, + const char *method, + const char *query) { struct json_object *obj; char *str = jbus_call_ss_sync(jbus, method, query); if (str == NULL) obj = NULL; else { - parse(jbus, str, &obj); + jparse(jbus, str, &obj); free(str); } return obj; } -char *jbus_call_js_sync(struct jbus *jbus, const char *method, struct json_object *query) +/* + * Synchronous call to 'method' of 'jbus' passing the json 'query'. + * The returned string response is returned. + * + * Returns the string response or NULL in case of error. + */ +char *jbus_call_js_sync( + struct jbus *jbus, + const char *method, + struct json_object *query) { const char *str = json_object_to_json_string(query); if (str == NULL) { @@ -807,7 +1207,16 @@ char *jbus_call_js_sync(struct jbus *jbus, const char *method, struct json_objec return jbus_call_ss_sync(jbus, method, str); } -struct json_object *jbus_call_jj_sync(struct jbus *jbus, const char *method, struct json_object *query) +/* + * Synchronous call to 'method' of 'jbus' passing the json 'query'. + * The returned json response is returned. + * + * Returns the json response or NULL in case of error. + */ +struct json_object *jbus_call_jj_sync( + struct jbus *jbus, + const char *method, + struct json_object *query) { const char *str = json_object_to_json_string(query); if (str == NULL) { @@ -817,17 +1226,43 @@ struct json_object *jbus_call_jj_sync(struct jbus *jbus, const char *method, str return jbus_call_sj_sync(jbus, method, str); } -int jbus_on_signal_s(struct jbus *jbus, const char *name, void (*onsig)(const char *, void *), void *data) +/* + * Records for 'jbus' the string signal handler 'onsig' with closure 'data' + * for the signal of 'name'. + * The callback handler is called with 2 arguments: + * 1. char *: the string parameter associated to the signal + * 2. void *: the closure data. + * + * Returns 0 in case of success or -1 otherwise. + */ +int jbus_on_signal_s( + struct jbus *jbus, + const char *name, + void (*onsig) (const char *, void *), + void *data) { return add_signal(jbus, name, onsig, NULL, data); } -int jbus_on_signal_j(struct jbus *jbus, const char *name, void (*onsig)(struct json_object *, void *), void *data) +/* + * Records for 'jbus' the json signal handler 'onsig' with closure 'data' + * for the signal of 'name'. + * The callback handler is called with 2 arguments: + * 1. struct json_object *: the json parameter associated to the signal + * 2. void *: the closure data. + * + * Returns 0 in case of success or -1 otherwise. + */ +int jbus_on_signal_j( + struct jbus *jbus, + const char *name, + void (*onsig) (struct json_object *, void *), + void *data) { return add_signal(jbus, name, NULL, onsig, data); } -/************************** FEW LITTLE TESTS *****************************************/ +/****************** FEW LITTLE TESTS *****************************************/ #ifdef SERVER #include @@ -835,20 +1270,24 @@ int jbus_on_signal_j(struct jbus *jbus, const char *name, void (*onsig)(struct j struct jbus *jbus; void ping(struct jreq *jreq, struct json_object *request, void *unused) { -printf("ping(%s) -> %s\n",json_object_to_json_string(request),json_object_to_json_string(request)); + printf("ping(%s) -> %s\n", json_object_to_json_string(request), + json_object_to_json_string(request)); jbus_reply_j(jreq, request); - json_object_put(request); + json_object_put(request); } + void incr(struct jreq *jreq, struct json_object *request, void *unused) { static int counter = 0; struct json_object *res = json_object_new_int(++counter); -printf("incr(%s) -> %s\n",json_object_to_json_string(request),json_object_to_json_string(res)); + printf("incr(%s) -> %s\n", json_object_to_json_string(request), + json_object_to_json_string(res)); jbus_reply_j(jreq, res); -jbus_send_signal_j(jbus, "incremented", res); + jbus_send_signal_j(jbus, "incremented", res); json_object_put(res); json_object_put(request); } + int main() { int s1, s2, s3; @@ -857,7 +1296,7 @@ int main() s2 = jbus_add_service_j(jbus, "incr", incr, NULL); s3 = jbus_start_serving(jbus); printf("started %d %d %d\n", s1, s2, s3); - while (!jbus_read_write_dispatch (jbus, -1)); + while (!jbus_read_write_dispatch(jbus, -1)) ; } #endif #ifdef CLIENT @@ -866,32 +1305,30 @@ int main() struct jbus *jbus; void onresp(int status, struct json_object *response, void *data) { - printf("resp: %d, %s, %s\n",status,(char*)data,json_object_to_json_string(response)); + printf("resp: %d, %s, %s\n", status, (char *)data, + json_object_to_json_string(response)); json_object_put(response); } + void signaled(const char *data) { printf("signaled with {%s}\n", data); } + int main() { int i = 10; jbus = create_jbus(1, "/bzh/iot/jdbus"); jbus_on_signal_s(jbus, "incremented", signaled); - while(i--) { - jbus_call_sj(jbus, "ping", "{\"toto\":[1,2,3,4,true,\"toto\"]}", onresp, "ping"); - jbus_call_sj(jbus, "incr", "{\"doit\":\"for-me\"}", onresp, "incr"); - jbus_read_write_dispatch (jbus, 1); + while (i--) { + jbus_call_sj(jbus, "ping", "{\"toto\":[1,2,3,4,true,\"toto\"]}", + onresp, "ping"); + jbus_call_sj(jbus, "incr", "{\"doit\":\"for-me\"}", onresp, + "incr"); + jbus_read_write_dispatch(jbus, 1); } - printf("[[[%s]]]\n", jbus_call_ss_sync(jbus, "ping", "\"formidable!\"")); - while (!jbus_read_write_dispatch (jbus, -1)); + printf("[[[%s]]]\n", + jbus_call_ss_sync(jbus, "ping", "\"formidable!\"")); + while (!jbus_read_write_dispatch(jbus, -1)) ; } #endif - - - - - - - - diff --git a/src/utils-jbus.h b/src/utils-jbus.h index 11cb8ed..1069098 100644 --- a/src/utils-jbus.h +++ b/src/utils-jbus.h @@ -16,9 +16,9 @@ limitations under the License. */ - struct jreq; struct jbus; +struct pollfd; extern struct jbus *create_jbus(const char *path, int session); extern struct jbus *create_jbus_session(const char *path); @@ -27,38 +27,133 @@ extern struct jbus *create_jbus_system(const char *path); extern void jbus_addref(struct jbus *jbus); extern void jbus_unref(struct jbus *jbus); -struct pollfd; -extern int jbus_fill_pollfds(struct jbus **jbuses, int njbuses, struct pollfd *fds); -extern int jbus_dispatch_pollfds(struct jbus **jbuses, int njbuses, struct pollfd *fds, int maxcount); -extern int jbus_read_write_dispatch_multiple(struct jbus **jbuses, int njbuses, int toms, int maxcount); -extern int jbus_dispatch_multiple(struct jbus **jbuses, int njbuses, int maxcount); +extern int jbus_fill_pollfds( + struct jbus **jbuses, + int njbuses, + struct pollfd *fds); -extern int jbus_read_write_dispatch(struct jbus *jbus, int toms); +extern int jbus_dispatch_pollfds( + struct jbus **jbuses, + int njbuses, + struct pollfd *fds, + int maxcount); -/* verbs for the clients */ -extern int jbus_call_ss(struct jbus *jbus, const char *method, const char *query, void (*onresp)(int, const char *, void *), void *data); -extern int jbus_call_js(struct jbus *jbus, const char *method, struct json_object *query, void (*onresp)(int, const char *, void *), void *data); -extern int jbus_call_sj(struct jbus *jbus, const char *method, const char *query, void (*onresp)(int, struct json_object *, void *), void *data); -extern int jbus_call_jj(struct jbus *jbus, const char *method, struct json_object *query, void (*onresp)(int, struct json_object *, void *), void *data); +extern int jbus_read_write_dispatch_multiple( + struct jbus **jbuses, + int njbuses, + int toms, + int maxcount); -extern char *jbus_call_ss_sync(struct jbus *jbus, const char *method, const char *query); -extern char *jbus_call_js_sync(struct jbus *jbus, const char *method, struct json_object *query); -extern struct json_object *jbus_call_sj_sync(struct jbus *jbus, const char *method, const char *query); -extern struct json_object *jbus_call_jj_sync(struct jbus *jbus, const char *method, struct json_object *query); +extern int jbus_dispatch_multiple( + struct jbus **jbuses, + int njbuses, + int maxcount); -extern int jbus_on_signal_s(struct jbus *jbus, const char *name, void (*onsignal)(const char *, void *), void *data); -extern int jbus_on_signal_j(struct jbus *jbus, const char *name, void (*onsignal)(struct json_object *, void *), void *data); +extern int jbus_read_write_dispatch( + struct jbus *jbus, + int toms); -/* verbs for servers */ -extern int jbus_reply_s(struct jreq *jreq, const char *reply); -extern int jbus_reply_j(struct jreq *jreq, struct json_object *reply); -extern int jbus_reply_error_s(struct jreq *jreq, const char *reply); -extern int jbus_reply_error_j(struct jreq *jreq, struct json_object *reply); -extern int jbus_add_service_s(struct jbus *jbus, const char *method, void (*oncall)(struct jreq *, const char *, void *), void *data); -extern int jbus_add_service_j(struct jbus *jbus, const char *method, void (*oncall)(struct jreq *, struct json_object *, void *), void *data); -extern int jbus_start_serving(struct jbus *jbus); -extern int jbus_send_signal_s(struct jbus *jbus, const char *name, const char *content); -extern int jbus_send_signal_j(struct jbus *jbus, const char *name, struct json_object *content); +/* verbs for the clients */ +extern int jbus_call_ss( + struct jbus *jbus, + const char *method, + const char *query, + void (*onresp) (int, const char *, void *), + void *data); + +extern int jbus_call_js( + struct jbus *jbus, + const char *method, + struct json_object *query, + void (*onresp) (int, const char *, void *), + void *data); + +extern int jbus_call_sj( + struct jbus *jbus, + const char *method, + const char *query, + void (*onresp) (int, struct json_object *, void *), + void *data); + +extern int jbus_call_jj( + struct jbus *jbus, + const char *method, + struct json_object *query, + void (*onresp) (int, struct json_object *, void *), + void *data); + +extern char *jbus_call_ss_sync( + struct jbus *jbus, + const char *method, + const char *query); + +extern char *jbus_call_js_sync( + struct jbus *jbus, + const char *method, + struct json_object *query); + +extern struct json_object *jbus_call_sj_sync( + struct jbus *jbus, + const char *method, + const char *query); + +extern struct json_object *jbus_call_jj_sync( + struct jbus *jbus, + const char *method, + struct json_object *query); + +extern int jbus_on_signal_s( + struct jbus *jbus, + const char *name, + void (*onsignal) (const char *, void *), + void *data); + +extern int jbus_on_signal_j( + struct jbus *jbus, + const char *name, + void (*onsignal) (struct json_object *, void *), + void *data); +/* verbs for servers */ +extern int jbus_reply_s( + struct jreq *jreq, + const char *reply); + +extern int jbus_reply_j( + struct jreq *jreq, + struct json_object *reply); + +extern int jbus_reply_error_s( + struct jreq *jreq, + const char *reply); + +extern int jbus_reply_error_j( + struct jreq *jreq, + struct json_object *reply); + +extern int jbus_add_service_s( + struct jbus *jbus, + const char *method, + void (*oncall) (struct jreq *, const char *, void *), + void *data); + +extern int jbus_add_service_j( + struct jbus *jbus, + const char *method, + void (*oncall) (struct jreq *, struct json_object *, void *), + void *data); + +extern int jbus_start_serving( + struct jbus *jbus); + +extern int jbus_send_signal_s( + struct jbus *jbus, + const char *name, + const char *content); + +extern int jbus_send_signal_j( + struct jbus *jbus, + const char *name, + struct json_object *content);