aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-09-04 18:17:55 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2017-09-07 09:43:14 +0200
commit550b36945f2e9eae1fc4b822ea9a00a2a866eb83 (patch)
tree6d94b4fa92efcd7ff4a4cf9f8e0bb5b73f46dc3d
parente51d68ddc998f558507217e3c849b16ce94c068f (diff)
Allow renaming of API
The function afb_daemon_rename_api allows to rename an API during the preinit phase. Change-Id: I35477ba99d35b1dc51a7cacf8e55c3f02d86d7b4 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--docs/afb-binding-references.md12
-rw-r--r--include/afb/afb-binding.h2
-rw-r--r--include/afb/afb-daemon-common.h1
-rw-r--r--include/afb/afb-daemon-v1.h11
-rw-r--r--include/afb/afb-daemon-v2.h11
-rw-r--r--src/afb-api-so-v1.c21
-rw-r--r--src/afb-api-so-v2.c22
-rw-r--r--src/afb-ditf.c32
-rw-r--r--src/afb-hook.c14
-rw-r--r--src/afb-hook.h6
10 files changed, 107 insertions, 25 deletions
diff --git a/docs/afb-binding-references.md b/docs/afb-binding-references.md
index c266c2ef..f5ab66d1 100644
--- a/docs/afb-binding-references.md
+++ b/docs/afb-binding-references.md
@@ -238,6 +238,18 @@ bindings at its initialization.
int afb_daemon_require_api(const char *name, int initialized)
```
+This function allows to give a different name to the binding.
+It can be called during pre-init.
+
+```C
+/*
+ * Set the name of the API to 'name'.
+ * Calling this function is only allowed within preinit.
+ * Returns 0 in case of success or -1 in case of error.
+ */
+int afb_daemon_rename_api(const char *name);
+```
+
## Functions of class afb_service
The following functions allow services to call verbs of other
diff --git a/include/afb/afb-binding.h b/include/afb/afb-binding.h
index 1c4ec3f2..f8e38c49 100644
--- a/include/afb/afb-binding.h
+++ b/include/afb/afb-binding.h
@@ -161,6 +161,7 @@ typedef struct afb_service_itf afb_service_itf;
#define afb_daemon_rootdir_open_locale afb_daemon_rootdir_open_locale_v1
#define afb_daemon_queue_job afb_daemon_queue_job_v1
#define afb_daemon_require_api afb_daemon_require_api_v1
+#define afb_daemon_rename_api afb_daemon_rename_api_v1
#define afb_service_call afb_service_call_v1
#define afb_service_call_sync afb_service_call_sync_v1
@@ -216,6 +217,7 @@ typedef struct afb_service_itf afb_service_itf;
#define afb_daemon_queue_job afb_daemon_queue_job_v2
#define afb_daemon_unstore_req afb_daemon_unstore_req_v2
#define afb_daemon_require_api afb_daemon_require_api_v2
+#define afb_daemon_rename_api afb_daemon_rename_api_v2
#define afb_service_call afb_service_call_v2
#define afb_service_call_sync afb_service_call_sync_v2
diff --git a/include/afb/afb-daemon-common.h b/include/afb/afb-daemon-common.h
index 1d576b9a..5faf5758 100644
--- a/include/afb/afb-daemon-common.h
+++ b/include/afb/afb-daemon-common.h
@@ -42,6 +42,7 @@ struct afb_daemon_itf
void (*vverbose_v2)(void*closure, int level, const char *file, int line, const char * func, const char *fmt, va_list args);
struct afb_req (*unstore_req)(void*closure, struct afb_stored_req *sreq);
int (*require_api)(void*closure, const char *name, int initialized);
+ int (*rename_api)(void*closure, const char *name);
};
/*
diff --git a/include/afb/afb-daemon-v1.h b/include/afb/afb-daemon-v1.h
index 81cdb124..7fc2c235 100644
--- a/include/afb/afb-daemon-v1.h
+++ b/include/afb/afb-daemon-v1.h
@@ -180,3 +180,14 @@ static inline int afb_daemon_require_api_v1(struct afb_daemon daemon, const char
{
return daemon.itf->require_api(daemon.closure, name, initialized);
}
+
+/*
+ * Set the name of the API to 'name'.
+ * Calling this function is only allowed within preinit.
+ * Returns 0 in case of success or -1 in case of error.
+ */
+static inline int afb_daemon_rename_api_v1(struct afb_daemon daemon, const char *name)
+{
+ return daemon.itf->rename_api(daemon.closure, name);
+}
+
diff --git a/include/afb/afb-daemon-v2.h b/include/afb/afb-daemon-v2.h
index 7ef085b0..1451a097 100644
--- a/include/afb/afb-daemon-v2.h
+++ b/include/afb/afb-daemon-v2.h
@@ -157,3 +157,14 @@ static inline int afb_daemon_require_api_v2(const char *name, int initialized)
{
return afb_get_daemon_v2().itf->require_api(afb_get_daemon_v2().closure, name, initialized);
}
+
+/*
+ * Set the name of the API to 'name'.
+ * Calling this function is only allowed within preinit.
+ * Returns 0 in case of success or -1 in case of error.
+ */
+static inline int afb_daemon_rename_api_v2(const char *name)
+{
+ return afb_get_daemon_v2().itf->rename_api(afb_get_daemon_v2().closure, name);
+}
+
diff --git a/src/afb-api-so-v1.c b/src/afb-api-so-v1.c
index ad7a0cdd..84b870d7 100644
--- a/src/afb-api-so-v1.c
+++ b/src/afb-api-so-v1.c
@@ -90,7 +90,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
goto done;
/* already started: it is an error */
- ERROR("Service %s already started", desc->binding->v1.prefix);
+ ERROR("Service %s already started", desc->ditf.api);
return -1;
}
@@ -103,14 +103,14 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
goto done;
/* no initialisation method */
- ERROR("Binding %s is not a service", desc->binding->v1.prefix);
+ ERROR("Binding %s is not a service", desc->ditf.api);
return -1;
}
/* get the event handler if any */
- desc->service = afb_svc_create(desc->binding->v1.prefix, apiset, share_session, onevent, NULL);
+ desc->service = afb_svc_create(desc->ditf.api, apiset, share_session, onevent, NULL);
if (desc->service == NULL) {
- ERROR("Creation of service %s failed", desc->binding->v1.prefix);
+ ERROR("Creation of service %s failed", desc->ditf.api);
return -1;
}
@@ -119,7 +119,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
rc = afb_svc_start_v1(desc->service, init);
if (rc < 0) {
/* initialisation error */
- ERROR("Initialisation of service %s failed (%d): %m", desc->binding->v1.prefix, rc);
+ ERROR("Initialisation of service %s failed (%d): %m", desc->ditf.api, rc);
afb_svc_destroy(desc->service, NULL);
desc->service = NULL;
return rc;
@@ -195,9 +195,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->binding->v1.prefix));
+ json_object_object_add(i, "title", json_object_new_string(desc->ditf.api));
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->binding->v1.prefix));
+ json_object_object_add(i, "description", json_object_new_string(desc->binding->v1.info ?: desc->ditf.api));
p = json_object_new_object();
json_object_object_add(r, "paths", p);
@@ -303,15 +303,16 @@ int afb_api_so_v1_add(const char *path, void *handle, struct afb_apiset *apiset)
}
/* records the binding */
- afb_ditf_rename(&desc->ditf, desc->binding->v1.prefix);
+ if (desc->ditf.api == path)
+ afb_ditf_rename(&desc->ditf, 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->binding->v1.prefix, afb_api) < 0) {
+ if (afb_apiset_add(apiset, desc->ditf.api, afb_api) < 0) {
ERROR("binding [%s] can't be registered...", path);
goto error2;
}
- INFO("binding %s loaded with API prefix %s", path, desc->binding->v1.prefix);
+ INFO("binding %s loaded with API prefix %s", path, desc->ditf.api);
return 1;
error2:
diff --git a/src/afb-api-so-v2.c b/src/afb-api-so-v2.c
index d8941a42..8403366b 100644
--- a/src/afb-api-so-v2.c
+++ b/src/afb-api-so-v2.c
@@ -90,7 +90,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
goto done;
/* already started: it is an error */
- ERROR("Service %s already started", desc->binding->api);
+ ERROR("Service %s already started", desc->ditf.api);
return -1;
}
@@ -103,15 +103,15 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
goto done;
/* no initialisation method */
- ERROR("Binding %s is not a service", desc->binding->api);
+ ERROR("Binding %s is not a service", desc->ditf.api);
return -1;
}
/* get the event handler if any */
- desc->service = afb_svc_create(desc->binding->api, apiset, share_session, onevent, &desc->data->service);
+ 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->binding->api);
+ ERROR("Starting service %s failed", desc->ditf.api);
return -1;
}
@@ -120,7 +120,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct
rc = afb_svc_start_v2(desc->service, start);
if (rc < 0) {
/* initialisation error */
- ERROR("Initialisation of service %s failed (%d): %m", desc->binding->api, rc);
+ ERROR("Initialisation of service %s failed (%d): %m", desc->ditf.api, rc);
afb_svc_destroy(desc->service, &desc->data->service);
desc->service = NULL;
return rc;
@@ -196,9 +196,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->binding->api));
+ json_object_object_add(i, "title", json_object_new_string(desc->ditf.api));
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->binding->api));
+ json_object_object_add(i, "description", json_object_new_string(desc->binding->info ?: desc->ditf.api));
p = json_object_new_object();
json_object_object_add(r, "paths", p);
@@ -288,7 +288,7 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle
INFO("binding %s calling preinit function", binding->api);
rc = binding->preinit();
if (rc < 0) {
- ERROR("binding %s preinit function failed...", binding->api);
+ ERROR("binding %s preinit function failed...", desc->ditf.api);
goto error2;
}
}
@@ -297,11 +297,11 @@ 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, binding->api, afb_api) < 0) {
- ERROR("binding %s can't be registered to set %s...", binding->api, afb_apiset_name(apiset));
+ 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;
}
- INFO("binding %s added to set %s", binding->api, afb_apiset_name(apiset));
+ INFO("binding %s added to set %s", desc->ditf.api, afb_apiset_name(apiset));
return 1;
error2:
diff --git a/src/afb-ditf.c b/src/afb-ditf.c
index 63268a85..d3db9bb0 100644
--- a/src/afb-ditf.c
+++ b/src/afb-ditf.c
@@ -137,6 +137,24 @@ static int require_api_cb(void *closure, const char *name, int initialized)
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
**********************************************/
@@ -232,6 +250,14 @@ static int hooked_require_api_cb(void *closure, const char *name, int initialize
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
**********************************************/
@@ -247,7 +273,8 @@ static const struct afb_daemon_itf daemon_itf = {
.rootdir_open_locale = rootdir_open_locale_cb,
.queue_job = queue_job_cb,
.unstore_req = unstore_req_cb,
- .require_api = require_api_cb
+ .require_api = require_api_cb,
+ .rename_api = rename_api_cb
};
static const struct afb_daemon_itf hooked_daemon_itf = {
@@ -262,7 +289,8 @@ static const struct afb_daemon_itf hooked_daemon_itf = {
.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
+ .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)
diff --git a/src/afb-hook.c b/src/afb-hook.c
index 7dd81cba..a1ecea6d 100644
--- a/src/afb-hook.c
+++ b/src/afb-hook.c
@@ -752,6 +752,11 @@ static void hook_ditf_require_api_result_cb(void *closure, const struct afb_hook
_hook_ditf_(ditf, "...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)
+{
+ _hook_ditf_(ditf, "rename_api(%s -> %s) -> %d", oldname, newname, result);
+}
+
static struct afb_hook_ditf_itf hook_ditf_default_itf = {
.hook_ditf_event_broadcast_before = hook_ditf_event_broadcast_before_cb,
.hook_ditf_event_broadcast_after = hook_ditf_event_broadcast_after_cb,
@@ -765,7 +770,8 @@ static struct afb_hook_ditf_itf hook_ditf_default_itf = {
.hook_ditf_queue_job = hook_ditf_queue_job_cb,
.hook_ditf_unstore_req = hook_ditf_unstore_req_cb,
.hook_ditf_require_api = hook_ditf_require_api_cb,
- .hook_ditf_require_api_result = hook_ditf_require_api_result_cb
+ .hook_ditf_require_api_result = hook_ditf_require_api_result_cb,
+ .hook_ditf_rename_api = hook_ditf_rename_api_cb
};
/******************************************************************************
@@ -862,6 +868,12 @@ int afb_hook_ditf_require_api_result(const struct afb_ditf *ditf, const char *na
return result;
}
+int afb_hook_ditf_rename_api(const struct afb_ditf *ditf, const char *oldname, const char *newname, int result)
+{
+ _HOOK_DITF_(rename_api, ditf, oldname, newname, result);
+ return result;
+}
+
/******************************************************************************
* section: hooking ditf
*****************************************************************************/
diff --git a/src/afb-hook.h b/src/afb-hook.h
index 235e19d9..6f54f703 100644
--- a/src/afb-hook.h
+++ b/src/afb-hook.h
@@ -176,11 +176,13 @@ extern int afb_hook_xreq_has_permission(const struct afb_xreq *xreq, const char
#define afb_hook_flag_ditf_unstore_req 0x000400
#define afb_hook_flag_ditf_require_api 0x000800
#define afb_hook_flag_ditf_require_api_result 0x001000
+#define afb_hook_flag_ditf_rename_api 0x002000
#define afb_hook_flags_ditf_common (afb_hook_flag_ditf_vverbose\
|afb_hook_flag_ditf_event_make\
|afb_hook_flag_ditf_event_broadcast_before\
- |afb_hook_flag_ditf_event_broadcast_after)
+ |afb_hook_flag_ditf_event_broadcast_after\
+ |afb_hook_flag_ditf_rename_api)
#define afb_hook_flags_ditf_extra (afb_hook_flag_ditf_get_event_loop\
|afb_hook_flag_ditf_get_user_bus\
|afb_hook_flag_ditf_get_system_bus\
@@ -207,6 +209,7 @@ struct afb_hook_ditf_itf {
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);
};
extern void afb_hook_ditf_event_broadcast_before(const struct afb_ditf *ditf, const char *name, struct json_object *object);
@@ -222,6 +225,7 @@ extern int afb_hook_ditf_queue_job(const struct afb_ditf *ditf, void (*callback)
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 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);