X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=plugins%2Fsamples%2FHelloWorld.c;h=b6f49b78c876a293387821e42fc2d67ce333b0fe;hb=39c2ebc125fcc694ac349ae196b62729c7f05037;hp=2714ef4e6a6a607f883c0fffcfe1a3c6acacc2ef;hpb=3bbfb37bb4572a110122b1a83e21261108a65460;p=src%2Fapp-framework-binder.git diff --git a/plugins/samples/HelloWorld.c b/plugins/samples/HelloWorld.c index 2714ef4e..b6f49b78 100644 --- a/plugins/samples/HelloWorld.c +++ b/plugins/samples/HelloWorld.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 "IoT.bzh" + * Copyright (C) 2015, 2016 "IoT.bzh" * Author "Fulup Ar Foll" * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,12 +17,95 @@ #define _GNU_SOURCE #include #include -#include +#include -#include "afb-plugin.h" +#include const struct AFB_interface *interface; +struct event +{ + struct event *next; + struct afb_event event; + char tag[1]; +}; + +static struct event *events = 0; + +/* searchs the event of tag */ +static struct event *event_get(const char *tag) +{ + struct event *e = events; + while(e && strcmp(e->tag, tag)) + e = e->next; + return e; +} + +/* deletes the event of tag */ +static int event_del(const char *tag) +{ + struct event *e, **p; + + /* check exists */ + e = event_get(tag); + if (!e) return -1; + + /* unlink */ + p = &events; + while(*p != e) p = &(*p)->next; + *p = e->next; + + /* destroys */ + afb_event_drop(e->event); + free(e); + return 0; +} + +/* creates the event of tag */ +static int event_add(const char *tag, const char *name) +{ + struct event *e; + + /* check valid tag */ + e = event_get(tag); + if (e) return -1; + + /* creation */ + e = malloc(strlen(tag) + sizeof *e); + if (!e) return -1; + strcpy(e->tag, tag); + + /* make the event */ + e->event = afb_daemon_make_event(interface->daemon, name); + if (!e->event.closure) { free(e); return -1; } + + /* link */ + e->next = events; + events = e; + return 0; +} + +static int event_subscribe(struct afb_req request, const char *tag) +{ + struct event *e; + e = event_get(tag); + return e ? afb_req_subscribe(request, e->event) : -1; +} + +static int event_unsubscribe(struct afb_req request, const char *tag) +{ + struct event *e; + e = event_get(tag); + return e ? afb_req_unsubscribe(request, e->event) : -1; +} + +static int event_push(struct json_object *args, const char *tag) +{ + struct event *e; + e = event_get(tag); + return e ? afb_event_push(e->event, json_object_get(args)) : -1; +} + // Sample Generic Ping Debug API static void ping(struct afb_req request, json_object *jresp, const char *tag) { @@ -54,7 +137,7 @@ static void pingBug (struct afb_req request) static void pingEvent(struct afb_req request) { json_object *query = afb_req_json(request); - afb_evmgr_push(afb_daemon_get_evmgr(interface->daemon), "event", query); + afb_daemon_broadcast_event(interface->daemon, "event", json_object_get(query)); ping(request, json_object_get(query), "event"); } @@ -76,26 +159,120 @@ static void pingJson (struct afb_req request) { ping(request, jresp, "pingJson"); } +static void subcallcb (void *prequest, int iserror, json_object *object) +{ + struct afb_req request = afb_req_unstore(prequest); + if (iserror) + afb_req_fail(request, "failed", json_object_to_json_string(object)); + else + afb_req_success(request, object, NULL); + afb_req_unref(request); +} + +static void subcall (struct afb_req request) +{ + const char *api = afb_req_value(request, "api"); + const char *verb = afb_req_value(request, "verb"); + const char *args = afb_req_value(request, "args"); + json_object *object = api && verb && args ? json_tokener_parse(args) : NULL; + + if (object == NULL) + afb_req_fail(request, "failed", "bad arguments"); + else + afb_req_subcall(request, api, verb, object, subcallcb, afb_req_store(request)); +} + +static void eventadd (struct afb_req request) +{ + const char *tag = afb_req_value(request, "tag"); + const char *name = afb_req_value(request, "name"); + + if (tag == NULL || name == NULL) + afb_req_fail(request, "failed", "bad arguments"); + else if (0 != event_add(tag, name)) + afb_req_fail(request, "failed", "creation error"); + else + afb_req_success(request, NULL, NULL); +} + +static void eventdel (struct afb_req request) +{ + const char *tag = afb_req_value(request, "tag"); + + if (tag == NULL) + afb_req_fail(request, "failed", "bad arguments"); + else if (0 != event_del(tag)) + afb_req_fail(request, "failed", "deletion error"); + else + afb_req_success(request, NULL, NULL); +} + +static void eventsub (struct afb_req request) +{ + const char *tag = afb_req_value(request, "tag"); + + if (tag == NULL) + afb_req_fail(request, "failed", "bad arguments"); + else if (0 != event_subscribe(request, tag)) + afb_req_fail(request, "failed", "subscription error"); + else + afb_req_success(request, NULL, NULL); +} + +static void eventunsub (struct afb_req request) +{ + const char *tag = afb_req_value(request, "tag"); + + if (tag == NULL) + afb_req_fail(request, "failed", "bad arguments"); + else if (0 != event_unsubscribe(request, tag)) + afb_req_fail(request, "failed", "unsubscription error"); + else + afb_req_success(request, NULL, NULL); +} + +static void eventpush (struct afb_req request) +{ + const char *tag = afb_req_value(request, "tag"); + const char *data = afb_req_value(request, "data"); + json_object *object = data ? json_tokener_parse(data) : NULL; + + if (tag == NULL) + afb_req_fail(request, "failed", "bad arguments"); + else if (0 > event_push(object, tag)) + afb_req_fail(request, "failed", "push error"); + else + afb_req_success(request, NULL, NULL); +} + // NOTE: this sample does not use session to keep test a basic as possible // in real application most APIs should be protected with AFB_SESSION_CHECK -static const struct AFB_restapi pluginApis[]= { +static const struct AFB_verb_desc_v1 verbs[]= { {"ping" , AFB_SESSION_NONE, pingSample , "Ping Application Framework"}, {"pingfail" , AFB_SESSION_NONE, pingFail , "Fails"}, {"pingnull" , AFB_SESSION_NONE, pingNull , "Return NULL"}, {"pingbug" , AFB_SESSION_NONE, pingBug , "Do a Memory Violation"}, {"pingJson" , AFB_SESSION_NONE, pingJson , "Return a JSON object"}, {"pingevent", AFB_SESSION_NONE, pingEvent , "Send an event"}, + {"subcall", AFB_SESSION_NONE, subcall , "Call api/verb(args)"}, + {"eventadd", AFB_SESSION_NONE, eventadd , "adds the event of 'name' for the 'tag'"}, + {"eventdel", AFB_SESSION_NONE, eventdel , "deletes the event of 'tag'"}, + {"eventsub", AFB_SESSION_NONE, eventsub , "subscribes to the event of 'tag'"}, + {"eventunsub",AFB_SESSION_NONE, eventunsub , "unsubscribes to the event of 'tag'"}, + {"eventpush", AFB_SESSION_NONE, eventpush , "pushs the event of 'tag' with the 'data'"}, {NULL} }; static const struct AFB_plugin plugin_desc = { - .type = AFB_PLUGIN_JSON, - .info = "Minimal Hello World Sample", - .prefix = "hello", - .apis = pluginApis + .type = AFB_PLUGIN_VERSION_1, + .v1 = { + .info = "Minimal Hello World Sample", + .prefix = "hello", + .verbs = verbs + } }; -const struct AFB_plugin *pluginRegister (const struct AFB_interface *itf) +const struct AFB_plugin *pluginAfbV1Register (const struct AFB_interface *itf) { interface = itf; return &plugin_desc;