+static void api_call_cb(void *closure, struct afb_xreq *xreq)
+{
+ struct afb_export *export = closure;
+
+ xreq->request.api = to_api_x3(export);
+
+ switch (export->version) {
+#if defined(WITH_LEGACY_BINDING_V1)
+ case Api_Version_1:
+ afb_api_so_v1_process_call(export->desc.v1, xreq);
+ break;
+#endif
+ case Api_Version_2:
+ afb_api_so_v2_process_call(export->desc.v2, xreq);
+ break;
+ case Api_Version_3:
+ afb_api_v3_process_call(export->desc.v3, xreq);
+ break;
+ default:
+ afb_xreq_reply(xreq, NULL, "bad-api-type", NULL);
+ break;
+ }
+}
+
+static struct json_object *api_describe_cb(void *closure)
+{
+ struct afb_export *export = closure;
+ struct json_object *result;
+
+ switch (export->version) {
+#if defined(WITH_LEGACY_BINDING_V1)
+ case Api_Version_1:
+ result = afb_api_so_v1_make_description_openAPIv3(export->desc.v1, export->api.apiname);
+ break;
+#endif
+ case Api_Version_2:
+ result = afb_api_so_v2_make_description_openAPIv3(export->desc.v2, export->api.apiname);
+ break;
+ case Api_Version_3:
+ result = afb_api_v3_make_description_openAPIv3(export->desc.v3, export->api.apiname);
+ break;
+ default:
+ result = NULL;
+ break;
+ }
+ return result;
+}
+
+static int api_service_start_cb(void *closure, int share_session, int onneed)
+{
+ struct afb_export *export = closure;
+
+ return afb_export_start(export, share_session, onneed);
+}
+
+static void api_update_hooks_cb(void *closure)
+{
+ struct afb_export *export = closure;
+
+ afb_export_update_hooks(export);
+}
+
+static int api_get_logmask_cb(void *closure)
+{
+ struct afb_export *export = closure;
+
+ return afb_export_logmask_get(export);
+}
+
+static void api_set_logmask_cb(void *closure, int level)
+{
+ struct afb_export *export = closure;
+
+ afb_export_logmask_set(export, level);
+}
+
+static void api_unref_cb(void *closure)
+{
+ struct afb_export *export = closure;
+
+ afb_export_unref(export);
+}
+
+static struct afb_api_itf export_api_itf =
+{
+ .call = api_call_cb,
+ .service_start = api_service_start_cb,
+ .update_hooks = api_update_hooks_cb,
+ .get_logmask = api_get_logmask_cb,
+ .set_logmask = api_set_logmask_cb,
+ .describe = api_describe_cb,
+ .unref = api_unref_cb
+};
+
+int afb_export_declare(struct afb_export *export,
+ int noconcurrency)
+{
+ int rc;
+ struct afb_api_item afb_api;
+
+ if (export->declared)
+ rc = 0;
+ else {
+ /* init the record structure */
+ afb_api.closure = afb_export_addref(export);
+ afb_api.itf = &export_api_itf;
+ afb_api.group = noconcurrency ? export : NULL;
+
+ /* records the binding */
+ rc = afb_apiset_add(export->declare_set, export->api.apiname, afb_api);
+ if (rc >= 0)
+ export->declared = 1;
+ else {
+ ERROR("can't declare export %s to set %s, ABORTING it!",
+ export->api.apiname,
+ afb_apiset_name(export->declare_set));
+ afb_export_addref(export);
+ }
+ }
+
+ return rc;
+}
+
+void afb_export_undeclare(struct afb_export *export)
+{
+ if (export->declared) {
+ export->declared = 0;
+ afb_apiset_del(export->declare_set, export->api.apiname);
+ }
+}
+
+int afb_export_subscribe(struct afb_export *export, struct afb_event_x2 *event)
+{
+ return afb_evt_event_x2_add_watch(export->listener, event);
+}
+
+int afb_export_unsubscribe(struct afb_export *export, struct afb_event_x2 *event)
+{
+ return afb_evt_event_x2_remove_watch(export->listener, event);
+}
+
+void afb_export_process_xreq(struct afb_export *export, struct afb_xreq *xreq)
+{
+ afb_xreq_process(xreq, export->call_set);
+}
+
+void afb_export_context_init(struct afb_export *export, struct afb_context *context)
+{
+ afb_context_init(context, export->session, NULL);
+}
+