X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-subcall.c;h=ef114077e5d5dcb0783a1287655722e714284f55;hb=a86967decc0ff9b139f412fffccc7914e27a80a9;hp=6566b5b2d6162eff3d5489f0edd8851513e01994;hpb=0a8f8f784646254d9b71e928e930003f82d89603;p=src%2Fapp-framework-binder.git diff --git a/src/afb-subcall.c b/src/afb-subcall.c index 6566b5b2..ef114077 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"); @@ -25,170 +25,94 @@ #include "afb-subcall.h" #include "afb-msg-json.h" -#include "afb-apis.h" +#include "afb-apiset.h" #include "afb-context.h" +#include "afb-xreq.h" +#include "afb-cred.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 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) -{ - subcall->refcount++; -} - -static void subcall_unref(struct afb_subcall *subcall) +static void subcall_destroy(struct afb_xreq *xreq) { - if (0 == --subcall->refcount) { - json_object_put(subcall->args); - afb_req_unref(subcall->req); - free(subcall); - } -} - -static struct json_object *subcall_json(struct afb_subcall *subcall) -{ - return subcall->args; -} + struct subcall *subcall = CONTAINER_OF_XREQ(struct subcall, xreq); -static struct afb_arg subcall_get(struct afb_subcall *subcall, const char *name) -{ - return afb_msg_json_get_arg(subcall->args, name); + json_object_put(subcall->xreq.json); + afb_cred_unref(subcall->xreq.cred); + afb_xreq_unref(subcall->caller); + free(subcall); } -static void subcall_emit(struct afb_subcall *subcall, int iserror, struct json_object *object) +static void subcall_reply(struct afb_xreq *xreq, int iserror, struct json_object *obj) { - if (subcall->context.refreshing != 0) - subcall->original_context->refreshing = 1; + struct subcall *subcall = CONTAINER_OF_XREQ(struct subcall, xreq); - subcall->callback(subcall->closure, iserror, object); - json_object_put(object); + subcall->callback(subcall->closure, iserror, obj); + json_object_put(obj); } -static void subcall_fail(struct afb_subcall *subcall, const char *status, const char *info) +static int subcall_subscribe(struct afb_xreq *xreq, struct afb_event event) { - subcall_emit(subcall, 1, afb_msg_json_reply_error(status, info, NULL, NULL)); -} - -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)); -} + struct subcall *subcall = CONTAINER_OF_XREQ(struct subcall, xreq); -static const char *subcall_raw(struct afb_subcall *subcall, size_t *size) -{ - const char *result = json_object_to_json_string(subcall->args); - if (size != NULL) - *size = strlen(result); - return result; + return afb_xreq_subscribe(subcall->caller, event); } -static void subcall_send(struct afb_subcall *subcall, const char *buffer, size_t size) +static int subcall_unsubscribe(struct afb_xreq *xreq, struct afb_event event) { - subcall_emit(subcall, 0, json_tokener_parse(buffer)); -} + struct subcall *subcall = CONTAINER_OF_XREQ(struct subcall, xreq); -static void subcall_session_close(struct afb_subcall *subcall) -{ - afb_req_session_close(subcall->req); + return afb_xreq_unsubscribe(subcall->caller, event); } -static int subcall_session_set_LOA(struct afb_subcall *subcall, unsigned loa) -{ - return afb_req_session_set_LOA(subcall->req, loa); -} - -static int subcall_subscribe(struct afb_subcall *subcall, struct afb_event event) -{ - return afb_req_subscribe(subcall->req, event); -} - -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 }); -} - -void afb_subcall_internal_error(void (*callback)(void*, int, struct json_object*), void *closure) -{ - static struct json_object *obj; - - if (obj == NULL) - obj = afb_msg_json_reply_error("failed", "internal error", NULL, NULL); - - callback(closure, 1, obj); -} - -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) -{ - struct afb_subcall *subcall; +const struct afb_xreq_query_itf afb_subcall_xreq_itf = { + .reply = subcall_reply, + .unref = subcall_destroy, + .subscribe = subcall_subscribe, + .unsubscribe = subcall_unsubscribe +}; - subcall = calloc(1, sizeof *subcall); - if (subcall == NULL) { - afb_subcall_internal_error(callback, closure); - return; +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 subcall *subcall; + size_t lenapi, lenverb; + char *copy; + + lenapi = 1 + strlen(api); + lenverb = 1 + strlen(verb); + subcall = malloc(lenapi + lenverb + sizeof *subcall); + if (subcall == NULL) + callback(closure, 1, afb_msg_json_internal_error()); + else { + afb_xreq_init(&subcall->xreq, &afb_subcall_xreq_itf); + afb_context_subinit(&subcall->xreq.context, &caller->context); + subcall->xreq.cred = afb_cred_addref(caller->cred); + subcall->xreq.json = args; + copy = (char*)&subcall[1]; + memcpy(copy, api, lenapi); + subcall->xreq.api = copy; + copy = ©[lenapi]; + memcpy(copy, verb, lenverb); + subcall->xreq.verb = copy; + subcall->caller = caller; + subcall->callback = callback; + subcall->closure = closure; + afb_xreq_addref(caller); + json_object_get(args); /* keep args existing */ + afb_xreq_process(&subcall->xreq, caller->apiset); } - - 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); } -