afb-export: refactor of binder interface
authorJosé Bollo <jose.bollo@iot.bzh>
Tue, 19 Sep 2017 08:14:04 +0000 (10:14 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Mon, 9 Oct 2017 12:08:28 +0000 (14:08 +0200)
The interfaces of the binder called afb_ditf and
afb_svc are merged together to create the afb_export
structure.

Change-Id: I841ba04d7b2f94bfc19f691ec746d0bd221f164d
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
13 files changed:
src/CMakeLists.txt
src/afb-api-so-v1.c
src/afb-api-so-v2.c
src/afb-ditf.c [deleted file]
src/afb-ditf.h [deleted file]
src/afb-export.c [new file with mode: 0644]
src/afb-export.h [new file with mode: 0644]
src/afb-hook.c
src/afb-hook.h
src/afb-monitor.c
src/afb-svc.c [deleted file]
src/afb-svc.h [deleted file]
src/afb-trace.c

index 74702ad..39b7fe1 100644 (file)
@@ -43,8 +43,8 @@ ADD_LIBRARY(afb-lib STATIC
        afb-context.c
        afb-cred.c
        afb-debug.c
-       afb-ditf.c
        afb-evt.c
+       afb-export.c
        afb-hook.c
        afb-hreq.c
        afb-hsrv.c
@@ -55,7 +55,6 @@ ADD_LIBRARY(afb-lib STATIC
        afb-proto-ws.c
        afb-session.c
        afb-stub-ws.c
-       afb-svc.c
        afb-trace.c
        afb-websock.c
        afb-ws-client.c
index 84b870d..dd2db5b 100644 (file)
 #include "afb-api.h"
 #include "afb-api-so-v1.h"
 #include "afb-apiset.h"
-#include "afb-svc.h"
-#include "afb-evt.h"
+#include "afb-export.h"
+//#include "afb-evt.h"
 #include "afb-common.h"
 #include "afb-context.h"
 #include "afb-api-so.h"
 #include "afb-xreq.h"
-#include "afb-ditf.h"
 #include "verbose.h"
 
 /*
@@ -51,9 +50,7 @@ static const char afb_api_so_v1_service_event[] = "afbBindingV1ServiceEvent";
 struct api_so_v1 {
        struct afb_binding_v1 *binding; /* descriptor */
        void *handle;                   /* context of dlopen */
-       struct afb_svc *service;        /* handler for service started */
-       struct afb_binding_interface_v1 interface;
-       struct afb_ditf ditf;           /* daemon interface */
+       struct afb_export *export;      /* export */
 };
 
 static const struct afb_verb_desc_v1 *search(struct api_so_v1 *desc, const char *name)
@@ -84,70 +81,64 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
        struct api_so_v1 *desc = closure;
 
        /* check state */
-       if (desc->service != NULL) {
+       if (afb_export_is_started(desc->export)) {
                /* not an error when onneed */
                if (onneed != 0)
                        goto done;
 
                /* already started: it is an error */
-               ERROR("Service %s already started", desc->ditf.api);
+               ERROR("Service %s already started", afb_export_apiname(desc->export));
                return -1;
        }
 
        /* get the initialisation */
        init = dlsym(desc->handle, afb_api_so_v1_service_init);
        onevent = dlsym(desc->handle, afb_api_so_v1_service_event);
-       if (init == NULL && onevent == NULL) {
-               /* not an error when onneed */
-               if (onneed != 0)
-                       goto done;
 
-               /* no initialisation method */
-               ERROR("Binding %s is not a service", desc->ditf.api);
-               return -1;
+       /* unshare the session if asked */
+       if (!share_session) {
+               rc = afb_export_unshare_session(desc->export);
+               if (rc < 0) {
+                       ERROR("Can't unshare the session for %s", afb_export_apiname(desc->export));
+                       return -1;
+               }
        }
 
-       /* get the event handler if any */
-       desc->service = afb_svc_create(desc->ditf.api, apiset, share_session, onevent, NULL);
-       if (desc->service == NULL) {
-               ERROR("Creation of service %s failed", desc->ditf.api);
+       /* set event handling */
+       rc = afb_export_handle_events(desc->export, onevent);
+       if (rc < 0) {
+               ERROR("Can't set event handler for %s", afb_export_apiname(desc->export));
                return -1;
        }
 
        /* Starts the service */
-       desc->ditf.state = Daemon_Init;
-       rc = afb_svc_start_v1(desc->service, init);
+       rc = afb_export_start_v1(desc->export, init);
        if (rc < 0) {
                /* initialisation error */
-               ERROR("Initialisation of service %s failed (%d): %m", desc->ditf.api, rc);
-               afb_svc_destroy(desc->service, NULL);
-               desc->service = NULL;
+               ERROR("Initialisation of service %s failed (%d): %m", afb_export_apiname(desc->export), rc);
                return rc;
        }
 
 done:
-       desc->ditf.state = Daemon_Run;
        return 0;
 }
 
 static void update_hooks_cb(void *closure)
 {
        struct api_so_v1 *desc = closure;
-       afb_ditf_update_hook(&desc->ditf);
-       if (desc->service)
-               afb_svc_update_hook(desc->service);
+       afb_export_update_hook(desc->export);
 }
 
 static int get_verbosity_cb(void *closure)
 {
        struct api_so_v1 *desc = closure;
-       return desc->interface.verbosity;
+       return afb_export_verbosity_get(desc->export);
 }
 
 static void set_verbosity_cb(void *closure, int level)
 {
        struct api_so_v1 *desc = closure;
-       desc->interface.verbosity = level;
+       afb_export_verbosity_set(desc->export, level);
 }
 
 static struct json_object *addperm(struct json_object *o, struct json_object *x)
@@ -195,9 +186,9 @@ static struct json_object *make_description_openAPIv3(struct api_so_v1 *desc)
 
        i = json_object_new_object();
        json_object_object_add(r, "info", i);
-       json_object_object_add(i, "title", json_object_new_string(desc->ditf.api));
+       json_object_object_add(i, "title", json_object_new_string(afb_export_apiname(desc->export)));
        json_object_object_add(i, "version", json_object_new_string("0.0.0"));
-       json_object_object_add(i, "description", json_object_new_string(desc->binding->v1.info ?: desc->ditf.api));
+       json_object_object_add(i, "description", json_object_new_string(desc->binding->v1.info ?: afb_export_apiname(desc->export)));
 
        p = json_object_new_object();
        json_object_object_add(r, "paths", p);
@@ -254,6 +245,7 @@ int afb_api_so_v1_add(const char *path, void *handle, struct afb_apiset *apiset)
        struct api_so_v1 *desc;
        struct afb_binding_v1 *(*register_function) (const struct afb_binding_interface_v1 *interface);
        struct afb_api afb_api;
+       struct afb_export *export;
 
        /* retrieves the register function */
        register_function = dlsym(handle, afb_api_so_v1_register);
@@ -262,62 +254,62 @@ int afb_api_so_v1_add(const char *path, void *handle, struct afb_apiset *apiset)
        INFO("binding [%s] is a valid AFB binding V1", path);
 
        /* allocates the description */
+       export = afb_export_create_v1(path);
        desc = calloc(1, sizeof *desc);
-       if (desc == NULL) {
+       if (desc == NULL || export == NULL) {
                ERROR("out of memory");
                goto error;
        }
+       desc->export = export;
        desc->handle = handle;
 
-       /* init the interface */
-       afb_ditf_init_v1(&desc->ditf, path, &desc->interface);
-
        /* init the binding */
        INFO("binding [%s] calling registering function %s", path, afb_api_so_v1_register);
-       desc->binding = register_function(&desc->interface);
+       desc->binding = afb_export_register_v1(desc->export, register_function);
        if (desc->binding == NULL) {
                ERROR("binding [%s] register function failed. continuing...", path);
-               goto error2;
+               goto error;
        }
 
        /* check the returned structure */
        if (desc->binding->type != AFB_BINDING_VERSION_1) {
                ERROR("binding [%s] invalid type %d...", path, desc->binding->type);
-               goto error2;
+               goto error;
        }
        if (desc->binding->v1.prefix == NULL || *desc->binding->v1.prefix == 0) {
                ERROR("binding [%s] bad prefix...", path);
-               goto error2;
+               goto error;
        }
        if (!afb_api_is_valid_name(desc->binding->v1.prefix)) {
                ERROR("binding [%s] invalid prefix...", path);
-               goto error2;
+               goto error;
        }
        if (desc->binding->v1.info == NULL || *desc->binding->v1.info == 0) {
                ERROR("binding [%s] bad description...", path);
-               goto error2;
+               goto error;
        }
        if (desc->binding->v1.verbs == NULL) {
                ERROR("binding [%s] no APIs...", path);
-               goto error2;
+               goto error;
        }
 
        /* records the binding */
-       if (desc->ditf.api == path)
-               afb_ditf_rename(&desc->ditf, desc->binding->v1.prefix);
+       if (!strcmp(path, afb_export_apiname(desc->export)))
+               afb_export_rename(desc->export, desc->binding->v1.prefix);
        afb_api.closure = desc;
        afb_api.itf = &so_v1_api_itf;
        afb_api.noconcurrency = 0;
-       if (afb_apiset_add(apiset, desc->ditf.api, afb_api) < 0) {
+       if (afb_apiset_add(apiset, afb_export_apiname(desc->export), afb_api) < 0) {
                ERROR("binding [%s] can't be registered...", path);
-               goto error2;
+               goto error;
        }
-       INFO("binding %s loaded with API prefix %s", path, desc->ditf.api);
+       INFO("binding %s loaded with API prefix %s", path, afb_export_apiname(desc->export));
        return 1;
 
-error2:
-       free(desc);
 error:
+       afb_export_destroy(export);
+       free(desc);
+
        return -1;
 }
 
index 3281224..68fd865 100644 (file)
@@ -28,8 +28,7 @@
 #include "afb-api.h"
 #include "afb-api-so-v2.h"
 #include "afb-apiset.h"
-#include "afb-svc.h"
-#include "afb-ditf.h"
+#include "afb-export.h"
 #include "afb-evt.h"
 #include "afb-common.h"
 #include "afb-context.h"
@@ -49,10 +48,8 @@ static const char afb_api_so_v2_data[] = "afbBindingV2data";
  */
 struct api_so_v2 {
        const struct afb_binding_v2 *binding;   /* descriptor */
-       struct afb_binding_data_v2 *data;       /* data */
-       void *handle;                   /* context of dlopen */
-       struct afb_svc *service;        /* handler for service started */
-       struct afb_ditf ditf;           /* daemon interface */
+       void *handle;                           /* context of dlopen */
+       struct afb_export *export;              /* exportations */
 };
 
 static const struct afb_verb_v2 *search(struct api_so_v2 *desc, const char *name)
@@ -84,71 +81,64 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
        struct api_so_v2 *desc = closure;
 
        /* check state */
-       if (desc->service != NULL) {
+       if (afb_export_is_started(desc->export)) {
                /* not an error when onneed */
                if (onneed != 0)
                        goto done;
 
                /* already started: it is an error */
-               ERROR("Service %s already started", desc->ditf.api);
+               ERROR("Service %s already started", afb_export_apiname(desc->export));
                return -1;
        }
 
        /* get the initialisation */
        start = desc->binding->init;
        onevent = desc->binding->onevent;
-       if (start == NULL && onevent == NULL) {
-               /* not an error when onneed */
-               if (onneed != 0)
-                       goto done;
 
-               /* no initialisation method */
-               ERROR("Binding %s is not a service", desc->ditf.api);
-               return -1;
+       /* unshare the session if asked */
+       if (!share_session) {
+               rc = afb_export_unshare_session(desc->export);
+               if (rc < 0) {
+                       ERROR("Can't unshare the session for %s", afb_export_apiname(desc->export));
+                       return -1;
+               }
        }
 
-       /* get the event handler if any */
-       desc->service = afb_svc_create(desc->ditf.api, apiset, share_session, onevent, &desc->data->service);
-       if (desc->service == NULL) {
-               /* starting error */
-               ERROR("Starting service %s failed", desc->ditf.api);
+       /* set event handling */
+       rc = afb_export_handle_events(desc->export, onevent);
+       if (rc < 0) {
+               ERROR("Can't set event handler for %s", afb_export_apiname(desc->export));
                return -1;
        }
 
        /* Starts the service */
-       desc->ditf.state = Daemon_Init;
-       rc = afb_svc_start_v2(desc->service, start);
+       rc = afb_export_start_v2(desc->export, start);
        if (rc < 0) {
                /* initialisation error */
-               ERROR("Initialisation of service %s failed (%d): %m", desc->ditf.api, rc);
-               afb_svc_destroy(desc->service, &desc->data->service);
-               desc->service = NULL;
+               ERROR("Initialisation of service %s failed (%d): %m", afb_export_apiname(desc->export), rc);
                return rc;
        }
 
 done:
-       desc->ditf.state = Daemon_Run;
        return 0;
 }
 
 static void update_hooks_cb(void *closure)
 {
        struct api_so_v2 *desc = closure;
-       afb_ditf_update_hook(&desc->ditf);
-       if (desc->service)
-               afb_svc_update_hook(desc->service);
+       afb_export_update_hook(desc->export);
 }
 
 static int get_verbosity_cb(void *closure)
 {
        struct api_so_v2 *desc = closure;
-       return desc->data->verbosity;
+       return afb_export_verbosity_get(desc->export);
 }
 
 static void set_verbosity_cb(void *closure, int level)
 {
        struct api_so_v2 *desc = closure;
-       desc->data->verbosity = level;
+       afb_export_verbosity_set(desc->export, level);
 }
 
 static struct json_object *addperm(struct json_object *o, struct json_object *x)
@@ -225,9 +215,9 @@ static struct json_object *make_description_openAPIv3(struct api_so_v2 *desc)
 
        i = json_object_new_object();
        json_object_object_add(r, "info", i);
-       json_object_object_add(i, "title", json_object_new_string(desc->ditf.api));
+       json_object_object_add(i, "title", json_object_new_string(afb_export_apiname(desc->export)));
        json_object_object_add(i, "version", json_object_new_string("0.0.0"));
-       json_object_object_add(i, "description", json_object_new_string(desc->binding->info ?: desc->ditf.api));
+       json_object_object_add(i, "description", json_object_new_string(desc->binding->info ?: afb_export_apiname(desc->export)));
 
        p = json_object_new_object();
        json_object_object_add(r, "paths", p);
@@ -288,6 +278,7 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle
        int rc;
        struct api_so_v2 *desc;
        struct afb_api afb_api;
+       struct afb_export *export;
 
        /* basic checks */
        assert(binding);
@@ -296,27 +287,23 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle
        assert(data);
 
        /* allocates the description */
+       export = afb_export_create_v2(binding->api, data);
        desc = calloc(1, sizeof *desc);
        if (desc == NULL) {
                ERROR("out of memory");
                goto error;
        }
        desc->binding = binding;
-       desc->data = data;
        desc->handle = handle;
-       desc->service = NULL;
-
-       /* init the interface */
-       desc->data->verbosity = verbosity;
-       afb_ditf_init_v2(&desc->ditf, binding->api, data);
+       desc->export = export;
 
        /* init the binding */
        if (binding->preinit) {
                INFO("binding %s calling preinit function", binding->api);
                rc = binding->preinit();
                if (rc < 0) {
-                       ERROR("binding %s preinit function failed...", desc->ditf.api);
-                       goto error2;
+                       ERROR("binding %s preinit function failed...", afb_export_apiname(desc->export));
+                       goto error;
                }
        }
 
@@ -324,16 +311,17 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle
        afb_api.closure = desc;
        afb_api.itf = &so_v2_api_itf;
        afb_api.noconcurrency = binding->noconcurrency;
-       if (afb_apiset_add(apiset, desc->ditf.api, afb_api) < 0) {
-               ERROR("binding %s can't be registered to set %s...", desc->ditf.api, afb_apiset_name(apiset));
-               goto error2;
+       if (afb_apiset_add(apiset, afb_export_apiname(desc->export), afb_api) < 0) {
+               ERROR("binding %s can't be registered to set %s...", afb_export_apiname(desc->export), afb_apiset_name(apiset));
+               goto error;
        }
-       INFO("binding %s added to set %s", desc->ditf.api, afb_apiset_name(apiset));
+       INFO("binding %s added to set %s", afb_export_apiname(desc->export), afb_apiset_name(apiset));
        return 1;
 
-error2:
-       free(desc);
 error:
+       afb_export_destroy(export);
+       free(desc);
+
        return -1;
 }
 
diff --git a/src/afb-ditf.c b/src/afb-ditf.c
deleted file mode 100644 (file)
index a7f97dd..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 "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 <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <json-c/json.h>
-
-#include <afb/afb-binding-v1.h>
-#include <afb/afb-binding-v2.h>
-
-#include "afb-ditf.h"
-#include "afb-evt.h"
-#include "afb-common.h"
-#include "afb-xreq.h"
-#include "afb-api.h"
-#include "afb-apiset.h"
-#include "afb-hook.h"
-#include "jobs.h"
-#include "verbose.h"
-
-extern struct afb_apiset *main_apiset;
-
-/**********************************************
-* normal flow
-**********************************************/
-static void vverbose_cb(void *closure, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
-{
-       char *p;
-       struct afb_ditf *ditf = closure;
-
-       if (!fmt || vasprintf(&p, fmt, args) < 0)
-               vverbose(level, file, line, function, fmt, args);
-       else {
-               verbose(level, file, line, function, "[API %s] %s", ditf->api, p);
-               free(p);
-       }
-}
-
-static void old_vverbose_cb(void *closure, int level, const char *file, int line, const char *fmt, va_list args)
-{
-       vverbose_cb(closure, level, file, line, NULL, fmt, args);
-}
-
-static struct afb_event event_make_cb(void *closure, const char *name)
-{
-       size_t plen, nlen;
-       char *event;
-       struct afb_ditf *ditf = closure;
-
-       /* check daemon state */
-       if (ditf->state == Daemon_Pre_Init) {
-               ERROR("[API %s] Bad call to 'afb_daemon_event_make(%s)', must not be in PreInit", ditf->api, name);
-               errno = EINVAL;
-               return (struct afb_event){ .itf = NULL, .closure = NULL };
-       }
-
-       /* makes the event name */
-       plen = strlen(ditf->api);
-       nlen = strlen(name);
-       event = alloca(nlen + plen + 2);
-       memcpy(event, ditf->api, plen);
-       event[plen] = '/';
-       memcpy(event + plen + 1, name, nlen + 1);
-
-       /* create the event */
-       return afb_evt_create_event(event);
-}
-
-static int event_broadcast_cb(void *closure, const char *name, struct json_object *object)
-{
-       size_t plen, nlen;
-       char *event;
-       struct afb_ditf *ditf = closure;
-
-       /* check daemon state */
-       if (ditf->state == Daemon_Pre_Init) {
-               ERROR("[API %s] Bad call to 'afb_daemon_event_broadcast(%s, %s)', must not be in PreInit", ditf->api, name, json_object_to_json_string(object));
-               errno = EINVAL;
-               return 0;
-       }
-
-       /* makes the event name */
-       plen = strlen(ditf->api);
-       nlen = strlen(name);
-       event = alloca(nlen + plen + 2);
-       memcpy(event, ditf->api, plen);
-       event[plen] = '/';
-       memcpy(event + plen + 1, name, nlen + 1);
-
-       /* broadcast the event */
-       return afb_evt_broadcast(event, object);
-}
-
-static int rootdir_open_locale_cb(void *closure, const char *filename, int flags, const char *locale)
-{
-       return afb_common_rootdir_open_locale(filename, flags, locale);
-}
-
-static int queue_job_cb(void *closure, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
-{
-       return jobs_queue(group, timeout, callback, argument);
-}
-
-static struct afb_req unstore_req_cb(void *closure, struct afb_stored_req *sreq)
-{
-       return afb_xreq_unstore(sreq);
-}
-
-static int require_api_cb(void *closure, const char *name, int initialized)
-{
-       struct afb_ditf *ditf = closure;
-       if (ditf->state != Daemon_Init) {
-               ERROR("[API %s] Bad call to 'afb_daemon_require(%s, %d)', must be in Init", ditf->api, name, initialized);
-               errno = EINVAL;
-               return -1;
-       }
-       return -!(initialized ? afb_apiset_lookup_started : afb_apiset_lookup)(main_apiset, name, 1);
-}
-
-static int rename_api_cb(void *closure, const char *name)
-{
-       struct afb_ditf *ditf = closure;
-       if (ditf->state != Daemon_Pre_Init) {
-               ERROR("[API %s] Bad call to 'afb_daemon_rename(%s)', must be in PreInit", ditf->api, name);
-               errno = EINVAL;
-               return -1;
-       }
-       if (!afb_api_is_valid_name(name)) {
-               ERROR("[API %s] Can't rename to %s: bad API name", ditf->api, name);
-               errno = EINVAL;
-               return -1;
-       }
-       NOTICE("[API %s] renamed to [API %s]", ditf->api, name);
-       afb_ditf_rename(ditf, name);
-       return 0;
-}
-
-/**********************************************
-* hooked flow
-**********************************************/
-static void hooked_vverbose_cb(void *closure, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
-{
-       struct afb_ditf *ditf = closure;
-       va_list ap;
-       va_copy(ap, args);
-       vverbose_cb(closure, level, file, line, function, fmt, args);
-       afb_hook_ditf_vverbose(ditf, level, file, line, function, fmt, ap);
-       va_end(ap);
-}
-
-static void hooked_old_vverbose_cb(void *closure, int level, const char *file, int line, const char *fmt, va_list args)
-{
-       hooked_vverbose_cb(closure, level, file, line, NULL, fmt, args);
-}
-
-static struct afb_event hooked_event_make_cb(void *closure, const char *name)
-{
-       struct afb_ditf *ditf = closure;
-       struct afb_event r = event_make_cb(closure, name);
-       return afb_hook_ditf_event_make(ditf, name, r);
-}
-
-static int hooked_event_broadcast_cb(void *closure, const char *name, struct json_object *object)
-{
-       int r;
-       struct afb_ditf *ditf = closure;
-       json_object_get(object);
-       afb_hook_ditf_event_broadcast_before(ditf, name, json_object_get(object));
-       r = event_broadcast_cb(closure, name, object);
-       afb_hook_ditf_event_broadcast_after(ditf, name, object, r);
-       json_object_put(object);
-       return r;
-}
-
-static struct sd_event *hooked_get_event_loop(void *closure)
-{
-       struct afb_ditf *ditf = closure;
-       struct sd_event *r = afb_common_get_event_loop();
-       return afb_hook_ditf_get_event_loop(ditf, r);
-}
-
-static struct sd_bus *hooked_get_user_bus(void *closure)
-{
-       struct afb_ditf *ditf = closure;
-       struct sd_bus *r = afb_common_get_user_bus();
-       return afb_hook_ditf_get_user_bus(ditf, r);
-}
-
-static struct sd_bus *hooked_get_system_bus(void *closure)
-{
-       struct afb_ditf *ditf = closure;
-       struct sd_bus *r = afb_common_get_system_bus();
-       return afb_hook_ditf_get_system_bus(ditf, r);
-}
-
-static int hooked_rootdir_get_fd(void *closure)
-{
-       struct afb_ditf *ditf = closure;
-       int r = afb_common_rootdir_get_fd();
-       return afb_hook_ditf_rootdir_get_fd(ditf, r);
-}
-
-static int hooked_rootdir_open_locale_cb(void *closure, const char *filename, int flags, const char *locale)
-{
-       struct afb_ditf *ditf = closure;
-       int r = rootdir_open_locale_cb(closure, filename, flags, locale);
-       return afb_hook_ditf_rootdir_open_locale(ditf, filename, flags, locale, r);
-}
-
-static int hooked_queue_job_cb(void *closure, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
-{
-       struct afb_ditf *ditf = closure;
-       int r = queue_job_cb(closure, callback, argument, group, timeout);
-       return afb_hook_ditf_queue_job(ditf, callback, argument, group, timeout, r);
-}
-
-static struct afb_req hooked_unstore_req_cb(void *closure, struct afb_stored_req *sreq)
-{
-       struct afb_ditf *ditf = closure;
-       afb_hook_ditf_unstore_req(ditf, sreq);
-       return unstore_req_cb(closure, sreq);
-}
-
-static int hooked_require_api_cb(void *closure, const char *name, int initialized)
-{
-       int result;
-       struct afb_ditf *ditf = closure;
-       afb_hook_ditf_require_api(ditf, name, initialized);
-       result = require_api_cb(closure, name, initialized);
-       return afb_hook_ditf_require_api_result(ditf, name, initialized, result);
-}
-
-static int hooked_rename_api_cb(void *closure, const char *name)
-{
-       struct afb_ditf *ditf = closure;
-       const char *oldname = ditf->api;
-       int result = rename_api_cb(closure, name);
-       return afb_hook_ditf_rename_api(ditf, oldname, name, result);
-}
-
-/**********************************************
-* vectors
-**********************************************/
-static const struct afb_daemon_itf daemon_itf = {
-       .vverbose_v1 = old_vverbose_cb,
-       .vverbose_v2 = vverbose_cb,
-       .event_make = event_make_cb,
-       .event_broadcast = event_broadcast_cb,
-       .get_event_loop = afb_common_get_event_loop,
-       .get_user_bus = afb_common_get_user_bus,
-       .get_system_bus = afb_common_get_system_bus,
-       .rootdir_get_fd = afb_common_rootdir_get_fd,
-       .rootdir_open_locale = rootdir_open_locale_cb,
-       .queue_job = queue_job_cb,
-       .unstore_req = unstore_req_cb,
-       .require_api = require_api_cb,
-       .rename_api = rename_api_cb
-};
-
-static const struct afb_daemon_itf hooked_daemon_itf = {
-       .vverbose_v1 = hooked_old_vverbose_cb,
-       .vverbose_v2 = hooked_vverbose_cb,
-       .event_make = hooked_event_make_cb,
-       .event_broadcast = hooked_event_broadcast_cb,
-       .get_event_loop = hooked_get_event_loop,
-       .get_user_bus = hooked_get_user_bus,
-       .get_system_bus = hooked_get_system_bus,
-       .rootdir_get_fd = hooked_rootdir_get_fd,
-       .rootdir_open_locale = hooked_rootdir_open_locale_cb,
-       .queue_job = hooked_queue_job_cb,
-       .unstore_req = hooked_unstore_req_cb,
-       .require_api = hooked_require_api_cb,
-       .rename_api = hooked_rename_api_cb
-};
-
-void afb_ditf_init_v2(struct afb_ditf *ditf, const char *api, struct afb_binding_data_v2 *data)
-{
-       ditf->version = 2;
-       ditf->state = Daemon_Pre_Init;
-       ditf->v2 = data;
-       data->daemon.closure = ditf;
-       afb_ditf_rename(ditf, api);
-}
-
-void afb_ditf_init_v1(struct afb_ditf *ditf, const char *api, struct afb_binding_interface_v1 *itf)
-{
-       ditf->version = 1;
-       ditf->state = Daemon_Pre_Init;
-       ditf->v1 = itf;
-       itf->verbosity = verbosity;
-       itf->mode = AFB_MODE_LOCAL;
-       itf->daemon.closure = ditf;
-       afb_ditf_rename(ditf, api);
-}
-
-void afb_ditf_rename(struct afb_ditf *ditf, const char *api)
-{
-       ditf->api = api;
-       afb_ditf_update_hook(ditf);
-}
-
-void afb_ditf_update_hook(struct afb_ditf *ditf)
-{
-       int hooked = !!afb_hook_flags_ditf(ditf->api);
-       switch (ditf->version) {
-       case 1:
-               ditf->v1->daemon.itf = hooked ? &hooked_daemon_itf : &daemon_itf;
-               break;
-       default:
-       case 2:
-               ditf->v2->daemon.itf = hooked ? &hooked_daemon_itf : &daemon_itf;
-               break;
-       }
-}
-
diff --git a/src/afb-ditf.h b/src/afb-ditf.h
deleted file mode 100644 (file)
index a24eb0a..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 "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 afb_binding_interface_v1;
-struct afb_binding_data_v2;
-
-enum afb_ditf_state
-{
-       Daemon_Pre_Init,
-       Daemon_Init,
-       Daemon_Run
-};
-
-struct afb_ditf
-{
-       int version;
-       enum afb_ditf_state state;
-       const char *api;
-       union {
-               struct afb_binding_interface_v1 *v1;
-               struct afb_binding_data_v2 *v2;
-       };
-};
-
-extern void afb_ditf_init_v1(struct afb_ditf *ditf, const char *api, struct afb_binding_interface_v1 *itf);
-extern void afb_ditf_init_v2(struct afb_ditf *ditf, const char *api, struct afb_binding_data_v2 *data);
-extern void afb_ditf_rename(struct afb_ditf *ditf, const char *api);
-extern void afb_ditf_update_hook(struct afb_ditf *ditf);
-
diff --git a/src/afb-export.c b/src/afb-export.c
new file mode 100644 (file)
index 0000000..70a6377
--- /dev/null
@@ -0,0 +1,882 @@
+/*
+ * Copyright (C) 2016, 2017 "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 <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <json-c/json.h>
+
+#include <afb/afb-binding-v1.h>
+#include <afb/afb-binding-v2.h>
+
+#include "afb-api.h"
+#include "afb-apiset.h"
+#include "afb-common.h"
+#include "afb-cred.h"
+#include "afb-evt.h"
+#include "afb-export.h"
+#include "afb-hook.h"
+#include "afb-msg-json.h"
+#include "afb-session.h"
+#include "afb-xreq.h"
+#include "jobs.h"
+#include "verbose.h"
+
+extern struct afb_apiset *main_apiset;
+
+/*************************************************************************
+ * internal types and structures
+ ************************************************************************/
+
+enum afb_api_version
+{
+       Api_Version_None = 0,
+       Api_Version_1 = 1,
+       Api_Version_2 = 2,
+       Api_Version_3 = 3
+};
+
+enum afb_api_state
+{
+       Api_State_Pre_Init,
+       Api_State_Init,
+       Api_State_Run
+};
+
+struct afb_export
+{
+       /* name of the api */
+       char *apiname;
+
+       /* version of the api */
+       unsigned version: 4;
+
+       /* current state */
+       unsigned state: 4;
+
+       /* hooking flags */
+       int hookditf;
+       int hooksvc;
+       
+       /* session for service */
+       struct afb_session *session;
+
+       /* apiset for service */
+       struct afb_apiset *apiset;
+
+       /* event listener for service or NULL */
+       struct afb_evt_listener *listener;
+
+       /* event callback for service */
+       void (*on_event)(const char *event, struct json_object *object);
+
+       /* exported data */
+       union {
+               struct afb_binding_interface_v1 v1;
+               struct afb_binding_data_v2 *v2;
+       } export;
+};
+
+/*************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+                                           F R O M     D I T F
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************/
+
+/**********************************************
+* normal flow
+**********************************************/
+static void vverbose_cb(void *closure, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
+{
+       char *p;
+       struct afb_export *export = closure;
+
+       if (!fmt || vasprintf(&p, fmt, args) < 0)
+               vverbose(level, file, line, function, fmt, args);
+       else {
+               verbose(level, file, line, function, "[API %s] %s", export->apiname, p);
+               free(p);
+       }
+}
+
+static void old_vverbose_cb(void *closure, int level, const char *file, int line, const char *fmt, va_list args)
+{
+       vverbose_cb(closure, level, file, line, NULL, fmt, args);
+}
+
+static struct afb_event event_make_cb(void *closure, const char *name)
+{
+       size_t plen, nlen;
+       char *event;
+       struct afb_export *export = closure;
+
+       /* check daemon state */
+       if (export->state == Api_State_Pre_Init) {
+               ERROR("[API %s] Bad call to 'afb_daemon_event_make(%s)', must not be in PreInit", export->apiname, name);
+               errno = EINVAL;
+               return (struct afb_event){ .itf = NULL, .closure = NULL };
+       }
+
+       /* makes the event name */
+       plen = strlen(export->apiname);
+       nlen = strlen(name);
+       event = alloca(nlen + plen + 2);
+       memcpy(event, export->apiname, plen);
+       event[plen] = '/';
+       memcpy(event + plen + 1, name, nlen + 1);
+
+       /* create the event */
+       return afb_evt_create_event(event);
+}
+
+static int event_broadcast_cb(void *closure, const char *name, struct json_object *object)
+{
+       size_t plen, nlen;
+       char *event;
+       struct afb_export *export = closure;
+
+       /* check daemon state */
+       if (export->state == Api_State_Pre_Init) {
+               ERROR("[API %s] Bad call to 'afb_daemon_event_broadcast(%s, %s)', must not be in PreInit", export->apiname, name, json_object_to_json_string(object));
+               errno = EINVAL;
+               return 0;
+       }
+
+       /* makes the event name */
+       plen = strlen(export->apiname);
+       nlen = strlen(name);
+       event = alloca(nlen + plen + 2);
+       memcpy(event, export->apiname, plen);
+       event[plen] = '/';
+       memcpy(event + plen + 1, name, nlen + 1);
+
+       /* broadcast the event */
+       return afb_evt_broadcast(event, object);
+}
+
+static int rootdir_open_locale_cb(void *closure, const char *filename, int flags, const char *locale)
+{
+       return afb_common_rootdir_open_locale(filename, flags, locale);
+}
+
+static int queue_job_cb(void *closure, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
+{
+       return jobs_queue(group, timeout, callback, argument);
+}
+
+static struct afb_req unstore_req_cb(void *closure, struct afb_stored_req *sreq)
+{
+       return afb_xreq_unstore(sreq);
+}
+
+static int require_api_cb(void *closure, const char *name, int initialized)
+{
+       struct afb_export *export = closure;
+       if (export->state != Api_State_Init) {
+               ERROR("[API %s] Bad call to 'afb_daemon_require(%s, %d)', must be in Init", export->apiname, name, initialized);
+               errno = EINVAL;
+               return -1;
+       }
+       return -!(initialized ? afb_apiset_lookup_started : afb_apiset_lookup)(main_apiset, name, 1);
+}
+
+static int rename_api_cb(void *closure, const char *name)
+{
+       struct afb_export *export = closure;
+       if (export->state != Api_State_Pre_Init) {
+               ERROR("[API %s] Bad call to 'afb_daemon_rename(%s)', must be in PreInit", export->apiname, name);
+               errno = EINVAL;
+               return -1;
+       }
+       if (!afb_api_is_valid_name(name)) {
+               ERROR("[API %s] Can't rename to %s: bad API name", export->apiname, name);
+               errno = EINVAL;
+               return -1;
+       }
+       NOTICE("[API %s] renamed to [API %s]", export->apiname, name);
+       afb_export_rename(export, name);
+       return 0;
+}
+
+/**********************************************
+* hooked flow
+**********************************************/
+static void hooked_vverbose_cb(void *closure, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
+{
+       struct afb_export *export = closure;
+       va_list ap;
+       va_copy(ap, args);
+       vverbose_cb(closure, level, file, line, function, fmt, args);
+       afb_hook_ditf_vverbose(export, level, file, line, function, fmt, ap);
+       va_end(ap);
+}
+
+static void hooked_old_vverbose_cb(void *closure, int level, const char *file, int line, const char *fmt, va_list args)
+{
+       hooked_vverbose_cb(closure, level, file, line, NULL, fmt, args);
+}
+
+static struct afb_event hooked_event_make_cb(void *closure, const char *name)
+{
+       struct afb_export *export = closure;
+       struct afb_event r = event_make_cb(closure, name);
+       return afb_hook_ditf_event_make(export, name, r);
+}
+
+static int hooked_event_broadcast_cb(void *closure, const char *name, struct json_object *object)
+{
+       int r;
+       struct afb_export *export = closure;
+       json_object_get(object);
+       afb_hook_ditf_event_broadcast_before(export, name, json_object_get(object));
+       r = event_broadcast_cb(closure, name, object);
+       afb_hook_ditf_event_broadcast_after(export, name, object, r);
+       json_object_put(object);
+       return r;
+}
+
+static struct sd_event *hooked_get_event_loop(void *closure)
+{
+       struct afb_export *export = closure;
+       struct sd_event *r = afb_common_get_event_loop();
+       return afb_hook_ditf_get_event_loop(export, r);
+}
+
+static struct sd_bus *hooked_get_user_bus(void *closure)
+{
+       struct afb_export *export = closure;
+       struct sd_bus *r = afb_common_get_user_bus();
+       return afb_hook_ditf_get_user_bus(export, r);
+}
+
+static struct sd_bus *hooked_get_system_bus(void *closure)
+{
+       struct afb_export *export = closure;
+       struct sd_bus *r = afb_common_get_system_bus();
+       return afb_hook_ditf_get_system_bus(export, r);
+}
+
+static int hooked_rootdir_get_fd(void *closure)
+{
+       struct afb_export *export = closure;
+       int r = afb_common_rootdir_get_fd();
+       return afb_hook_ditf_rootdir_get_fd(export, r);
+}
+
+static int hooked_rootdir_open_locale_cb(void *closure, const char *filename, int flags, const char *locale)
+{
+       struct afb_export *export = closure;
+       int r = rootdir_open_locale_cb(closure, filename, flags, locale);
+       return afb_hook_ditf_rootdir_open_locale(export, filename, flags, locale, r);
+}
+
+static int hooked_queue_job_cb(void *closure, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
+{
+       struct afb_export *export = closure;
+       int r = queue_job_cb(closure, callback, argument, group, timeout);
+       return afb_hook_ditf_queue_job(export, callback, argument, group, timeout, r);
+}
+
+static struct afb_req hooked_unstore_req_cb(void *closure, struct afb_stored_req *sreq)
+{
+       struct afb_export *export = closure;
+       afb_hook_ditf_unstore_req(export, sreq);
+       return unstore_req_cb(closure, sreq);
+}
+
+static int hooked_require_api_cb(void *closure, const char *name, int initialized)
+{
+       int result;
+       struct afb_export *export = closure;
+       afb_hook_ditf_require_api(export, name, initialized);
+       result = require_api_cb(closure, name, initialized);
+       return afb_hook_ditf_require_api_result(export, name, initialized, result);
+}
+
+static int hooked_rename_api_cb(void *closure, const char *name)
+{
+       struct afb_export *export = closure;
+       const char *oldname = export->apiname;
+       int result = rename_api_cb(closure, name);
+       return afb_hook_ditf_rename_api(export, oldname, name, result);
+}
+
+/**********************************************
+* vectors
+**********************************************/
+static const struct afb_daemon_itf daemon_itf = {
+       .vverbose_v1 = old_vverbose_cb,
+       .vverbose_v2 = vverbose_cb,
+       .event_make = event_make_cb,
+       .event_broadcast = event_broadcast_cb,
+       .get_event_loop = afb_common_get_event_loop,
+       .get_user_bus = afb_common_get_user_bus,
+       .get_system_bus = afb_common_get_system_bus,
+       .rootdir_get_fd = afb_common_rootdir_get_fd,
+       .rootdir_open_locale = rootdir_open_locale_cb,
+       .queue_job = queue_job_cb,
+       .unstore_req = unstore_req_cb,
+       .require_api = require_api_cb,
+       .rename_api = rename_api_cb
+};
+
+static const struct afb_daemon_itf hooked_daemon_itf = {
+       .vverbose_v1 = hooked_old_vverbose_cb,
+       .vverbose_v2 = hooked_vverbose_cb,
+       .event_make = hooked_event_make_cb,
+       .event_broadcast = hooked_event_broadcast_cb,
+       .get_event_loop = hooked_get_event_loop,
+       .get_user_bus = hooked_get_user_bus,
+       .get_system_bus = hooked_get_system_bus,
+       .rootdir_get_fd = hooked_rootdir_get_fd,
+       .rootdir_open_locale = hooked_rootdir_open_locale_cb,
+       .queue_job = hooked_queue_job_cb,
+       .unstore_req = hooked_unstore_req_cb,
+       .require_api = hooked_require_api_cb,
+       .rename_api = hooked_rename_api_cb
+};
+
+
+/*************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+                                           F R O M     S V C
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************/
+
+/* the common session for services sharing their session */
+static struct afb_session *common_session;
+
+/*************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+                                           F R O M     S V C
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************/
+
+/*
+ * Structure for requests initiated by the service
+ */
+struct call_req
+{
+       struct afb_xreq xreq;
+
+       struct afb_export *export;
+
+       /* the args */
+       void (*callback)(void*, int, struct json_object*);
+       void *closure;
+
+       /* sync */
+       struct jobloop *jobloop;
+       struct json_object *result;
+       int status;
+       int async;
+};
+
+/*
+ * destroys the call_req
+ */
+static void callreq_destroy(struct afb_xreq *xreq)
+{
+       struct call_req *callreq = CONTAINER_OF_XREQ(struct call_req, xreq);
+
+       afb_context_disconnect(&callreq->xreq.context);
+       json_object_put(callreq->xreq.json);
+       afb_cred_unref(callreq->xreq.cred);
+       free(callreq);
+}
+
+static void callreq_reply(struct afb_xreq *xreq, int status, json_object *obj)
+{
+       struct call_req *callreq = CONTAINER_OF_XREQ(struct call_req, xreq);
+       if (callreq->callback)
+               callreq->callback(callreq->closure, status, obj);
+       json_object_put(obj);
+}
+
+static void callreq_sync_leave(struct call_req *callreq)
+{
+       struct jobloop *jobloop = callreq->jobloop;
+
+       if (jobloop) {
+               callreq->jobloop = NULL;
+               jobs_leave(jobloop);
+       }
+}
+
+static void callreq_reply_sync(struct afb_xreq *xreq, int status, json_object *obj)
+{
+       struct call_req *callreq = CONTAINER_OF_XREQ(struct call_req, xreq);
+       callreq->status = status;
+       callreq->result = obj;
+       callreq_sync_leave(callreq);
+}
+
+static void callreq_sync_enter(int signum, void *closure, struct jobloop *jobloop)
+{
+       struct call_req *callreq = closure;
+
+       if (!signum) {
+               callreq->jobloop = jobloop;
+               afb_xreq_process(&callreq->xreq, callreq->export->apiset);
+       } else {
+               callreq->result = afb_msg_json_internal_error();
+               callreq->status = -1;
+               callreq_sync_leave(callreq);
+       }
+}
+
+/* interface for requests of services */
+const struct afb_xreq_query_itf afb_export_xreq_itf = {
+       .unref = callreq_destroy,
+       .reply = callreq_reply
+};
+
+/* interface for requests of services */
+const struct afb_xreq_query_itf afb_export_xreq_sync_itf = {
+       .unref = callreq_destroy,
+       .reply = callreq_reply_sync
+};
+
+/*
+ * create an call_req
+ */
+static struct call_req *callreq_create(struct afb_export *export, const char *api, const char *verb, struct json_object *args, const struct afb_xreq_query_itf *itf)
+{
+       struct call_req *callreq;
+       size_t lenapi, lenverb;
+       char *copy;
+
+       /* allocates the request */
+       lenapi = 1 + strlen(api);
+       lenverb = 1 + strlen(verb);
+       callreq = malloc(lenapi + lenverb + sizeof *callreq);
+       if (callreq != NULL) {
+               /* initialises the request */
+               afb_xreq_init(&callreq->xreq, itf);
+               afb_context_init(&callreq->xreq.context, export->session, NULL);
+               callreq->xreq.context.validated = 1;
+               copy = (char*)&callreq[1];
+               memcpy(copy, api, lenapi);
+               callreq->xreq.api = copy;
+               copy = &copy[lenapi];
+               memcpy(copy, verb, lenverb);
+               callreq->xreq.verb = copy;
+               callreq->xreq.listener = export->listener;
+               callreq->xreq.json = args;
+               callreq->export = export;
+       }
+       return callreq;
+}
+
+/*
+ * Initiates a call for the service
+ */
+static void svc_call(void *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cbclosure)
+{
+       struct afb_export *export = closure;
+       struct call_req *callreq;
+       struct json_object *ierr;
+
+       /* allocates the request */
+       callreq = callreq_create(export, api, verb, args, &afb_export_xreq_itf);
+       if (callreq == NULL) {
+               ERROR("out of memory");
+               json_object_put(args);
+               ierr = afb_msg_json_internal_error();
+               if (callback)
+                       callback(cbclosure, -1, ierr);
+               json_object_put(ierr);
+               return;
+       }
+
+       /* initialises the request */
+       callreq->jobloop = NULL;
+       callreq->callback = callback;
+       callreq->closure = cbclosure;
+       callreq->async = 1;
+
+       /* terminates and frees ressources if needed */
+       afb_xreq_process(&callreq->xreq, export->apiset);
+}
+
+static int svc_call_sync(void *closure, const char *api, const char *verb, struct json_object *args,
+                               struct json_object **result)
+{
+       struct afb_export *export = closure;
+       struct call_req *callreq;
+       struct json_object *resu;
+       int rc;
+
+       /* allocates the request */
+       callreq = callreq_create(export, api, verb, args, &afb_export_xreq_sync_itf);
+       if (callreq == NULL) {
+               ERROR("out of memory");
+               errno = ENOMEM;
+               json_object_put(args);
+               resu = afb_msg_json_internal_error();
+               rc = -1;
+       } else {
+               /* initialises the request */
+               callreq->jobloop = NULL;
+               callreq->callback = NULL;
+               callreq->result = NULL;
+               callreq->status = 0;
+               callreq->async = 0;
+               afb_xreq_addref(&callreq->xreq);
+               rc = jobs_enter(NULL, 0, callreq_sync_enter, callreq);
+               if (rc >= 0)
+                       rc = callreq->status;
+               resu = (rc >= 0 || callreq->result) ? callreq->result : afb_msg_json_internal_error();
+               afb_xreq_unref(&callreq->xreq);
+       }
+       if (result)
+               *result = resu;
+       else
+               json_object_put(resu);
+       return rc;
+}
+
+struct hooked_call
+{
+       struct afb_export *export;
+       void (*callback)(void*, int, struct json_object*);
+       void *cbclosure;
+};
+
+static void svc_hooked_call_result(void *closure, int status, struct json_object *result)
+{
+       struct hooked_call *hc = closure;
+       afb_hook_svc_call_result(hc->export, status, result);
+       hc->callback(hc->cbclosure, status, result);
+       free(hc);
+}
+
+static void svc_hooked_call(void *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cbclosure)
+{
+       struct afb_export *export = closure;
+       struct hooked_call *hc;
+
+       if (export->hooksvc & afb_hook_flag_svc_call)
+               afb_hook_svc_call(export, api, verb, args);
+
+       if (export->hooksvc & afb_hook_flag_svc_call_result) {
+               hc = malloc(sizeof *hc);
+               if (!hc)
+                       WARNING("allocation failed");
+               else {
+                       hc->export = export;
+                       hc->callback = callback;
+                       hc->cbclosure = cbclosure;
+                       callback = svc_hooked_call_result;
+                       cbclosure = hc;
+               }
+       }
+       svc_call(closure, api, verb, args, callback, cbclosure);
+}
+
+static int svc_hooked_call_sync(void *closure, const char *api, const char *verb, struct json_object *args,
+                               struct json_object **result)
+{
+       struct afb_export *export = closure;
+       struct json_object *resu;
+       int rc;
+
+       if (export->hooksvc & afb_hook_flag_svc_callsync)
+               afb_hook_svc_callsync(export, api, verb, args);
+
+       rc = svc_call_sync(closure, api, verb, args, &resu);
+
+       if (export->hooksvc & afb_hook_flag_svc_callsync_result)
+               afb_hook_svc_callsync_result(export, rc, resu);
+
+       if (result)
+               *result = resu;
+       else
+               json_object_put(resu);
+
+       return rc;
+}
+
+/* the interface for services */
+static const struct afb_service_itf service_itf = {
+       .call = svc_call,
+       .call_sync = svc_call_sync
+};
+
+/* the interface for services */
+static const struct afb_service_itf hooked_service_itf = {
+       .call = svc_hooked_call,
+       .call_sync = svc_hooked_call_sync
+};
+
+/*************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+                                           F R O M     S V C
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************/
+
+/*
+ * Propagates the event to the service
+ */
+static void export_on_event(void *closure, const char *event, int eventid, struct json_object *object)
+{
+       struct afb_export *export = closure;
+
+       if (export->hooksvc & afb_hook_flag_svc_on_event_before)
+               afb_hook_svc_on_event_before(export, event, eventid, object);
+       export->on_event(event, object);
+       if (export->hooksvc & afb_hook_flag_svc_on_event_after)
+               afb_hook_svc_on_event_after(export, event, eventid, object);
+       json_object_put(object);
+}
+
+/* the interface for events */
+static const struct afb_evt_itf evt_itf = {
+       .broadcast = export_on_event,
+       .push = export_on_event
+};
+
+/*************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+                                           M E R G E D
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************
+ *************************************************************************************************************/
+
+static struct afb_export *create(const char *apiname, enum afb_api_version version)
+{
+       struct afb_export *export;
+
+       /* session shared with other exports */
+       if (common_session == NULL) {
+               common_session = afb_session_create (NULL, 0);
+               if (common_session == NULL)
+                       return NULL;
+       }
+       export = calloc(1, sizeof *export);
+       if (!export)
+               errno = ENOMEM;
+       else {
+               memset(export, 0, sizeof *export);
+               export->apiname = strdup(apiname);
+               export->version = version;
+               export->state = Api_State_Pre_Init;
+               export->session = afb_session_addref(common_session);
+               export->apiset = afb_apiset_addref(main_apiset);
+       }
+       return export;
+}
+
+void afb_export_destroy(struct afb_export *export)
+{
+       if (export) {
+               if (export->listener != NULL)
+                       afb_evt_listener_unref(export->listener);
+               afb_session_unref(export->session);
+               afb_apiset_unref(export->apiset);
+               free(export->apiname);
+               free(export);
+       }
+}
+
+struct afb_export *afb_export_create_v1(const char *apiname)
+{
+       struct afb_export *export = create(apiname, Api_Version_1);
+       if (export) {
+               export->export.v1.verbosity = verbosity;
+               export->export.v1.mode = AFB_MODE_LOCAL;
+               export->export.v1.daemon.closure = export;
+               afb_export_update_hook(export);
+       }
+       return export;
+}
+
+struct afb_export *afb_export_create_v2(const char *apiname, struct afb_binding_data_v2 *data)
+{
+       struct afb_export *export = create(apiname, Api_Version_2);
+       if (export) {
+               export->export.v2 = data;
+               data->daemon.closure = export;
+               data->service.closure = export;
+               afb_export_update_hook(export);
+       }
+       return export;
+}
+
+void afb_export_rename(struct afb_export *export, const char *apiname)
+{
+       free(export->apiname);
+       export->apiname = strdup(apiname);
+       afb_export_update_hook(export);
+}
+
+const char *afb_export_apiname(const struct afb_export *export)
+{
+       return export->apiname;
+}
+
+void afb_export_update_hook(struct afb_export *export)
+{
+       export->hookditf = afb_hook_flags_ditf(export->apiname);
+       export->hooksvc = afb_hook_flags_svc(export->apiname);
+       switch (export->version) {
+       case Api_Version_1:
+               export->export.v1.daemon.itf = export->hookditf ? &hooked_daemon_itf : &daemon_itf;
+               break;
+       default:
+       case Api_Version_2:
+               export->export.v2->daemon.itf = export->hookditf ? &hooked_daemon_itf : &daemon_itf;
+               export->export.v2->service.itf = export->hooksvc ? &hooked_service_itf : &service_itf;
+               break;
+       }
+}
+
+struct afb_binding_interface_v1 *afb_export_get_interface_v1(struct afb_export *export)
+{
+       return export->version == Api_Version_1 ? &export->export.v1 : NULL;
+}
+
+int afb_export_unshare_session(struct afb_export *export)
+{
+       if (export->session == common_session) {
+               export->session = afb_session_create (NULL, 0);
+               if (export->session)
+                       afb_session_unref(common_session);
+               else {
+                       export->session = common_session;
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+void afb_export_set_apiset(struct afb_export *export, struct afb_apiset *apiset)
+{
+       struct afb_apiset *prvset = export->apiset;
+       export->apiset = afb_apiset_addref(apiset);
+       afb_apiset_unref(prvset);
+}
+       
+/*
+ * Creates a new service
+ */
+int afb_export_handle_events(struct afb_export *export, void (*on_event)(const char *event, struct json_object *object))
+{
+       if (on_event != export->on_event) {
+               if (!on_event) {
+                       afb_evt_listener_unref(export->listener);
+                       export->listener = NULL;
+               } else if (!export->listener) {
+                       export->listener = afb_evt_listener_create(&evt_itf, export);
+                       if (export->listener == NULL)
+                               return -1;
+               }
+               export->on_event = on_event;
+       }
+       return 0;
+}
+
+
+
+int afb_export_is_started(const struct afb_export *export)
+{
+       return export->state != Api_State_Pre_Init;
+}
+
+
+/*
+ * Starts a new service (v1)
+ */
+struct afb_binding_v1 *afb_export_register_v1(struct afb_export *export, struct afb_binding_v1 *(*regfun)(const struct afb_binding_interface_v1*))
+{
+       return regfun(&export->export.v1);
+       
+}
+
+int afb_export_start_v1(struct afb_export *export, int (*start)(struct afb_service))
+{
+       int rc;
+       struct afb_service svc = { .itf = &hooked_service_itf, .closure = export };
+
+       if (export->hooksvc & afb_hook_flag_svc_start_before)
+               afb_hook_svc_start_before(export);
+       export->state = Api_State_Init;
+       rc = start ? start(svc) : 0;
+       export->state = Api_State_Run;
+       if (export->hooksvc & afb_hook_flag_svc_start_after)
+               afb_hook_svc_start_after(export, rc);
+       return rc;
+}
+
+/*
+ * Starts a new service (v2)
+ */
+int afb_export_start_v2(struct afb_export *export, int (*start)())
+{
+       int rc;
+
+       if (export->hooksvc & afb_hook_flag_svc_start_before)
+               afb_hook_svc_start_before(export);
+       export->state = Api_State_Init;
+       rc = start ? start() : 0;
+       export->state = Api_State_Run;
+       if (export->hooksvc & afb_hook_flag_svc_start_after)
+               afb_hook_svc_start_after(export, rc);
+       if (rc >= 0)
+               export->state = Api_State_Run;
+       return rc;
+}
+
+int afb_export_verbosity_get(const struct afb_export *export)
+{
+       switch (export->version) {
+       case Api_Version_1: return export->export.v1.verbosity;
+       case Api_Version_2: return export->export.v2->verbosity;
+       }
+       return verbosity;
+}
+
+void afb_export_verbosity_set(struct afb_export *export, int level)
+{
+       switch (export->version) {
+       case Api_Version_1: export->export.v1.verbosity = level; break;
+       case Api_Version_2: export->export.v2->verbosity = level; break;
+       }
+}
+
diff --git a/src/afb-export.h b/src/afb-export.h
new file mode 100644 (file)
index 0000000..96ccb93
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016, 2017 "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 afb_export;
+struct afb_apiset;
+
+struct afb_service;
+struct afb_binding_data_v2;
+struct afb_binding_interface_v1;
+
+extern struct afb_export *afb_export_create_v1(const char *apiname);
+extern struct afb_export *afb_export_create_v2(const char *apiname, struct afb_binding_data_v2 *data);
+extern void afb_export_destroy(struct afb_export *export);
+
+extern const char *afb_export_apiname(const struct afb_export *export);
+extern void afb_export_rename(struct afb_export *export, const char *apiname);
+extern void afb_export_update_hook(struct afb_export *export);
+
+extern int afb_export_unshare_session(struct afb_export *export);
+extern void afb_export_set_apiset(struct afb_export *export, struct afb_apiset *apiset);
+       
+extern int afb_export_is_started(const struct afb_export *export);
+extern struct afb_binding_v1 *afb_export_register_v1(struct afb_export *export, struct afb_binding_v1 *(*regfun)(const struct afb_binding_interface_v1*));
+extern int afb_export_start_v1(struct afb_export *export, int (*start)(struct afb_service));
+extern int afb_export_start_v2(struct afb_export *export, int (*start)());
+
+extern int afb_export_handle_events(struct afb_export *export, void (*on_event)(const char *event, struct json_object *object));
+
+extern int afb_export_verbosity_get(const struct afb_export *export);
+extern void afb_export_verbosity_set(struct afb_export *export, int level);
+
index a1ecea6..92a4c82 100644 (file)
@@ -36,8 +36,7 @@
 #include "afb-session.h"
 #include "afb-cred.h"
 #include "afb-xreq.h"
-#include "afb-ditf.h"
-#include "afb-svc.h"
+#include "afb-export.h"
 #include "afb-evt.h"
 #include "verbose.h"
 
@@ -56,7 +55,7 @@ struct afb_hook_xreq {
 };
 
 /**
- * Definition of a hook for ditf
+ * Definition of a hook for export
  */
 struct afb_hook_ditf {
        struct afb_hook_ditf *next; /**< next hook */
@@ -68,7 +67,7 @@ struct afb_hook_ditf {
 };
 
 /**
- * Definition of a hook for svc
+ * Definition of a hook for export
  */
 struct afb_hook_svc {
        struct afb_hook_svc *next; /**< next hook */
@@ -108,10 +107,10 @@ static pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
 /* list of hooks for xreq */
 static struct afb_hook_xreq *list_of_xreq_hooks = NULL;
 
-/* list of hooks for ditf */
+/* list of hooks for export */
 static struct afb_hook_ditf *list_of_ditf_hooks = NULL;
 
-/* list of hooks for svc */
+/* list of hooks for export */
 static struct afb_hook_svc *list_of_svc_hooks = NULL;
 
 /* list of hooks for evt */
@@ -650,40 +649,40 @@ void afb_hook_unref_xreq(struct afb_hook_xreq *hook)
  * section: default callbacks for tracing daemon interface
  *****************************************************************************/
 
-static void _hook_ditf_(const struct afb_ditf *ditf, const char *format, ...)
+static void _hook_ditf_(const struct afb_export *export, const char *format, ...)
 {
        va_list ap;
        va_start(ap, format);
-       _hook_("ditf-%s", format, ap, ditf->api);
+       _hook_("export-%s", format, ap, afb_export_apiname(export));
        va_end(ap);
 }
 
-static void hook_ditf_event_broadcast_before_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, struct json_object *object)
+static void hook_ditf_event_broadcast_before_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, struct json_object *object)
 {
-       _hook_ditf_(ditf, "event_broadcast.before(%s, %s)....", name, json_object_to_json_string(object));
+       _hook_ditf_(export, "event_broadcast.before(%s, %s)....", name, json_object_to_json_string(object));
 }
 
-static void hook_ditf_event_broadcast_after_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, struct json_object *object, int result)
+static void hook_ditf_event_broadcast_after_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, struct json_object *object, int result)
 {
-       _hook_ditf_(ditf, "event_broadcast.after(%s, %s) -> %d", name, json_object_to_json_string(object), result);
+       _hook_ditf_(export, "event_broadcast.after(%s, %s) -> %d", name, json_object_to_json_string(object), result);
 }
 
-static void hook_ditf_get_event_loop_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct sd_event *result)
+static void hook_ditf_get_event_loop_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct sd_event *result)
 {
-       _hook_ditf_(ditf, "get_event_loop() -> %p", result);
+       _hook_ditf_(export, "get_event_loop() -> %p", result);
 }
 
-static void hook_ditf_get_user_bus_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct sd_bus *result)
+static void hook_ditf_get_user_bus_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct sd_bus *result)
 {
-       _hook_ditf_(ditf, "get_user_bus() -> %p", result);
+       _hook_ditf_(export, "get_user_bus() -> %p", result);
 }
 
-static void hook_ditf_get_system_bus_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct sd_bus *result)
+static void hook_ditf_get_system_bus_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct sd_bus *result)
 {
-       _hook_ditf_(ditf, "get_system_bus() -> %p", result);
+       _hook_ditf_(export, "get_system_bus() -> %p", result);
 }
 
-static void hook_ditf_vverbose_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
+static void hook_ditf_vverbose_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
 {
        int len;
        char *msg;
@@ -694,67 +693,67 @@ static void hook_ditf_vverbose_cb(void *closure, const struct afb_hookid *hookid
        va_end(ap);
 
        if (len < 0)
-               _hook_ditf_(ditf, "vverbose(%d, %s, %d, %s) -> %s ? ? ?", level, file, line, function, fmt);
+               _hook_ditf_(export, "vverbose(%d, %s, %d, %s) -> %s ? ? ?", level, file, line, function, fmt);
        else {
-               _hook_ditf_(ditf, "vverbose(%d, %s, %d, %s) -> %s", level, file, line, function, msg);
+               _hook_ditf_(export, "vverbose(%d, %s, %d, %s) -> %s", level, file, line, function, msg);
                free(msg);
        }
 }
 
-static void hook_ditf_event_make_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, struct afb_event result)
+static void hook_ditf_event_make_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, struct afb_event result)
 {
-       _hook_ditf_(ditf, "event_make(%s) -> %s:%d", name, afb_evt_event_name(result), afb_evt_event_id(result));
+       _hook_ditf_(export, "event_make(%s) -> %s:%d", name, afb_evt_event_name(result), afb_evt_event_id(result));
 }
 
-static void hook_ditf_rootdir_get_fd_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, int result)
+static void hook_ditf_rootdir_get_fd_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int result)
 {
        char path[PATH_MAX];
        if (result < 0)
-               _hook_ditf_(ditf, "rootdir_get_fd() -> %d, %m", result);
+               _hook_ditf_(export, "rootdir_get_fd() -> %d, %m", result);
        else {
                sprintf(path, "/proc/self/fd/%d", result);
                readlink(path, path, sizeof path);
-               _hook_ditf_(ditf, "rootdir_get_fd() -> %d = %s", result, path);
+               _hook_ditf_(export, "rootdir_get_fd() -> %d = %s", result, path);
        }
 }
 
-static void hook_ditf_rootdir_open_locale_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *filename, int flags, const char *locale, int result)
+static void hook_ditf_rootdir_open_locale_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *filename, int flags, const char *locale, int result)
 {
        char path[PATH_MAX];
        if (!locale)
                locale = "(null)";
        if (result < 0)
-               _hook_ditf_(ditf, "rootdir_open_locale(%s, %d, %s) -> %d, %m", filename, flags, locale, result);
+               _hook_ditf_(export, "rootdir_open_locale(%s, %d, %s) -> %d, %m", filename, flags, locale, result);
        else {
                sprintf(path, "/proc/self/fd/%d", result);
                readlink(path, path, sizeof path);
-               _hook_ditf_(ditf, "rootdir_open_locale(%s, %d, %s) -> %d = %s", filename, flags, locale, result, path);
+               _hook_ditf_(export, "rootdir_open_locale(%s, %d, %s) -> %d = %s", filename, flags, locale, result, path);
        }
 }
 
-static void hook_ditf_queue_job_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result)
+static void hook_ditf_queue_job_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result)
 {
-       _hook_ditf_(ditf, "queue_job(%p, %p, %p, %d) -> %d", callback, argument, group, timeout, result);
+       _hook_ditf_(export, "queue_job(%p, %p, %p, %d) -> %d", callback, argument, group, timeout, result);
 }
 
-static void hook_ditf_unstore_req_cb(void *closure, const struct afb_hookid *hookid,  const struct afb_ditf *ditf, struct afb_stored_req *sreq)
+static void hook_ditf_unstore_req_cb(void *closure, const struct afb_hookid *hookid,  const struct afb_export *export, struct afb_stored_req *sreq)
 {
-       _hook_ditf_(ditf, "unstore_req(%p)", sreq);
+       _hook_ditf_(export, "unstore_req(%p)", sreq);
 }
 
-static void hook_ditf_require_api_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, int initialized)
+static void hook_ditf_require_api_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, int initialized)
 {
-       _hook_ditf_(ditf, "require_api(%s, %d)...", name, initialized);
+       _hook_ditf_(export, "require_api(%s, %d)...", name, initialized);
 }
 
-static void hook_ditf_require_api_result_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, int initialized, int result)
+static void hook_ditf_require_api_result_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, int initialized, int result)
 {
-       _hook_ditf_(ditf, "...require_api(%s, %d) -> %d", name, initialized, result);
+       _hook_ditf_(export, "...require_api(%s, %d) -> %d", name, initialized, result);
 }
 
-static void hook_ditf_rename_api_cb(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *oldname, const char *newname, int result)
+static void hook_ditf_rename_api_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *oldname, const char *newname, int result)
 {
-       _hook_ditf_(ditf, "rename_api(%s -> %s) -> %d", oldname, newname, result);
+       _hook_ditf_(export, "rename_api(%s -> %s) -> %d", oldname, newname, result);
 }
 
 static struct afb_hook_ditf_itf hook_ditf_default_itf = {
@@ -775,107 +774,108 @@ static struct afb_hook_ditf_itf hook_ditf_default_itf = {
 };
 
 /******************************************************************************
- * section: hooks for tracing daemon interface (ditf)
+ * section: hooks for tracing daemon interface (export)
  *****************************************************************************/
 
 #define _HOOK_DITF_(what,...)   \
        struct afb_hook_ditf *hook; \
        struct afb_hookid hookid; \
+       const char *apiname = afb_export_apiname(export); \
        pthread_rwlock_rdlock(&rwlock); \
        init_hookid(&hookid); \
        hook = list_of_ditf_hooks; \
        while (hook) { \
                if (hook->itf->hook_ditf_##what \
                 && (hook->flags & afb_hook_flag_ditf_##what) != 0 \
-                && (!hook->api || !strcasecmp(hook->api, ditf->api))) { \
+                && (!hook->api || !strcasecmp(hook->api, apiname))) { \
                        hook->itf->hook_ditf_##what(hook->closure, &hookid, __VA_ARGS__); \
                } \
                hook = hook->next; \
        } \
        pthread_rwlock_unlock(&rwlock);
 
-void afb_hook_ditf_event_broadcast_before(const struct afb_ditf *ditf, const char *name, struct json_object *object)
+void afb_hook_ditf_event_broadcast_before(const struct afb_export *export, const char *name, struct json_object *object)
 {
-       _HOOK_DITF_(event_broadcast_before, ditf, name, object);
+       _HOOK_DITF_(event_broadcast_before, export, name, object);
 }
 
-int afb_hook_ditf_event_broadcast_after(const struct afb_ditf *ditf, const char *name, struct json_object *object, int result)
+int afb_hook_ditf_event_broadcast_after(const struct afb_export *export, const char *name, struct json_object *object, int result)
 {
-       _HOOK_DITF_(event_broadcast_after, ditf, name, object, result);
+       _HOOK_DITF_(event_broadcast_after, export, name, object, result);
        return result;
 }
 
-struct sd_event *afb_hook_ditf_get_event_loop(const struct afb_ditf *ditf, struct sd_event *result)
+struct sd_event *afb_hook_ditf_get_event_loop(const struct afb_export *export, struct sd_event *result)
 {
-       _HOOK_DITF_(get_event_loop, ditf, result);
+       _HOOK_DITF_(get_event_loop, export, result);
        return result;
 }
 
-struct sd_bus *afb_hook_ditf_get_user_bus(const struct afb_ditf *ditf, struct sd_bus *result)
+struct sd_bus *afb_hook_ditf_get_user_bus(const struct afb_export *export, struct sd_bus *result)
 {
-       _HOOK_DITF_(get_user_bus, ditf, result);
+       _HOOK_DITF_(get_user_bus, export, result);
        return result;
 }
 
-struct sd_bus *afb_hook_ditf_get_system_bus(const struct afb_ditf *ditf, struct sd_bus *result)
+struct sd_bus *afb_hook_ditf_get_system_bus(const struct afb_export *export, struct sd_bus *result)
 {
-       _HOOK_DITF_(get_system_bus, ditf, result);
+       _HOOK_DITF_(get_system_bus, export, result);
        return result;
 }
 
-void afb_hook_ditf_vverbose(const struct afb_ditf *ditf, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
+void afb_hook_ditf_vverbose(const struct afb_export *export, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
 {
-       _HOOK_DITF_(vverbose, ditf, level, file, line, function, fmt, args);
+       _HOOK_DITF_(vverbose, export, level, file, line, function, fmt, args);
 }
 
-struct afb_event afb_hook_ditf_event_make(const struct afb_ditf *ditf, const char *name, struct afb_event result)
+struct afb_event afb_hook_ditf_event_make(const struct afb_export *export, const char *name, struct afb_event result)
 {
-       _HOOK_DITF_(event_make, ditf, name, result);
+       _HOOK_DITF_(event_make, export, name, result);
        return result;
 }
 
-int afb_hook_ditf_rootdir_get_fd(const struct afb_ditf *ditf, int result)
+int afb_hook_ditf_rootdir_get_fd(const struct afb_export *export, int result)
 {
-       _HOOK_DITF_(rootdir_get_fd, ditf, result);
+       _HOOK_DITF_(rootdir_get_fd, export, result);
        return result;
 }
 
-int afb_hook_ditf_rootdir_open_locale(const struct afb_ditf *ditf, const char *filename, int flags, const char *locale, int result)
+int afb_hook_ditf_rootdir_open_locale(const struct afb_export *export, const char *filename, int flags, const char *locale, int result)
 {
-       _HOOK_DITF_(rootdir_open_locale, ditf, filename, flags, locale, result);
+       _HOOK_DITF_(rootdir_open_locale, export, filename, flags, locale, result);
        return result;
 }
 
-int afb_hook_ditf_queue_job(const struct afb_ditf *ditf, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result)
+int afb_hook_ditf_queue_job(const struct afb_export *export, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result)
 {
-       _HOOK_DITF_(queue_job, ditf, callback, argument, group, timeout, result);
+       _HOOK_DITF_(queue_job, export, callback, argument, group, timeout, result);
        return result;
 }
 
-void afb_hook_ditf_unstore_req(const struct afb_ditf *ditf, struct afb_stored_req *sreq)
+void afb_hook_ditf_unstore_req(const struct afb_export *export, struct afb_stored_req *sreq)
 {
-       _HOOK_DITF_(unstore_req, ditf, sreq);
+       _HOOK_DITF_(unstore_req, export, sreq);
 }
 
-void afb_hook_ditf_require_api(const struct afb_ditf *ditf, const char *name, int initialized)
+void afb_hook_ditf_require_api(const struct afb_export *export, const char *name, int initialized)
 {
-       _HOOK_DITF_(require_api, ditf, name, initialized);
+       _HOOK_DITF_(require_api, export, name, initialized);
 }
 
-int afb_hook_ditf_require_api_result(const struct afb_ditf *ditf, const char *name, int initialized, int result)
+int afb_hook_ditf_require_api_result(const struct afb_export *export, const char *name, int initialized, int result)
 {
-       _HOOK_DITF_(require_api_result, ditf, name, initialized, result);
+       _HOOK_DITF_(require_api_result, export, name, initialized, result);
        return result;
 }
 
-int afb_hook_ditf_rename_api(const struct afb_ditf *ditf, const char *oldname, const char *newname, int result)
+int afb_hook_ditf_rename_api(const struct afb_export *export, const char *oldname, const char *newname, int result)
 {
-       _HOOK_DITF_(rename_api, ditf, oldname, newname, result);
+       _HOOK_DITF_(rename_api, export, oldname, newname, result);
        return result;
 }
 
 /******************************************************************************
- * section: hooking ditf
+ * section: hooking export
  *****************************************************************************/
 
 int afb_hook_flags_ditf(const char *api)
@@ -961,55 +961,55 @@ void afb_hook_unref_ditf(struct afb_hook_ditf *hook)
 }
 
 /******************************************************************************
- * section: default callbacks for tracing service interface (svc)
+ * section: default callbacks for tracing service interface (export)
  *****************************************************************************/
 
-static void _hook_svc_(const struct afb_svc *svc, const char *format, ...)
+static void _hook_svc_(const struct afb_export *export, const char *format, ...)
 {
        va_list ap;
        va_start(ap, format);
-       _hook_("svc-%s", format, ap, svc->api);
+       _hook_("export-%s", format, ap, afb_export_apiname(export));
        va_end(ap);
 }
 
-static void hook_svc_start_before_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc)
+static void hook_svc_start_before_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export)
 {
-       _hook_svc_(svc, "start.before");
+       _hook_svc_(export, "start.before");
 }
 
-static void hook_svc_start_after_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, int status)
+static void hook_svc_start_after_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int status)
 {
-       _hook_svc_(svc, "start.after -> %d", status);
+       _hook_svc_(export, "start.after -> %d", status);
 }
 
-static void hook_svc_on_event_before_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *event, int eventid, struct json_object *object)
+static void hook_svc_on_event_before_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int eventid, struct json_object *object)
 {
-       _hook_svc_(svc, "on_event.before(%s, %d, %s)", event, eventid, json_object_to_json_string(object));
+       _hook_svc_(export, "on_event.before(%s, %d, %s)", event, eventid, json_object_to_json_string(object));
 }
 
-static void hook_svc_on_event_after_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *event, int eventid, struct json_object *object)
+static void hook_svc_on_event_after_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int eventid, struct json_object *object)
 {
-       _hook_svc_(svc, "on_event.after(%s, %d, %s)", event, eventid, json_object_to_json_string(object));
+       _hook_svc_(export, "on_event.after(%s, %d, %s)", event, eventid, json_object_to_json_string(object));
 }
 
-static void hook_svc_call_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args)
+static void hook_svc_call_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *api, const char *verb, struct json_object *args)
 {
-       _hook_svc_(svc, "call(%s/%s, %s) ...", api, verb, json_object_to_json_string(args));
+       _hook_svc_(export, "call(%s/%s, %s) ...", api, verb, json_object_to_json_string(args));
 }
 
-static void hook_svc_call_result_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, int status, struct json_object *result)
+static void hook_svc_call_result_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int status, struct json_object *result)
 {
-       _hook_svc_(svc, "    ...call... -> %d: %s", status, json_object_to_json_string(result));
+       _hook_svc_(export, "    ...call... -> %d: %s", status, json_object_to_json_string(result));
 }
 
-static void hook_svc_callsync_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args)
+static void hook_svc_callsync_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *api, const char *verb, struct json_object *args)
 {
-       _hook_svc_(svc, "callsync(%s/%s, %s) ...", api, verb, json_object_to_json_string(args));
+       _hook_svc_(export, "callsync(%s/%s, %s) ...", api, verb, json_object_to_json_string(args));
 }
 
-static void hook_svc_callsync_result_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, int status, struct json_object *result)
+static void hook_svc_callsync_result_default_cb(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int status, struct json_object *result)
 {
-       _hook_svc_(svc, "    ...callsync... -> %d: %s", status, json_object_to_json_string(result));
+       _hook_svc_(export, "    ...callsync... -> %d: %s", status, json_object_to_json_string(result));
 }
 
 static struct afb_hook_svc_itf hook_svc_default_itf = {
@@ -1024,69 +1024,70 @@ static struct afb_hook_svc_itf hook_svc_default_itf = {
 };
 
 /******************************************************************************
- * section: hooks for tracing service interface (svc)
+ * section: hooks for tracing service interface (export)
  *****************************************************************************/
 
 #define _HOOK_SVC_(what,...)   \
        struct afb_hook_svc *hook; \
        struct afb_hookid hookid; \
+       const char *apiname = afb_export_apiname(export); \
        pthread_rwlock_rdlock(&rwlock); \
        init_hookid(&hookid); \
        hook = list_of_svc_hooks; \
        while (hook) { \
                if (hook->itf->hook_svc_##what \
                 && (hook->flags & afb_hook_flag_svc_##what) != 0 \
-                && (!hook->api || !strcasecmp(hook->api, svc->api))) { \
+                && (!hook->api || !strcasecmp(hook->api, apiname))) { \
                        hook->itf->hook_svc_##what(hook->closure, &hookid, __VA_ARGS__); \
                } \
                hook = hook->next; \
        } \
        pthread_rwlock_unlock(&rwlock);
 
-void afb_hook_svc_start_before(const struct afb_svc *svc)
+void afb_hook_svc_start_before(const struct afb_export *export)
 {
-       _HOOK_SVC_(start_before, svc);
+       _HOOK_SVC_(start_before, export);
 }
 
-int afb_hook_svc_start_after(const struct afb_svc *svc, int status)
+int afb_hook_svc_start_after(const struct afb_export *export, int status)
 {
-       _HOOK_SVC_(start_after, svc, status);
+       _HOOK_SVC_(start_after, export, status);
        return status;
 }
 
-void afb_hook_svc_on_event_before(const struct afb_svc *svc, const char *event, int eventid, struct json_object *object)
+void afb_hook_svc_on_event_before(const struct afb_export *export, const char *event, int eventid, struct json_object *object)
 {
-       _HOOK_SVC_(on_event_before, svc, event, eventid, object);
+       _HOOK_SVC_(on_event_before, export, event, eventid, object);
 }
 
-void afb_hook_svc_on_event_after(const struct afb_svc *svc, const char *event, int eventid, struct json_object *object)
+void afb_hook_svc_on_event_after(const struct afb_export *export, const char *event, int eventid, struct json_object *object)
 {
-       _HOOK_SVC_(on_event_after, svc, event, eventid, object);
+       _HOOK_SVC_(on_event_after, export, event, eventid, object);
 }
 
-void afb_hook_svc_call(const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args)
+void afb_hook_svc_call(const struct afb_export *export, const char *api, const char *verb, struct json_object *args)
 {
-       _HOOK_SVC_(call, svc, api, verb, args);
+       _HOOK_SVC_(call, export, api, verb, args);
 }
 
-void afb_hook_svc_call_result(const struct afb_svc *svc, int status, struct json_object *result)
+void afb_hook_svc_call_result(const struct afb_export *export, int status, struct json_object *result)
 {
-       _HOOK_SVC_(call_result, svc, status, result);
+       _HOOK_SVC_(call_result, export, status, result);
 }
 
-void afb_hook_svc_callsync(const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args)
+void afb_hook_svc_callsync(const struct afb_export *export, const char *api, const char *verb, struct json_object *args)
 {
-       _HOOK_SVC_(callsync, svc, api, verb, args);
+       _HOOK_SVC_(callsync, export, api, verb, args);
 }
 
-int afb_hook_svc_callsync_result(const struct afb_svc *svc, int status, struct json_object *result)
+int afb_hook_svc_callsync_result(const struct afb_export *export, int status, struct json_object *result)
 {
-       _HOOK_SVC_(callsync_result, svc, status, result);
+       _HOOK_SVC_(callsync_result, export, status, result);
        return status;
 }
 
 /******************************************************************************
- * section: hooking services (svc)
+ * section: hooking services (export)
  *****************************************************************************/
 
 int afb_hook_flags_svc(const char *api)
index 6f54f70..a9c3894 100644 (file)
@@ -27,8 +27,7 @@ struct afb_arg;
 struct afb_event;
 struct afb_session;
 struct afb_xreq;
-struct afb_ditf;
-struct afb_svc;
+struct afb_export;
 struct afb_stored_req;
 struct sd_bus;
 struct sd_event;
@@ -160,7 +159,7 @@ extern void afb_hook_xreq_subcall_req_result(const struct afb_xreq *xreq, int st
 extern int afb_hook_xreq_has_permission(const struct afb_xreq *xreq, const char *permission, int result);
 
 /*********************************************************
-* section hooking ditf (daemon interface)
+* section hooking export (daemon interface)
 *********************************************************/
 
 #define afb_hook_flag_ditf_vverbose                    0x000001
@@ -196,36 +195,36 @@ extern int afb_hook_xreq_has_permission(const struct afb_xreq *xreq, const char
 #define afb_hook_flags_ditf_all                (afb_hook_flags_ditf_common|afb_hook_flags_ditf_extra)
 
 struct afb_hook_ditf_itf {
-       void (*hook_ditf_event_broadcast_before)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, struct json_object *object);
-       void (*hook_ditf_event_broadcast_after)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, struct json_object *object, int result);
-       void (*hook_ditf_get_event_loop)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct sd_event *result);
-       void (*hook_ditf_get_user_bus)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct sd_bus *result);
-       void (*hook_ditf_get_system_bus)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct sd_bus *result);
-       void (*hook_ditf_vverbose)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, int level, const char *file, int line, const char *function, const char *fmt, va_list args);
-       void (*hook_ditf_event_make)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, struct afb_event result);
-       void (*hook_ditf_rootdir_get_fd)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, int result);
-       void (*hook_ditf_rootdir_open_locale)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *filename, int flags, const char *locale, int result);
-       void (*hook_ditf_queue_job)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result);
-       void (*hook_ditf_unstore_req)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct afb_stored_req *sreq);
-       void (*hook_ditf_require_api)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, int initialized);
-       void (*hook_ditf_require_api_result)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, int initialized, int result);
-       void (*hook_ditf_rename_api)(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *oldname, const char *newname, int result);
+       void (*hook_ditf_event_broadcast_before)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, struct json_object *object);
+       void (*hook_ditf_event_broadcast_after)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, struct json_object *object, int result);
+       void (*hook_ditf_get_event_loop)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct sd_event *result);
+       void (*hook_ditf_get_user_bus)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct sd_bus *result);
+       void (*hook_ditf_get_system_bus)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct sd_bus *result);
+       void (*hook_ditf_vverbose)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int level, const char *file, int line, const char *function, const char *fmt, va_list args);
+       void (*hook_ditf_event_make)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, struct afb_event result);
+       void (*hook_ditf_rootdir_get_fd)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int result);
+       void (*hook_ditf_rootdir_open_locale)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *filename, int flags, const char *locale, int result);
+       void (*hook_ditf_queue_job)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result);
+       void (*hook_ditf_unstore_req)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct afb_stored_req *sreq);
+       void (*hook_ditf_require_api)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, int initialized);
+       void (*hook_ditf_require_api_result)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, int initialized, int result);
+       void (*hook_ditf_rename_api)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *oldname, const char *newname, int result);
 };
 
-extern void afb_hook_ditf_event_broadcast_before(const struct afb_ditf *ditf, const char *name, struct json_object *object);
-extern int afb_hook_ditf_event_broadcast_after(const struct afb_ditf *ditf, const char *name, struct json_object *object, int result);
-extern struct sd_event *afb_hook_ditf_get_event_loop(const struct afb_ditf *ditf, struct sd_event *result);
-extern struct sd_bus *afb_hook_ditf_get_user_bus(const struct afb_ditf *ditf, struct sd_bus *result);
-extern struct sd_bus *afb_hook_ditf_get_system_bus(const struct afb_ditf *ditf, struct sd_bus *result);
-extern void afb_hook_ditf_vverbose(const struct afb_ditf *ditf, int level, const char *file, int line, const char *function, const char *fmt, va_list args);
-extern struct afb_event afb_hook_ditf_event_make(const struct afb_ditf *ditf, const char *name, struct afb_event result);
-extern int afb_hook_ditf_rootdir_get_fd(const struct afb_ditf *ditf, int result);
-extern int afb_hook_ditf_rootdir_open_locale(const struct afb_ditf *ditf, const char *filename, int flags, const char *locale, int result);
-extern int afb_hook_ditf_queue_job(const struct afb_ditf *ditf, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result);
-extern void afb_hook_ditf_unstore_req(const struct afb_ditf *ditf, struct afb_stored_req *sreq);
-extern void afb_hook_ditf_require_api(const struct afb_ditf *ditf, const char *name, int initialized);
-extern int afb_hook_ditf_require_api_result(const struct afb_ditf *ditf, const char *name, int initialized, int result);
-extern int afb_hook_ditf_rename_api(const struct afb_ditf *ditf, const char *oldname, const char *newname, int result);
+extern void afb_hook_ditf_event_broadcast_before(const struct afb_export *export, const char *name, struct json_object *object);
+extern int afb_hook_ditf_event_broadcast_after(const struct afb_export *export, const char *name, struct json_object *object, int result);
+extern struct sd_event *afb_hook_ditf_get_event_loop(const struct afb_export *export, struct sd_event *result);
+extern struct sd_bus *afb_hook_ditf_get_user_bus(const struct afb_export *export, struct sd_bus *result);
+extern struct sd_bus *afb_hook_ditf_get_system_bus(const struct afb_export *export, struct sd_bus *result);
+extern void afb_hook_ditf_vverbose(const struct afb_export *export, int level, const char *file, int line, const char *function, const char *fmt, va_list args);
+extern struct afb_event afb_hook_ditf_event_make(const struct afb_export *export, const char *name, struct afb_event result);
+extern int afb_hook_ditf_rootdir_get_fd(const struct afb_export *export, int result);
+extern int afb_hook_ditf_rootdir_open_locale(const struct afb_export *export, const char *filename, int flags, const char *locale, int result);
+extern int afb_hook_ditf_queue_job(const struct afb_export *export, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result);
+extern void afb_hook_ditf_unstore_req(const struct afb_export *export, struct afb_stored_req *sreq);
+extern void afb_hook_ditf_require_api(const struct afb_export *export, const char *name, int initialized);
+extern int afb_hook_ditf_require_api_result(const struct afb_export *export, const char *name, int initialized, int result);
+extern int afb_hook_ditf_rename_api(const struct afb_export *export, const char *oldname, const char *newname, int result);
 
 extern int afb_hook_flags_ditf(const char *api);
 extern struct afb_hook_ditf *afb_hook_create_ditf(const char *api, int flags, struct afb_hook_ditf_itf *itf, void *closure);
@@ -233,7 +232,7 @@ extern struct afb_hook_ditf *afb_hook_addref_ditf(struct afb_hook_ditf *hook);
 extern void afb_hook_unref_ditf(struct afb_hook_ditf *hook);
 
 /*********************************************************
-* section hooking svc (service interface)
+* section hooking export (service interface)
 *********************************************************/
 
 #define afb_hook_flag_svc_start_before                 0x000001
@@ -251,24 +250,24 @@ extern void afb_hook_unref_ditf(struct afb_hook_ditf *hook);
                                        |afb_hook_flag_svc_callsync|afb_hook_flag_svc_callsync_result)
 
 struct afb_hook_svc_itf {
-       void (*hook_svc_start_before)(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc);
-       void (*hook_svc_start_after)(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, int status);
-       void (*hook_svc_on_event_before)(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *event, int eventid, struct json_object *object);
-       void (*hook_svc_on_event_after)(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *event, int eventid, struct json_object *object);
-       void (*hook_svc_call)(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args);
-       void (*hook_svc_call_result)(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, int status, struct json_object *result);
-       void (*hook_svc_callsync)(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args);
-       void (*hook_svc_callsync_result)(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, int status, struct json_object *result);
+       void (*hook_svc_start_before)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export);
+       void (*hook_svc_start_after)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int status);
+       void (*hook_svc_on_event_before)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int eventid, struct json_object *object);
+       void (*hook_svc_on_event_after)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int eventid, struct json_object *object);
+       void (*hook_svc_call)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *api, const char *verb, struct json_object *args);
+       void (*hook_svc_call_result)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int status, struct json_object *result);
+       void (*hook_svc_callsync)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *api, const char *verb, struct json_object *args);
+       void (*hook_svc_callsync_result)(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int status, struct json_object *result);
 };
 
-extern void afb_hook_svc_start_before(const struct afb_svc *svc);
-extern int afb_hook_svc_start_after(const struct afb_svc *svc, int status);
-extern void afb_hook_svc_on_event_before(const struct afb_svc *svc, const char *event, int eventid, struct json_object *object);
-extern void afb_hook_svc_on_event_after(const struct afb_svc *svc, const char *event, int eventid, struct json_object *object);
-extern void afb_hook_svc_call(const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args);
-extern void afb_hook_svc_call_result(const struct afb_svc *svc, int status, struct json_object *result);
-extern void afb_hook_svc_callsync(const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args);
-extern int afb_hook_svc_callsync_result(const struct afb_svc *svc, int status, struct json_object *result);
+extern void afb_hook_svc_start_before(const struct afb_export *export);
+extern int afb_hook_svc_start_after(const struct afb_export *export, int status);
+extern void afb_hook_svc_on_event_before(const struct afb_export *export, const char *event, int eventid, struct json_object *object);
+extern void afb_hook_svc_on_event_after(const struct afb_export *export, const char *event, int eventid, struct json_object *object);
+extern void afb_hook_svc_call(const struct afb_export *export, const char *api, const char *verb, struct json_object *args);
+extern void afb_hook_svc_call_result(const struct afb_export *export, int status, struct json_object *result);
+extern void afb_hook_svc_callsync(const struct afb_export *export, const char *api, const char *verb, struct json_object *args);
+extern int afb_hook_svc_callsync_result(const struct afb_export *export, int status, struct json_object *result);
 
 extern int afb_hook_flags_svc(const char *api);
 extern struct afb_hook_svc *afb_hook_create_svc(const char *api, int flags, struct afb_hook_svc_itf *itf, void *closure);
index 168b13d..4b1c038 100644 (file)
@@ -26,7 +26,6 @@
 #include "afb-api.h"
 #include "afb-apiset.h"
 #include "afb-api-so-v2.h"
-#include "afb-ditf.h"
 #include "afb-evt.h"
 #include "afb-xreq.h"
 #include "afb-trace.h"
diff --git a/src/afb-svc.c b/src/afb-svc.c
deleted file mode 100644 (file)
index 212ecfa..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 "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 <string.h>
-#include <errno.h>
-
-#include <json-c/json.h>
-
-#include <afb/afb-binding-v1.h>
-#include <afb/afb-binding-v2.h>
-
-#include "afb-session.h"
-#include "afb-context.h"
-#include "afb-evt.h"
-#include "afb-msg-json.h"
-#include "afb-svc.h"
-#include "afb-xreq.h"
-#include "afb-cred.h"
-#include "afb-apiset.h"
-#include "afb-hook.h"
-#include "jobs.h"
-#include "verbose.h"
-
-
-#define HOOK(x,...) if((svc)->hookflags & afb_hook_flag_svc_##x) afb_hook_svc_##x(__VA_ARGS__)
-
-/*
- * Structure for requests initiated by the service
- */
-struct svc_req
-{
-       struct afb_xreq xreq;
-
-       struct afb_svc *svc;
-
-       /* the args */
-       void (*callback)(void*, int, struct json_object*);
-       void *closure;
-
-       /* sync */
-       struct jobloop *jobloop;
-       struct json_object *result;
-       int status;
-       int async;
-};
-
-/* functions for services */
-static void svc_on_event(void *closure, const char *event, int eventid, struct json_object *object);
-static void svc_call(void *closure, const char *api, const char *verb, struct json_object *args,
-                               void (*callback)(void*, int, struct json_object*), void *cbclosure);
-static int svc_call_sync(void *closure, const char *api, const char *verb, struct json_object *args,
-                               struct json_object **result);
-
-/* the interface for services */
-static const struct afb_service_itf service_itf = {
-       .call = svc_call,
-       .call_sync = svc_call_sync
-};
-
-/* the interface for events */
-static const struct afb_evt_itf evt_itf = {
-       .broadcast = svc_on_event,
-       .push = svc_on_event
-};
-
-/* functions for requests of services */
-static void svcreq_destroy(struct afb_xreq *xreq);
-static void svcreq_reply(struct afb_xreq *xreq, int status, json_object *obj);
-
-/* interface for requests of services */
-const struct afb_xreq_query_itf afb_svc_xreq_itf = {
-       .unref = svcreq_destroy,
-       .reply = svcreq_reply
-};
-
-/* the common session for services sharing their session */
-static struct afb_session *common_session;
-
-static inline struct afb_service to_afb_service(struct afb_svc *svc)
-{
-       return (struct afb_service){ .itf = &service_itf, .closure = svc };
-}
-
-/*
- * Frees a service
- */
-void afb_svc_destroy(struct afb_svc *svc, struct afb_service *service)
-{
-       if (service)
-               *service = (struct afb_service){ .itf = NULL, .closure = NULL };
-       if (svc) {
-               if (svc->listener != NULL)
-                       afb_evt_listener_unref(svc->listener);
-               if (svc->session)
-                       afb_session_unref(svc->session);
-               afb_apiset_unref(svc->apiset);
-               free(svc);
-       }
-}
-
-/*
- * Creates a new service
- */
-struct afb_svc *afb_svc_create(
-                       const char *api,
-                       struct afb_apiset *apiset,
-                       int share_session,
-                       void (*on_event)(const char *event, struct json_object *object),
-                       struct afb_service *service
-)
-{
-       struct afb_svc *svc;
-
-       /* allocates the svc handler */
-       svc = calloc(1, sizeof * svc);
-       if (svc == NULL) {
-               errno = ENOMEM;
-               return NULL;
-       }
-
-       /* instanciate the apiset */
-       svc->api = api;
-       svc->apiset = afb_apiset_addref(apiset);
-
-       /* instanciate the session */
-       if (share_session) {
-               /* session shared with other svcs */
-               if (common_session == NULL) {
-                       common_session = afb_session_create (NULL, 0);
-                       if (common_session == NULL)
-                               goto error;
-               }
-               svc->session = afb_session_addref(common_session);
-       } else {
-               /* session dedicated to the svc */
-               svc->session = afb_session_create (NULL, 0);
-               if (svc->session == NULL)
-                       goto error;
-       }
-
-       svc->hookflags = afb_hook_flags_svc(svc->api);
-       if (service)
-               *service = to_afb_service(svc);
-
-       /* initialises the listener if needed */
-       if (on_event) {
-               svc->on_event = on_event;
-               svc->listener = afb_evt_listener_create(&evt_itf, svc);
-               if (svc->listener == NULL)
-                       goto error;
-       }
-
-       return svc;
-
-error:
-       afb_svc_destroy(svc, service);
-       return NULL;
-}
-
-/*
- * Starts a new service (v1)
- */
-int afb_svc_start_v1(struct afb_svc *svc, int (*start)(struct afb_service))
-{
-       int rc;
-
-       HOOK(start_before, svc);
-       rc = start(to_afb_service(svc));
-       HOOK(start_after, svc, rc);
-       return rc;
-}
-
-/*
- * Starts a new service (v2)
- */
-int afb_svc_start_v2(struct afb_svc *svc, int (*start)())
-{
-       int rc;
-
-       HOOK(start_before, svc);
-       rc = start();
-       HOOK(start_after, svc, rc);
-       return rc;
-}
-
-/*
- * Request to updates the hooks
- */
-void afb_svc_update_hook(struct afb_svc *svc)
-{
-       svc->hookflags = afb_hook_flags_svc(svc->api);
-}
-
-/*
- * Propagates the event to the service
- */
-static void svc_on_event(void *closure, const char *event, int eventid, struct json_object *object)
-{
-       struct afb_svc *svc = closure;
-
-       HOOK(on_event_before, svc, event, eventid, object);
-       svc->on_event(event, object);
-       HOOK(on_event_after, svc, event, eventid, object);
-       json_object_put(object);
-}
-
-/*
- * create an svc_req
- */
-static struct svc_req *svcreq_create(struct afb_svc *svc, const char *api, const char *verb, struct json_object *args)
-{
-       struct svc_req *svcreq;
-       size_t lenapi, lenverb;
-       char *copy;
-
-       /* allocates the request */
-       lenapi = 1 + strlen(api);
-       lenverb = 1 + strlen(verb);
-       svcreq = malloc(lenapi + lenverb + sizeof *svcreq);
-       if (svcreq != NULL) {
-               /* initialises the request */
-               afb_xreq_init(&svcreq->xreq, &afb_svc_xreq_itf);
-               afb_context_init(&svcreq->xreq.context, svc->session, NULL);
-               svcreq->xreq.context.validated = 1;
-               copy = (char*)&svcreq[1];
-               memcpy(copy, api, lenapi);
-               svcreq->xreq.api = copy;
-               copy = &copy[lenapi];
-               memcpy(copy, verb, lenverb);
-               svcreq->xreq.verb = copy;
-               svcreq->xreq.listener = svc->listener;
-               svcreq->xreq.json = args;
-               svcreq->svc = svc;
-       }
-       return svcreq;
-}
-
-/*
- * destroys the svc_req
- */
-static void svcreq_destroy(struct afb_xreq *xreq)
-{
-       struct svc_req *svcreq = CONTAINER_OF_XREQ(struct svc_req, xreq);
-
-       afb_context_disconnect(&svcreq->xreq.context);
-       json_object_put(svcreq->xreq.json);
-       afb_cred_unref(svcreq->xreq.cred);
-       free(svcreq);
-}
-
-static void svcreq_sync_leave(struct svc_req *svcreq)
-{
-       struct jobloop *jobloop = svcreq->jobloop;
-
-       if (jobloop) {
-               svcreq->jobloop = NULL;
-               jobs_leave(jobloop);
-       }
-}
-
-static void svcreq_reply(struct afb_xreq *xreq, int status, json_object *obj)
-{
-       struct svc_req *svcreq = CONTAINER_OF_XREQ(struct svc_req, xreq);
-       if (svcreq->async) {
-               struct afb_svc *svc = svcreq->svc;
-               if (svcreq->callback)
-                       svcreq->callback(svcreq->closure, status, obj);
-               HOOK(call_result, svc, status, obj);
-               json_object_put(obj);
-       } else {
-               svcreq->status = status;
-               svcreq->result = obj;
-               svcreq_sync_leave(svcreq);
-       }
-}
-
-static void svcreq_sync_enter(int signum, void *closure, struct jobloop *jobloop)
-{
-       struct svc_req *svcreq = closure;
-
-       if (!signum) {
-               svcreq->jobloop = jobloop;
-               afb_xreq_process(&svcreq->xreq, svcreq->svc->apiset);
-       } else {
-               svcreq->result = afb_msg_json_internal_error();
-               svcreq->status = -1;
-               svcreq_sync_leave(svcreq);
-       }
-}
-
-/*
- * Initiates a call for the service
- */
-static void svc_call(void *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cbclosure)
-{
-       struct afb_svc *svc = closure;
-       struct svc_req *svcreq;
-       struct json_object *ierr;
-
-       HOOK(call, svc, api, verb, args);
-
-       /* allocates the request */
-       svcreq = svcreq_create(svc, api, verb, args);
-       if (svcreq == NULL) {
-               ERROR("out of memory");
-               json_object_put(args);
-               ierr = afb_msg_json_internal_error();
-               if (callback)
-                       callback(cbclosure, -1, ierr);
-               HOOK(call_result, svc, -1, ierr);
-               json_object_put(ierr);
-               return;
-       }
-
-       /* initialises the request */
-       svcreq->jobloop = NULL;
-       svcreq->callback = callback;
-       svcreq->closure = cbclosure;
-       svcreq->async = 1;
-
-       /* terminates and frees ressources if needed */
-       afb_xreq_process(&svcreq->xreq, svc->apiset);
-}
-
-static int svc_call_sync(void *closure, const char *api, const char *verb, struct json_object *args,
-                               struct json_object **result)
-{
-       struct afb_svc *svc = closure;
-       struct svc_req *svcreq;
-       struct json_object *resu;
-       int rc;
-
-       HOOK(callsync, svc, api, verb, args);
-
-       /* allocates the request */
-       svcreq = svcreq_create(svc, api, verb, args);
-       if (svcreq == NULL) {
-               ERROR("out of memory");
-               errno = ENOMEM;
-               json_object_put(args);
-               resu = afb_msg_json_internal_error();
-               rc = -1;
-       } else {
-               /* initialises the request */
-               svcreq->jobloop = NULL;
-               svcreq->callback = NULL;
-               svcreq->result = NULL;
-               svcreq->status = 0;
-               svcreq->async = 0;
-               afb_xreq_addref(&svcreq->xreq);
-               rc = jobs_enter(NULL, 0, svcreq_sync_enter, svcreq);
-               if (rc >= 0)
-                       rc = svcreq->status;
-               resu = (rc >= 0 || svcreq->result) ? svcreq->result : afb_msg_json_internal_error();
-               afb_xreq_unref(&svcreq->xreq);
-       }
-       HOOK(callsync_result, svc, rc, resu);
-       if (result)
-               *result = resu;
-       else
-               json_object_put(resu);
-       return rc;
-}
-
diff --git a/src/afb-svc.h b/src/afb-svc.h
deleted file mode 100644 (file)
index e23c286..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 "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 afb_svc;
-struct afb_service;
-struct afb_session;
-struct afb_apiset;
-struct afb_evt_listener;
-struct afb_binding_data_v2;
-
-struct json_object;
-
-/*
- * Structure for recording service
- */
-struct afb_svc
-{
-       /* api/prefix */
-       const char *api;
-
-       /* session of the service */
-       struct afb_session *session;
-
-       /* the apiset for the service */
-       struct afb_apiset *apiset;
-
-       /* event listener of the service or NULL */
-       struct afb_evt_listener *listener;
-
-       /* on event callback for the service */
-       void (*on_event)(const char *event, struct json_object *object);
-
-       /* hooking flags */
-       int hookflags;
-};
-
-extern void afb_svc_destroy(struct afb_svc *svc, struct afb_service *service);
-
-extern struct afb_svc *afb_svc_create(
-                       const char *api,
-                       struct afb_apiset *apiset,
-                       int share_session,
-                       void (*on_event)(const char *event, struct json_object *object),
-                       struct afb_service *service);
-
-extern int afb_svc_start_v1(struct afb_svc *svc, int (*start)(struct afb_service));
-extern int afb_svc_start_v2(struct afb_svc *svc, int (*start)());
-
-extern void afb_svc_update_hook(struct afb_svc *svc);
-
index 8537081..c581611 100644 (file)
@@ -33,8 +33,7 @@
 #include "afb-cred.h"
 #include "afb-session.h"
 #include "afb-xreq.h"
-#include "afb-ditf.h"
-#include "afb-svc.h"
+#include "afb-export.h"
 #include "afb-evt.h"
 #include "afb-trace.h"
 
@@ -95,8 +94,8 @@ struct hook {
 enum trace_type
 {
        Trace_Type_Xreq,        /* xreq hooks */
-       Trace_Type_Ditf,        /* ditf hooks */
-       Trace_Type_Svc,         /* svc hooks */
+       Trace_Type_Ditf,        /* export hooks */
+       Trace_Type_Svc,         /* export hooks */
        Trace_Type_Evt,         /* evt hooks */
        Trace_Type_Global,      /* global hooks */
        Trace_Type_Count        /* count of types of hooks */
@@ -506,52 +505,52 @@ static struct flag ditf_flags[] = { /* must be sorted by names */
                { "vverbose",                   afb_hook_flag_ditf_vverbose },
 };
 
-/* get the ditf value for flag of 'name' */
+/* get the export value for flag of 'name' */
 static int get_ditf_flag(const char *name)
 {
        return get_flag(name, ditf_flags, (int)(sizeof ditf_flags / sizeof *ditf_flags));
 }
 
 
-static void hook_ditf(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *action, const char *format, ...)
+static void hook_ditf(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *action, const char *format, ...)
 {
        va_list ap;
 
        va_start(ap, format);
        emit(closure, hookid, "daemon", "{ss ss}", format, ap,
-                                       "api", ditf->api,
+                                       "api", afb_export_apiname(export),
                                        "action", action);
        va_end(ap);
 }
 
-static void hook_ditf_event_broadcast_before(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, struct json_object *object)
+static void hook_ditf_event_broadcast_before(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, struct json_object *object)
 {
-       hook_ditf(closure, hookid, ditf, "event_broadcast_before", "{ss sO*}",
+       hook_ditf(closure, hookid, export, "event_broadcast_before", "{ss sO*}",
                        "name", name, "data", object);
 }
 
-static void hook_ditf_event_broadcast_after(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, struct json_object *object, int result)
+static void hook_ditf_event_broadcast_after(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, struct json_object *object, int result)
 {
-       hook_ditf(closure, hookid, ditf, "event_broadcast_after", "{ss sO* si}",
+       hook_ditf(closure, hookid, export, "event_broadcast_after", "{ss sO* si}",
                        "name", name, "data", object, "result", result);
 }
 
-static void hook_ditf_get_event_loop(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct sd_event *result)
+static void hook_ditf_get_event_loop(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct sd_event *result)
 {
-       hook_ditf(closure, hookid, ditf, "get_event_loop", NULL);
+       hook_ditf(closure, hookid, export, "get_event_loop", NULL);
 }
 
-static void hook_ditf_get_user_bus(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct sd_bus *result)
+static void hook_ditf_get_user_bus(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct sd_bus *result)
 {
-       hook_ditf(closure, hookid, ditf, "get_user_bus", NULL);
+       hook_ditf(closure, hookid, export, "get_user_bus", NULL);
 }
 
-static void hook_ditf_get_system_bus(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct sd_bus *result)
+static void hook_ditf_get_system_bus(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, struct sd_bus *result)
 {
-       hook_ditf(closure, hookid, ditf, "get_system_bus", NULL);
+       hook_ditf(closure, hookid, export, "get_system_bus", NULL);
 }
 
-static void hook_ditf_vverbose(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
+static void hook_ditf_vverbose(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int level, const char *file, int line, const char *function, const char *fmt, va_list args)
 {
        struct json_object *pos;
        int len;
@@ -568,7 +567,7 @@ static void hook_ditf_vverbose(void *closure, const struct afb_hookid *hookid, c
        if (file)
                wrap_json_pack(&pos, "{ss si ss*}", "file", file, "line", line, "function", function);
 
-       hook_ditf(closure, hookid, ditf, "vverbose", "{si ss* ss? so*}",
+       hook_ditf(closure, hookid, export, "vverbose", "{si ss* ss? so*}",
                                        "level", level,
                                        "type", verbosity_level_name(level),
                                        len < 0 ? "format" : "message", len < 0 ? fmt : msg,
@@ -577,13 +576,13 @@ static void hook_ditf_vverbose(void *closure, const struct afb_hookid *hookid, c
        free(msg);
 }
 
-static void hook_ditf_event_make(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, struct afb_event result)
+static void hook_ditf_event_make(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, struct afb_event result)
 {
-       hook_ditf(closure, hookid, ditf, "event_make", "{ss ss si}",
+       hook_ditf(closure, hookid, export, "event_make", "{ss ss si}",
                        "name", name, "event", afb_evt_event_name(result), "id", afb_evt_event_id(result));
 }
 
-static void hook_ditf_rootdir_get_fd(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, int result)
+static void hook_ditf_rootdir_get_fd(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int result)
 {
        char path[PATH_MAX];
 
@@ -592,12 +591,12 @@ static void hook_ditf_rootdir_get_fd(void *closure, const struct afb_hookid *hoo
                readlink(path, path, sizeof path);
        }
 
-       hook_ditf(closure, hookid, ditf, "rootdir_get_fd", "{ss}",
+       hook_ditf(closure, hookid, export, "rootdir_get_fd", "{ss}",
                        result < 0 ? "path" : "error",
                        result < 0 ? strerror(errno) : path);
 }
 
-static void hook_ditf_rootdir_open_locale(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *filename, int flags, const char *locale, int result)
+static void hook_ditf_rootdir_open_locale(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *filename, int flags, const char *locale, int result)
 {
        char path[PATH_MAX];
 
@@ -606,7 +605,7 @@ static void hook_ditf_rootdir_open_locale(void *closure, const struct afb_hookid
                readlink(path, path, sizeof path);
        }
 
-       hook_ditf(closure, hookid, ditf, "rootdir_open_locale", "{ss si ss* ss}",
+       hook_ditf(closure, hookid, export, "rootdir_open_locale", "{ss si ss* ss}",
                        "file", filename,
                        "flags", flags,
                        "locale", locale,
@@ -614,24 +613,24 @@ static void hook_ditf_rootdir_open_locale(void *closure, const struct afb_hookid
                        result < 0 ? strerror(errno) : path);
 }
 
-static void hook_ditf_queue_job(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result)
+static void hook_ditf_queue_job(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout, int result)
 {
-       hook_ditf(closure, hookid, ditf, "queue_job", "{ss}", "result", result);
+       hook_ditf(closure, hookid, export, "queue_job", "{ss}", "result", result);
 }
 
-static void hook_ditf_unstore_req(void * closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, struct afb_stored_req *sreq)
+static void hook_ditf_unstore_req(void * closure, const struct afb_hookid *hookid, const struct afb_export *export, struct afb_stored_req *sreq)
 {
-       hook_ditf(closure, hookid, ditf, "unstore_req", NULL);
+       hook_ditf(closure, hookid, export, "unstore_req", NULL);
 }
 
-static void hook_ditf_require_api(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, int initialized)
+static void hook_ditf_require_api(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, int initialized)
 {
-       hook_ditf(closure, hookid, ditf, "require_api", "{ss sb}", "name", name, "initialized", initialized);
+       hook_ditf(closure, hookid, export, "require_api", "{ss sb}", "name", name, "initialized", initialized);
 }
 
-static void hook_ditf_require_api_result(void *closure, const struct afb_hookid *hookid, const struct afb_ditf *ditf, const char *name, int initialized, int result)
+static void hook_ditf_require_api_result(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *name, int initialized, int result)
 {
-       hook_ditf(closure, hookid, ditf, "require_api_result", "{ss sb si}", "name", name, "initialized", initialized, "result", result);
+       hook_ditf(closure, hookid, export, "require_api_result", "{ss sb si}", "name", name, "initialized", initialized, "result", result);
 }
 
 static struct afb_hook_ditf_itf hook_ditf_itf = {
@@ -666,66 +665,66 @@ static struct flag svc_flags[] = { /* must be sorted by names */
                { "start_before",       afb_hook_flag_svc_start_before },
 };
 
-/* get the svc value for flag of 'name' */
+/* get the export value for flag of 'name' */
 static int get_svc_flag(const char *name)
 {
        return get_flag(name, svc_flags, (int)(sizeof svc_flags / sizeof *svc_flags));
 }
 
-static void hook_svc(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *action, const char *format, ...)
+static void hook_svc(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *action, const char *format, ...)
 {
        va_list ap;
 
        va_start(ap, format);
        emit(closure, hookid, "service", "{ss ss}", format, ap,
-                                       "api", svc->api,
+                                       "api", afb_export_apiname(export),
                                        "action", action);
        va_end(ap);
 }
 
-static void hook_svc_start_before(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc)
+static void hook_svc_start_before(void *closure, const struct afb_hookid *hookid, const struct afb_export *export)
 {
-       hook_svc(closure, hookid, svc, "start_before", NULL);
+       hook_svc(closure, hookid, export, "start_before", NULL);
 }
 
-static void hook_svc_start_after(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, int status)
+static void hook_svc_start_after(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int status)
 {
-       hook_svc(closure, hookid, svc, "start_after", "{si}", "result", status);
+       hook_svc(closure, hookid, export, "start_after", "{si}", "result", status);
 }
 
-static void hook_svc_on_event_before(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *event, int eventid, struct json_object *object)
+static void hook_svc_on_event_before(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int eventid, struct json_object *object)
 {
-       hook_svc(closure, hookid, svc, "on_event_before", "{ss si sO*}",
+       hook_svc(closure, hookid, export, "on_event_before", "{ss si sO*}",
                        "event", event, "id", eventid, "data", object);
 }
 
-static void hook_svc_on_event_after(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *event, int eventid, struct json_object *object)
+static void hook_svc_on_event_after(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *event, int eventid, struct json_object *object)
 {
-       hook_svc(closure, hookid, svc, "on_event_after", "{ss si sO*}",
+       hook_svc(closure, hookid, export, "on_event_after", "{ss si sO*}",
                        "event", event, "id", eventid, "data", object);
 }
 
-static void hook_svc_call(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args)
+static void hook_svc_call(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *api, const char *verb, struct json_object *args)
 {
-       hook_svc(closure, hookid, svc, "call", "{ss ss sO*}",
+       hook_svc(closure, hookid, export, "call", "{ss ss sO*}",
                        "api", api, "verb", verb, "args", args);
 }
 
-static void hook_svc_call_result(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, int status, struct json_object *result)
+static void hook_svc_call_result(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int status, struct json_object *result)
 {
-       hook_svc(closure, hookid, svc, "call_result", "{si sO*}",
+       hook_svc(closure, hookid, export, "call_result", "{si sO*}",
                        "status", status, "result", result);
 }
 
-static void hook_svc_callsync(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, const char *api, const char *verb, struct json_object *args)
+static void hook_svc_callsync(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, const char *api, const char *verb, struct json_object *args)
 {
-       hook_svc(closure, hookid, svc, "callsync", "{ss ss sO*}",
+       hook_svc(closure, hookid, export, "callsync", "{ss ss sO*}",
                        "api", api, "verb", verb, "args", args);
 }
 
-static void hook_svc_callsync_result(void *closure, const struct afb_hookid *hookid, const struct afb_svc *svc, int status, struct json_object *result)
+static void hook_svc_callsync_result(void *closure, const struct afb_hookid *hookid, const struct afb_export *export, int status, struct json_object *result)
 {
-       hook_svc(closure, hookid, svc, "callsync_result", "{si sO*}",
+       hook_svc(closure, hookid, export, "callsync_result", "{si sO*}",
                        "status", status, "result", result);
 }