aboutsummaryrefslogtreecommitdiffstats
path: root/src/afb-svc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/afb-svc.c')
-rw-r--r--src/afb-svc.c381
1 files changed, 0 insertions, 381 deletions
diff --git a/src/afb-svc.c b/src/afb-svc.c
deleted file mode 100644
index 212ecfa3..00000000
--- a/src/afb-svc.c
+++ /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;
-}
-