Adds 2017 to copyrights
[src/app-framework-binder.git] / src / afb-client-demo.c
index 6344d6a..4f8882e 100644 (file)
@@ -1,5 +1,5 @@
-/* 
- * Copyright (C) 2015, 2016 "IoT.bzh"
+/*
+ * Copyright (C) 2015, 2016, 2017 "IoT.bzh"
  * Author "Fulup Ar Foll"
  * Author José Bollo <jose.bollo@iot.bzh>
  *
 
 #include <systemd/sd-event.h>
 
-#include "afb-common.h"  /* TODO: remove dependency to afb-common.h */
 #include "afb-wsj1.h"
 #include "afb-ws-client.h"
 
+/* declaration of functions */
 static void on_hangup(void *closure, struct afb_wsj1 *wsj1);
 static void on_call(void *closure, const char *api, const char *verb, struct afb_wsj1_msg *msg);
 static void on_event(void *closure, const char *event, struct afb_wsj1_msg *msg);
 static int io_event_callback(sd_event_source *src, int fd, uint32_t revents, void *closure);
 static void emit(const char *api, const char *verb, const char *object);
 
+/* the callback interface for wsj1 */
 static struct afb_wsj1_itf itf = {
        .on_hangup = on_hangup,
        .on_call = on_call,
        .on_event = on_event
 };
 
+/* global variables */
 static struct afb_wsj1 *wsj1;
 static int exonrep;
 static int callcount;
 static sd_event_source *evsrc;
 
+/* print usage of the program */
 static void usage(int status, char *arg0)
 {
        char *name = strrchr(arg0, '/');
        name = name ? name + 1 : arg0;
-       fprintf(status ? stderr : stdin, "usage: %s uri [api verb data]\n", name);
+       fprintf(status ? stderr : stdout, "usage: %s uri [api verb [data]]\n", name);
        exit(status);
 }
 
+/* entry function */
 int main(int ac, char **av, char **env)
 {
-       if (ac != 2 && ac != 5)
+       int rc;
+       sd_event *loop;
+
+       /* check the argument count */
+       if (ac != 2 && ac != 4 && ac != 5)
                usage(1, av[0]);
+
+       /* emit error and exit if requested */
        if (!strcmp(av[1], "-h") || !strcmp(av[1], "--help"))
                usage(0, av[0]);
 
-       wsj1 = afb_ws_client_connect_wsj1(av[1], &itf, NULL);
+       /* get the default event loop */
+       rc = sd_event_default(&loop);
+       if (rc < 0) {
+               fprintf(stderr, "connection to default event loop failed: %s\n", strerror(-rc));
+               return 1;
+       }
+
+       /* connect the websocket wsj1 to the uri given by the first argument */
+       wsj1 = afb_ws_client_connect_wsj1(loop, av[1], &itf, NULL);
        if (wsj1 == NULL) {
                fprintf(stderr, "connection to %s failed: %m\n", av[1]);
                return 1;
        }
 
+       /* test the behaviour */
        if (ac == 2) {
+               /* get requests from stdin */
                fcntl(0, F_SETFL, O_NONBLOCK);
-               sd_event_add_io(afb_common_get_event_loop(), &evsrc, 0, EPOLLIN, io_event_callback, NULL);
+               sd_event_add_io(loop, &evsrc, 0, EPOLLIN, io_event_callback, NULL);
        } else {
+               /* the request is defined by the arguments */
                exonrep = 1;
                emit(av[2], av[3], av[4]);
        }
+
+       /* loop until end */
        for(;;)
-               sd_event_run(afb_common_get_event_loop(), 30000000);
+               sd_event_run(loop, 30000000);
        return 0;
 }
 
+/* called when wsj1 hangsup */
 static void on_hangup(void *closure, struct afb_wsj1 *wsj1)
 {
        printf("ON-HANGUP\n");
        exit(0);
 }
 
+/* called when wsj1 receives a method invocation */
 static void on_call(void *closure, const char *api, const char *verb, struct afb_wsj1_msg *msg)
 {
        int rc;
@@ -99,20 +124,13 @@ static void on_call(void *closure, const char *api, const char *verb, struct afb
                fprintf(stderr, "replying failed: %m\n");
 }
 
+/* called when wsj1 receives an event */
 static void on_event(void *closure, const char *event, struct afb_wsj1_msg *msg)
 {
        printf("ON-EVENT %s(%s)\n", event, afb_wsj1_msg_object_s(msg));
 }
 
-static void event(const char *event, const char *object)
-{
-       int rc;
-
-       rc = afb_wsj1_send_event_s(wsj1, event, object);
-       if (rc < 0)
-               fprintf(stderr, "sending !%s(%s) failed: %m\n", event, object);
-}
-
+/* called when wsj1 receives a reply */
 static void on_reply(void *closure, struct afb_wsj1_msg *msg)
 {
        printf("ON-REPLY %s: %s\n", (char*)closure, afb_wsj1_msg_object_s(msg));
@@ -123,13 +141,17 @@ static void on_reply(void *closure, struct afb_wsj1_msg *msg)
                exit(0);
 }
 
+/* makes a call */
 static void call(const char *api, const char *verb, const char *object)
 {
        static int num = 0;
        char *key;
        int rc;
 
+       /* allocates an id for the request */
        rc = asprintf(&key, "%d:%s/%s", ++num, api, verb);
+
+       /* send the request */
        callcount++;
        rc = afb_wsj1_call_s(wsj1, api, verb, object, on_reply, key);
        if (rc < 0) {
@@ -138,14 +160,28 @@ static void call(const char *api, const char *verb, const char *object)
        }
 }
 
+/* sends an event */
+static void event(const char *event, const char *object)
+{
+       int rc;
+
+       rc = afb_wsj1_send_event_s(wsj1, event, object);
+       if (rc < 0)
+               fprintf(stderr, "sending !%s(%s) failed: %m\n", event, object);
+}
+
+/* emits either a call (when api!='!') or an event */
 static void emit(const char *api, const char *verb, const char *object)
 {
+       if (object == NULL || object[0] == 0)
+               object = "null";
        if (api[0] == '!' && api[1] == 0)
                event(verb, object);
        else
                call(api, verb, object);
 }
 
+/* called when something happens on stdin */
 static int io_event_callback(sd_event_source *src, int fd, uint32_t revents, void *closure)
 {
        static size_t count = 0;
@@ -171,7 +207,7 @@ static int io_event_callback(sd_event_source *src, int fd, uint32_t revents, voi
        count += (size_t)rc;
 
        /* normalise the buffer content */
-       /* TODO: handle backspace \x7f */
+       /* TODO: handle backspace \x7f */
 
        /* process the lines */
        pos = 0;
@@ -186,7 +222,7 @@ static int io_event_callback(sd_event_source *src, int fd, uint32_t revents, voi
                rest[0] = i; while(i < count && line[i] != '\n') i++; rest[1] = i;
                if (i == count) break;
                line[i++] = 0;
-               if (api[0] == api[1] || verb[0] == verb[1] || rest[0] == rest[1])
+               if (api[0] == api[1] || verb[0] == verb[1])
                        fprintf(stderr, "bad line: %s\n", line+pos);
                else {
                        line[api[1]] = line[verb[1]] = 0;