X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-subcall.c;h=81361a08e640b48a9030b5bedaa78ed283587573;hb=0b838a6101edc810098ee0645d3bfd966096ae07;hp=bf6417384e5eea1b0e8bd317b5dcfa1ac8c39a86;hpb=b69290c369ba67ee804bc5a0a440210c0e5d37a3;p=src%2Fapp-framework-binder.git diff --git a/src/afb-subcall.c b/src/afb-subcall.c index bf641738..81361a08 100644 --- a/src/afb-subcall.c +++ b/src/afb-subcall.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 "IoT.bzh" + * Copyright (C) 2016, 2017 "IoT.bzh" * Author: José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,158 +27,115 @@ #include "afb-msg-json.h" #include "afb-apis.h" #include "afb-context.h" +#include "afb-xreq.h" #include "verbose.h" -struct afb_subcall; - -static void subcall_addref(struct afb_subcall *subcall); -static void subcall_unref(struct afb_subcall *subcall); -static struct json_object *subcall_json(struct afb_subcall *subcall); -static struct afb_arg subcall_get(struct afb_subcall *subcall, const char *name); -static void subcall_fail(struct afb_subcall *subcall, const char *status, const char *info); -static void subcall_success(struct afb_subcall *subcall, struct json_object *obj, const char *info); -static const char *subcall_raw(struct afb_subcall *subcall, size_t *size); -static void subcall_send(struct afb_subcall *subcall, const char *buffer, size_t size); -static int subcall_subscribe(struct afb_subcall *subcall, struct afb_event event); -static int subcall_unsubscribe(struct afb_subcall *subcall, struct afb_event event); -static void subcall_session_close(struct afb_subcall *subcall); -static int subcall_session_set_LOA(struct afb_subcall *subcall, unsigned loa); -static void subcall_subcall(struct afb_subcall *subcall, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *closure); - -const struct afb_req_itf afb_subcall_req_itf = { - .json = (void*)subcall_json, - .get = (void*)subcall_get, - .success = (void*)subcall_success, - .fail = (void*)subcall_fail, - .raw = (void*)subcall_raw, - .send = (void*)subcall_send, - .context_get = (void*)afb_context_get, - .context_set = (void*)afb_context_set, - .addref = (void*)subcall_addref, - .unref = (void*)subcall_unref, - .session_close = (void*)subcall_session_close, - .session_set_LOA = (void*)subcall_session_set_LOA, - .subscribe = (void*)subcall_subscribe, - .unsubscribe = (void*)subcall_unsubscribe, - .subcall = (void*)subcall_subcall +struct subcall; + +static void subcall_destroy(void *closure); +static void subcall_reply(void *closure, int iserror, struct json_object *obj); +static int subcall_subscribe(void *closure, struct afb_event event); +static int subcall_unsubscribe(void *closure, struct afb_event event); + +const struct afb_xreq_query_itf afb_subcall_xreq_itf = { + .reply = subcall_reply, + .unref = subcall_destroy, + .subscribe = subcall_subscribe, + .unsubscribe = subcall_unsubscribe }; -struct afb_subcall +struct subcall { - /* - * CAUTION: 'context' field should be the first because there - * is an implicit convertion to struct afb_context - */ - struct afb_context context; - struct afb_context *original_context; - int refcount; - struct json_object *args; - struct afb_req req; + struct afb_xreq xreq; + struct afb_xreq *caller; void (*callback)(void*, int, struct json_object*); void *closure; }; -static void subcall_addref(struct afb_subcall *subcall) +static void subcall_destroy(void *closure) { - subcall->refcount++; -} + struct subcall *subcall = closure; -static void subcall_unref(struct afb_subcall *subcall) -{ - if (0 == --subcall->refcount) { - json_object_put(subcall->args); - afb_req_unref(subcall->req); - free(subcall); - } + json_object_put(subcall->xreq.json); + afb_xreq_unref(subcall->caller); + free(subcall); } -static struct json_object *subcall_json(struct afb_subcall *subcall) +static void subcall_reply(void *closure, int iserror, struct json_object *obj) { - return subcall->args; -} + struct subcall *subcall = closure; -static struct afb_arg subcall_get(struct afb_subcall *subcall, const char *name) -{ - return afb_msg_json_get_arg(subcall->args, name); + subcall->callback(subcall->closure, iserror, obj); + json_object_put(obj); } -static void subcall_emit(struct afb_subcall *subcall, int iserror, struct json_object *object) +static int subcall_subscribe(void *closure, struct afb_event event) { - if (subcall->context.refreshing != 0) - subcall->original_context->refreshing = 1; + struct subcall *subcall = closure; - subcall->callback(subcall->closure, iserror, object); - json_object_put(object); + return afb_xreq_subscribe(subcall->caller, event); } -static void subcall_fail(struct afb_subcall *subcall, const char *status, const char *info) +static int subcall_unsubscribe(void *closure, struct afb_event event) { - subcall_emit(subcall, 1, afb_msg_json_reply_error(status, info, NULL, NULL)); -} + struct subcall *subcall = closure; -static void subcall_success(struct afb_subcall *subcall, struct json_object *obj, const char *info) -{ - subcall_emit(subcall, 0, afb_msg_json_reply_ok(info, obj, NULL, NULL)); + return afb_xreq_unsubscribe(subcall->caller, event); } -static const char *subcall_raw(struct afb_subcall *subcall, size_t *size) +void afb_subcall_internal_error(void (*callback)(void*, int, struct json_object*), void *closure) { - const char *result = json_object_to_json_string(subcall->args); - if (size != NULL) - *size = strlen(result); - return result; -} + static struct json_object *obj; -static void subcall_send(struct afb_subcall *subcall, const char *buffer, size_t size) -{ - subcall_emit(subcall, 0, json_tokener_parse(buffer)); -} + if (obj == NULL) + obj = afb_msg_json_reply_error("failed", "internal error", NULL, NULL); -static void subcall_session_close(struct afb_subcall *subcall) -{ - afb_req_session_close(subcall->req); + callback(closure, 1, obj); } -static int subcall_session_set_LOA(struct afb_subcall *subcall, unsigned loa) +static struct subcall *create_subcall(struct afb_xreq *caller, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *closure) { - return afb_req_session_set_LOA(subcall->req, loa); -} + struct subcall *subcall; -static int subcall_subscribe(struct afb_subcall *subcall, struct afb_event event) -{ - return afb_req_subscribe(subcall->req, event); -} + subcall = calloc(1, sizeof *subcall); + if (subcall == NULL) { + return NULL; + } -static int subcall_unsubscribe(struct afb_subcall *subcall, struct afb_event event) -{ - return afb_req_unsubscribe(subcall->req, event); -} -static void subcall_subcall(struct afb_subcall *subcall, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *closure) -{ - afb_subcall(&subcall->context, api, verb, args, callback, closure, (struct afb_req){ .itf = &afb_subcall_req_itf, .closure = subcall }); + afb_context_subinit(&subcall->xreq.context, &caller->context); + subcall->xreq.refcount = 1; + subcall->xreq.json = args; + subcall->xreq.api = api; /* TODO: alloc ? */ + subcall->xreq.verb = verb; /* TODO: alloc ? */ + subcall->xreq.query = subcall; + subcall->xreq.queryitf = &afb_subcall_xreq_itf; + subcall->caller = caller; + subcall->callback = callback; + subcall->closure = closure; + return subcall; } -void afb_subcall(struct afb_context *context, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *closure, struct afb_req req) +void afb_subcall( + struct afb_xreq *caller, + const char *api, + const char *verb, + struct json_object *args, + void (*callback)(void*, int, struct json_object*), + void *closure +) { - struct afb_subcall *subcall; + struct subcall *subcall; - subcall = calloc(1, sizeof *subcall); + subcall = create_subcall(caller, api, verb, args, callback, closure); if (subcall == NULL) { - callback(closure, 1, afb_msg_json_reply_error("failed", "out of memory", NULL, NULL)); + afb_subcall_internal_error(callback, closure); return; } - subcall->original_context = context; - subcall->refcount = 1; - subcall->args = args; - subcall->req = req; - subcall->callback = callback; - subcall->closure = closure; - subcall->context = *context; - afb_req_addref(req); - afb_apis_call_((struct afb_req){ .itf = &afb_subcall_req_itf, .closure = subcall }, &subcall->context, api, verb); - subcall_unref(subcall); + afb_xreq_addref(caller); + afb_apis_call(&subcall->xreq); + afb_xreq_unref(&subcall->xreq); }