improves documentation
authorJosé Bollo <jose.bollo@iot.bzh>
Fri, 27 May 2016 20:18:26 +0000 (22:18 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Fri, 27 May 2016 20:18:26 +0000 (22:18 +0200)
Change-Id: Idbd1b735571c2e35daed23d43f8d5d3990881533
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
doc/FAQ.html
doc/FAQ.md
doc/afb-daemon-vocabulary.html
doc/afb-daemon-vocabulary.md
doc/afb-plugin-writing.html
doc/afb-plugin-writing.md
include/afb/afb-plugin.h
plugins/samples/HelloWorld.c
plugins/samples/tic-tac-toe.c

index ffda81a..9833781 100644 (file)
@@ -8,7 +8,7 @@
 <h1>Frequently Asked Question about AFB-DAEMON</h1>
 
 <pre><code>version: 1
 <h1>Frequently Asked Question about AFB-DAEMON</h1>
 
 <pre><code>version: 1
-Date:    26 mai 2016
+Date:    27 mai 2016
 Author:  José Bollo
 </code></pre>
 
 Author:  José Bollo
 </code></pre>
 
index 9364731..6110582 100644 (file)
@@ -1,7 +1,7 @@
 Frequently Asked Question about AFB-DAEMON
 ==========================================
     version: 1
 Frequently Asked Question about AFB-DAEMON
 ==========================================
     version: 1
-    Date:    26 mai 2016
+    Date:    27 mai 2016
     Author:  José Bollo
 
 TABLE-OF-CONTENT-HERE
     Author:  José Bollo
 
 TABLE-OF-CONTENT-HERE
index 096f507..fadd1de 100644 (file)
@@ -8,7 +8,7 @@
 <h1>Vocabulary for AFB-DAEMON</h1>
 
 <pre><code>version: 1
 <h1>Vocabulary for AFB-DAEMON</h1>
 
 <pre><code>version: 1
-Date:    26 mai 2016
+Date:    27 mai 2016
 Author:  José Bollo
 </code></pre>
 
 Author:  José Bollo
 </code></pre>
 
index 7177194..8427b73 100644 (file)
@@ -1,7 +1,7 @@
 Vocabulary for AFB-DAEMON
 =========================
     version: 1
 Vocabulary for AFB-DAEMON
 =========================
     version: 1
-    Date:    26 mai 2016
+    Date:    27 mai 2016
     Author:  José Bollo
 
 TABLE-OF-CONTENT-HERE
     Author:  José Bollo
 
 TABLE-OF-CONTENT-HERE
index 9a98ffe..9873b62 100644 (file)
@@ -37,6 +37,8 @@ Author:  José Bollo
   </ul>
   </li>
   <li><a href="#The.Tic-Tac-Toe.example">The Tic-Tac-Toe example</a></li>
   </ul>
   </li>
   <li><a href="#The.Tic-Tac-Toe.example">The Tic-Tac-Toe example</a></li>
+  <li><a href="#Dependencies.when.compiling">Dependencies when compiling</a></li>
+  <li><a href="#Header.files.to.include">Header files to include</a></li>
   <li><a href="#Choosing.names">Choosing names</a>
   <ul>
    <li><a href="#Names.for.API..plugin.">Names for API (plugin)</a></li>
   <li><a href="#Choosing.names">Choosing names</a>
   <ul>
    <li><a href="#Names.for.API..plugin.">Names for API (plugin)</a></li>
@@ -45,8 +47,6 @@ Author:  José Bollo
    <li><a href="#Forging.names.widely.available">Forging names widely available</a></li>
   </ul>
   </li>
    <li><a href="#Forging.names.widely.available">Forging names widely available</a></li>
   </ul>
   </li>
-  <li><a href="#Options.to.set.when.compiling.plugins">Options to set when compiling plugins</a></li>
-  <li><a href="#Header.files.to.include">Header files to include</a></li>
   <li><a href="#Writing.a.synchronous.verb.implementation">Writing a synchronous verb implementation</a>
   <ul>
    <li><a href="#The.incoming.request">The incoming request</a></li>
   <li><a href="#Writing.a.synchronous.verb.implementation">Writing a synchronous verb implementation</a>
   <ul>
    <li><a href="#The.incoming.request">The incoming request</a></li>
@@ -265,6 +265,72 @@ This plugin example is in <em>plugins/samples/tic-tac-toe.c</em>.</p>
 
 <p>This plugin is named <strong><em>tictactoe</em></strong>.</p>
 
 
 <p>This plugin is named <strong><em>tictactoe</em></strong>.</p>
 
+<a name="Dependencies.when.compiling"></a>
+<h2>Dependencies when compiling</h2>
+
+<p>Afb-daemon provides a configuration file for <em>pkg-config</em>.
+Typing the command</p>
+
+<pre><code>pkg-config --cflags afb-daemon
+</code></pre>
+
+<p>will print the flags to use for compiling, like this:</p>
+
+<pre><code>$ pkg-config --cflags afb-daemon
+-I/opt/local/include -I/usr/include/json-c 
+</code></pre>
+
+<p>For linking, you should use</p>
+
+<pre><code>$ pkg-config --libs afb-daemon
+-ljson-c
+</code></pre>
+
+<p>As you see, afb-daemon automatically includes dependency to json-c.
+This is done through the <strong>Requires</strong> keyword of pkg-config
+because almost all plugin will use <strong>json-c</strong>.</p>
+
+<p>If this behaviour is a problem, let us know.</p>
+
+<p>Internally, afb-daemon uses <strong>libsystemd</strong> for its event loop
+and for its binding to D-Bus.
+Plugins developpers are encouraged to also use this library.
+But it is a matter of choice.
+Thus there is no dependency to <strong>libsystemd</strong>.</p>
+
+<blockquote><p>Afb-daemon provides no library for plugins.
+The functions that the plugin need to have are given
+to the plugin at runtime through pointer using read-only
+memory.</p></blockquote>
+
+<a name="Header.files.to.include"></a>
+<h2>Header files to include</h2>
+
+<p>The plugin <em>tictactoe</em> has the following lines for its includes:</p>
+
+<pre><code>#define _GNU_SOURCE
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;json-c/json.h&gt;
+#include &lt;afb/afb-plugin.h&gt;
+</code></pre>
+
+<p>The header <em>afb/afb-plugin.h</em> includes all the features that a plugin
+needs except two foreign header that must be included by the plugin
+if it needs it:</p>
+
+<ul>
+<li><em>json-c/json.h</em>: this header must be include to handle json objects;</li>
+<li><em>systemd/sd-event.h</em>: this must be include to access the main loop;</li>
+<li><em>systemd/sd-bus.h</em>: this may be include to use dbus connections.</li>
+</ul>
+
+
+<p>The <em>tictactoe</em> plugin does not use systemd features so it is not included.</p>
+
+<p>When including <em>afb/afb-plugin.h</em>, the macro <strong>_GNU_SOURCE</strong> must be
+defined.</p>
+
 <a name="Choosing.names"></a>
 <h2>Choosing names</h2>
 
 <a name="Choosing.names"></a>
 <h2>Choosing names</h2>
 
@@ -344,60 +410,6 @@ valid javascript identifier.</p>
 rely on the case sensitivity and to avoid the use of
 names different only by the case.</p>
 
 rely on the case sensitivity and to avoid the use of
 names different only by the case.</p>
 
-<a name="Options.to.set.when.compiling.plugins"></a>
-<h2>Options to set when compiling plugins</h2>
-
-<p>Afb-daemon provides a configuration file for <em>pkg-config</em>.
-Typing the command</p>
-
-<pre><code>pkg-config --cflags afb-daemon
-</code></pre>
-
-<p>will print the flags to use for compiling, like this:</p>
-
-<pre><code>$ pkg-config --cflags afb-daemon
--I/opt/local/include -I/usr/include/json-c 
-</code></pre>
-
-<p>For linking, you should use</p>
-
-<pre><code>$ pkg-config --libs afb-daemon
--ljson-c
-</code></pre>
-
-<p>As you see, afb-daemon automatically includes dependency to json-c.
-This is done through the <strong>Requires</strong> keyword of pkg-config.</p>
-
-<p>If this behaviour is a problem, let us know.</p>
-
-<a name="Header.files.to.include"></a>
-<h2>Header files to include</h2>
-
-<p>The plugin <em>tictactoe</em> has the following lines for its includes:</p>
-
-<pre><code>#define _GNU_SOURCE
-#include &lt;stdio.h&gt;
-#include &lt;string.h&gt;
-#include &lt;json-c/json.h&gt;
-#include &lt;afb/afb-plugin.h&gt;
-</code></pre>
-
-<p>The header <em>afb/afb-plugin.h</em> includes all the features that a plugin
-needs except two foreign header that must be included by the plugin
-if it needs it:</p>
-
-<ul>
-<li><em>json-c/json.h</em>: this header must be include to handle json objects;</li>
-<li><em>systemd/sd-event.h</em>: this must be include to access the main loop;</li>
-<li><em>systemd/sd-bus.h</em>: this may be include to use dbus connections.</li>
-</ul>
-
-
-<p>The <em>tictactoe</em> plugin does not use systemd features so it is not included.</p>
-
-<p>When including <em>afb/afb-plugin.h</em>, the macro <strong>_GNU_SOURCE</strong> must be
-defined.</p>
-
 <a name="Writing.a.synchronous.verb.implementation"></a>
 <h2>Writing a synchronous verb implementation</h2>
 
 <a name="Writing.a.synchronous.verb.implementation"></a>
 <h2>Writing a synchronous verb implementation</h2>
 
@@ -879,7 +891,7 @@ const struct AFB_interface *afbitf;
 static const struct AFB_verb_desc_v1 plugin_verbs[] = {
    /* VERB'S NAME     SESSION MANAGEMENT          FUNCTION TO CALL  SHORT DESCRIPTION */
    { .name= "new",   .session= AFB_SESSION_NONE, .callback= new,   .info= "Starts a new game" },
 static const struct AFB_verb_desc_v1 plugin_verbs[] = {
    /* VERB'S NAME     SESSION MANAGEMENT          FUNCTION TO CALL  SHORT DESCRIPTION */
    { .name= "new",   .session= AFB_SESSION_NONE, .callback= new,   .info= "Starts a new game" },
-   { .name= "play",  .session= AFB_SESSION_NONE, .callback= play,  .info= "Tells the server to play" },
+   { .name= "play",  .session= AFB_SESSION_NONE, .callback= play,  .info= "Asks the server to play" },
    { .name= "move",  .session= AFB_SESSION_NONE, .callback= move,  .info= "Tells the client move" },
    { .name= "board", .session= AFB_SESSION_NONE, .callback= board, .info= "Get the current board" },
    { .name= "level", .session= AFB_SESSION_NONE, .callback= level, .info= "Set the server level" },
    { .name= "move",  .session= AFB_SESSION_NONE, .callback= move,  .info= "Tells the client move" },
    { .name= "board", .session= AFB_SESSION_NONE, .callback= board, .info= "Get the current board" },
    { .name= "level", .session= AFB_SESSION_NONE, .callback= level, .info= "Set the server level" },
@@ -1196,9 +1208,85 @@ journal, syslog or kmsg. (See man sd-daemon).</p>
 <a name="Sending.events"></a>
 <h2>Sending events</h2>
 
 <a name="Sending.events"></a>
 <h2>Sending events</h2>
 
+<p>Since version 0.5, plugins can broadcast events to any potential listener.
+This kind of bradcast is not targeted. Event targeted will come in a future
+version of afb-daemon.</p>
+
+<p>The plugin <em>tic-tac-toe</em> broadcasts events when the board changes.
+This is done in the function <strong>changed</strong>:</p>
+
+<pre><code>/*
+ * signals a change of the board
+ */
+static void changed(struct board *board, const char *reason)
+{
+        ...
+        struct json_object *description;
+
+        /* get the description */
+        description = describe(board);
+
+        ...
+
+        afb_daemon_broadcast_event(afbitf-&gt;daemon, reason, description);
+}
+</code></pre>
+
+<p>The description of the changed board is pushed via the daemon interface.</p>
+
+<p>Within the plugin <em>tic-tac-toe</em>, the <em>reason</em> indicates the origin of
+the change. For the function <strong>afb_daemon_broadcast_event</strong>, the second
+parameter is the name of the broadcasted event. The third argument is the
+object that is transmitted with the event.</p>
+
+<p>The function <strong>afb_daemon_broadcast_event</strong> is defined as below:</p>
+
+<pre><code>/*
+ * Broadcasts widely the event of 'name' with the data 'object'.
+ * 'object' can be NULL.
+ * 'daemon' MUST be the daemon given in interface when activating the plugin.
+ */
+void afb_daemon_broadcast_event(struct afb_daemon daemon, const char *name, struct json_object *object);
+</code></pre>
+
+<p>In fact the event name received by the listener is prefixed with
+the name of the plugin. So when the change occurs after a move, the
+reason is <strong>move</strong> and then the clients receive the event <strong>tictactoe/move</strong>.</p>
+
+<blockquote><p>Note that nothing is said about the case sensitivity of event names.
+However, the event is always prefixed with the name that the plugin
+declared, with the same case, followed with a slash /.
+Thus it is safe to compare event using a case sensitive comparison.</p></blockquote>
+
 <a name="Writing.an.asynchronous.verb.implementation"></a>
 <h2>Writing an asynchronous verb implementation</h2>
 
 <a name="Writing.an.asynchronous.verb.implementation"></a>
 <h2>Writing an asynchronous verb implementation</h2>
 
+<p>/<em>
+ * signals a change of the board
+ </em>/
+static void changed(struct board <em>board, const char </em>reason)
+{
+    struct waiter <em>waiter, </em>next;
+    struct json_object *description;</p>
+
+<pre><code>/* get the description */
+description = describe(board);
+
+waiter = board-&gt;waiters;
+board-&gt;waiters = NULL;
+while (waiter != NULL) {
+        next = waiter-&gt;next;
+        afb_req_success(waiter-&gt;req, json_object_get(description), reason);
+        afb_req_unref(waiter-&gt;req);
+        free(waiter);
+        waiter = next;
+}
+
+afb_event_sender_push(afb_daemon_get_event_sender(afbitf-&gt;daemon), reason, description);
+</code></pre>
+
+<p>}</p>
+
 <a name="How.to.build.a.plugin"></a>
 <h2>How to build a plugin</h2>
 
 <a name="How.to.build.a.plugin"></a>
 <h2>How to build a plugin</h2>
 
index 734b15a..7861021 100644 (file)
@@ -178,6 +178,65 @@ This plugin example is in *plugins/samples/tic-tac-toe.c*.
 
 This plugin is named ***tictactoe***.
 
 
 This plugin is named ***tictactoe***.
 
+Dependencies when compiling
+---------------------------
+
+Afb-daemon provides a configuration file for *pkg-config*.
+Typing the command
+
+       pkg-config --cflags afb-daemon
+
+will print the flags to use for compiling, like this:
+
+       $ pkg-config --cflags afb-daemon
+       -I/opt/local/include -I/usr/include/json-c 
+
+For linking, you should use
+
+       $ pkg-config --libs afb-daemon
+       -ljson-c
+
+As you see, afb-daemon automatically includes dependency to json-c.
+This is done through the **Requires** keyword of pkg-config
+because almost all plugin will use **json-c**.
+
+If this behaviour is a problem, let us know.
+
+Internally, afb-daemon uses **libsystemd** for its event loop
+and for its binding to D-Bus.
+Plugins developpers are encouraged to also use this library.
+But it is a matter of choice.
+Thus there is no dependency to **libsystemd**.
+
+> Afb-daemon provides no library for plugins.
+> The functions that the plugin need to have are given
+> to the plugin at runtime through pointer using read-only
+> memory.
+
+Header files to include
+-----------------------
+
+The plugin *tictactoe* has the following lines for its includes:
+
+       #define _GNU_SOURCE
+       #include <stdio.h>
+       #include <string.h>
+       #include <json-c/json.h>
+       #include <afb/afb-plugin.h>
+
+The header *afb/afb-plugin.h* includes all the features that a plugin
+needs except two foreign header that must be included by the plugin
+if it needs it:
+
+- *json-c/json.h*: this header must be include to handle json objects;
+- *systemd/sd-event.h*: this must be include to access the main loop;
+- *systemd/sd-bus.h*: this may be include to use dbus connections.
+
+The *tictactoe* plugin does not use systemd features so it is not included.
+
+When including *afb/afb-plugin.h*, the macro **_GNU_SOURCE** must be
+defined.
+
 Choosing names
 --------------
 
 Choosing names
 --------------
 
@@ -248,53 +307,6 @@ It is also a good practice, even for arguments, to not
 rely on the case sensitivity and to avoid the use of
 names different only by the case.
 
 rely on the case sensitivity and to avoid the use of
 names different only by the case.
 
-Options to set when compiling plugins
--------------------------------------
-
-Afb-daemon provides a configuration file for *pkg-config*.
-Typing the command
-
-       pkg-config --cflags afb-daemon
-
-will print the flags to use for compiling, like this:
-
-       $ pkg-config --cflags afb-daemon
-       -I/opt/local/include -I/usr/include/json-c 
-
-For linking, you should use
-
-       $ pkg-config --libs afb-daemon
-       -ljson-c
-
-As you see, afb-daemon automatically includes dependency to json-c.
-This is done through the **Requires** keyword of pkg-config.
-
-If this behaviour is a problem, let us know.
-
-Header files to include
------------------------
-
-The plugin *tictactoe* has the following lines for its includes:
-
-       #define _GNU_SOURCE
-       #include <stdio.h>
-       #include <string.h>
-       #include <json-c/json.h>
-       #include <afb/afb-plugin.h>
-
-The header *afb/afb-plugin.h* includes all the features that a plugin
-needs except two foreign header that must be included by the plugin
-if it needs it:
-
-- *json-c/json.h*: this header must be include to handle json objects;
-- *systemd/sd-event.h*: this must be include to access the main loop;
-- *systemd/sd-bus.h*: this may be include to use dbus connections.
-
-The *tictactoe* plugin does not use systemd features so it is not included.
-
-When including *afb/afb-plugin.h*, the macro **_GNU_SOURCE** must be
-defined.
-
 Writing a synchronous verb implementation
 -----------------------------------------
 
 Writing a synchronous verb implementation
 -----------------------------------------
 
@@ -755,7 +767,7 @@ The description of the plugin is defined as below.
        static const struct AFB_verb_desc_v1 plugin_verbs[] = {
           /* VERB'S NAME     SESSION MANAGEMENT          FUNCTION TO CALL  SHORT DESCRIPTION */
           { .name= "new",   .session= AFB_SESSION_NONE, .callback= new,   .info= "Starts a new game" },
        static const struct AFB_verb_desc_v1 plugin_verbs[] = {
           /* VERB'S NAME     SESSION MANAGEMENT          FUNCTION TO CALL  SHORT DESCRIPTION */
           { .name= "new",   .session= AFB_SESSION_NONE, .callback= new,   .info= "Starts a new game" },
-          { .name= "play",  .session= AFB_SESSION_NONE, .callback= play,  .info= "Tells the server to play" },
+          { .name= "play",  .session= AFB_SESSION_NONE, .callback= play,  .info= "Asks the server to play" },
           { .name= "move",  .session= AFB_SESSION_NONE, .callback= move,  .info= "Tells the client move" },
           { .name= "board", .session= AFB_SESSION_NONE, .callback= board, .info= "Get the current board" },
           { .name= "level", .session= AFB_SESSION_NONE, .callback= level, .info= "Set the server level" },
           { .name= "move",  .session= AFB_SESSION_NONE, .callback= move,  .info= "Tells the client move" },
           { .name= "board", .session= AFB_SESSION_NONE, .callback= board, .info= "Get the current board" },
           { .name= "level", .session= AFB_SESSION_NONE, .callback= level, .info= "Set the server level" },
@@ -920,10 +932,81 @@ journal, syslog or kmsg. (See man sd-daemon).
 Sending events
 --------------
 
 Sending events
 --------------
 
+Since version 0.5, plugins can broadcast events to any potential listener.
+This kind of bradcast is not targeted. Event targeted will come in a future
+version of afb-daemon.
+
+The plugin *tic-tac-toe* broadcasts events when the board changes.
+This is done in the function **changed**:
+
+       /*
+        * signals a change of the board
+        */
+       static void changed(struct board *board, const char *reason)
+       {
+               ...
+               struct json_object *description;
+
+               /* get the description */
+               description = describe(board);
+
+               ...
+
+               afb_daemon_broadcast_event(afbitf->daemon, reason, description);
+       }
+
+The description of the changed board is pushed via the daemon interface.
+
+Within the plugin *tic-tac-toe*, the *reason* indicates the origin of
+the change. For the function **afb_daemon_broadcast_event**, the second
+parameter is the name of the broadcasted event. The third argument is the
+object that is transmitted with the event.
+
+The function **afb_daemon_broadcast_event** is defined as below:
+
+       /*
+        * Broadcasts widely the event of 'name' with the data 'object'.
+        * 'object' can be NULL.
+        * 'daemon' MUST be the daemon given in interface when activating the plugin.
+        */
+       void afb_daemon_broadcast_event(struct afb_daemon daemon, const char *name, struct json_object *object);
+
+In fact the event name received by the listener is prefixed with
+the name of the plugin. So when the change occurs after a move, the
+reason is **move** and then the clients receive the event **tictactoe/move**.
+
+> Note that nothing is said about the case sensitivity of event names.
+> However, the event is always prefixed with the name that the plugin
+> declared, with the same case, followed with a slash /.
+> Thus it is safe to compare event using a case sensitive comparison.
+
 
 Writing an asynchronous verb implementation
 -------------------------------------------
 
 
 Writing an asynchronous verb implementation
 -------------------------------------------
 
+/*
+ * signals a change of the board
+ */
+static void changed(struct board *board, const char *reason)
+{
+       struct waiter *waiter, *next;
+       struct json_object *description;
+
+       /* get the description */
+       description = describe(board);
+
+       waiter = board->waiters;
+       board->waiters = NULL;
+       while (waiter != NULL) {
+               next = waiter->next;
+               afb_req_success(waiter->req, json_object_get(description), reason);
+               afb_req_unref(waiter->req);
+               free(waiter);
+               waiter = next;
+       }
+
+       afb_event_sender_push(afb_daemon_get_event_sender(afbitf->daemon), reason, description);
+}
 
 How to build a plugin
 ---------------------
 
 How to build a plugin
 ---------------------
index cad55fb..3d16c7a 100644 (file)
@@ -56,10 +56,10 @@ enum  AFB_plugin_version
  */
 enum AFB_session_v1
 {
  */
 enum AFB_session_v1
 {
-       AFB_SESSION_NONE = 0,   /* no session and no authentification required */
-       AFB_SESSION_CREATE = 1, /* obsolete */
-       AFB_SESSION_CLOSE = 2,  /* closes the session after authentification */
-       AFB_SESSION_RENEW = 4,  /* refreshes the token after authentification */
+       AFB_SESSION_NONE = 0,   /* nothing required */
+       AFB_SESSION_CREATE = 1, /* Obsolete */
+       AFB_SESSION_CLOSE = 2,  /* After token authentification, closes the session at end */
+       AFB_SESSION_RENEW = 4,  /* After token authentification, refreshes the token at end */
        AFB_SESSION_CHECK = 8,  /* Requires token authentification */
 
        AFB_SESSION_LOA_GE = 16, /* check that the LOA is greater or equal to the given value */
        AFB_SESSION_CHECK = 8,  /* Requires token authentification */
 
        AFB_SESSION_LOA_GE = 16, /* check that the LOA is greater or equal to the given value */
@@ -67,12 +67,13 @@ enum AFB_session_v1
        AFB_SESSION_LOA_EQ = 48, /* check that the LOA is equal to the given value */
 
        AFB_SESSION_LOA_SHIFT = 6, /* shift for LOA */
        AFB_SESSION_LOA_EQ = 48, /* check that the LOA is equal to the given value */
 
        AFB_SESSION_LOA_SHIFT = 6, /* shift for LOA */
-       AFB_SESSION_LOA_MASK = 3,  /* mask for LOA */
+       AFB_SESSION_LOA_MASK = 7,  /* mask for LOA */
 
        AFB_SESSION_LOA_0 = 0,   /* value for LOA of 0 */
        AFB_SESSION_LOA_1 = 64,  /* value for LOA of 1 */
        AFB_SESSION_LOA_2 = 128, /* value for LOA of 2 */
        AFB_SESSION_LOA_3 = 192, /* value for LOA of 3 */
 
        AFB_SESSION_LOA_0 = 0,   /* value for LOA of 0 */
        AFB_SESSION_LOA_1 = 64,  /* value for LOA of 1 */
        AFB_SESSION_LOA_2 = 128, /* value for LOA of 2 */
        AFB_SESSION_LOA_3 = 192, /* value for LOA of 3 */
+       AFB_SESSION_LOA_4 = 256, /* value for LOA of 4 */
 
        AFB_SESSION_LOA_LE_0 = AFB_SESSION_LOA_LE | AFB_SESSION_LOA_0, /* check LOA <= 0 */
        AFB_SESSION_LOA_LE_1 = AFB_SESSION_LOA_LE | AFB_SESSION_LOA_1, /* check LOA <= 1 */
 
        AFB_SESSION_LOA_LE_0 = AFB_SESSION_LOA_LE | AFB_SESSION_LOA_0, /* check LOA <= 0 */
        AFB_SESSION_LOA_LE_1 = AFB_SESSION_LOA_LE | AFB_SESSION_LOA_1, /* check LOA <= 1 */
@@ -207,6 +208,16 @@ static inline struct sd_bus *afb_daemon_get_system_bus(struct afb_daemon daemon)
        return daemon.itf->get_system_bus(daemon.closure);
 }
 
        return daemon.itf->get_system_bus(daemon.closure);
 }
 
+/*
+ * Broadcasts widely the event of 'name' with the data 'object'.
+ * 'object' can be NULL.
+ * 'daemon' MUST be the daemon given in interface when activating the plugin.
+ */
+static inline void afb_daemon_broadcast_event(struct afb_daemon daemon, const char *name, struct json_object *object)
+{
+       return afb_event_sender_push(afb_daemon_get_event_sender(daemon), name, object);
+}
+
 /*
  * Send a message described by 'fmt' and following parameters
  * to the journal for the verbosity 'level'.
 /*
  * Send a message described by 'fmt' and following parameters
  * to the journal for the verbosity 'level'.
index 78a1eaf..fe11784 100644 (file)
@@ -54,8 +54,8 @@ static void pingBug (struct afb_req request)
 static void pingEvent(struct afb_req request)
 {
        json_object *query = afb_req_json(request);
 static void pingEvent(struct afb_req request)
 {
        json_object *query = afb_req_json(request);
-       afb_event_sender_push(afb_daemon_get_event_sender(interface->daemon), "event", query);
-       ping(request, json_object_get(query), "event");
+       afb_daemon_broadcast_event(interface->daemon, "event", json_object_get(query));
+       ping(request, query, "event");
 }
 
 
 }
 
 
index 79aaaf5..c372e99 100644 (file)
@@ -299,7 +299,7 @@ static void changed(struct board *board, const char *reason)
                waiter = next;
        }
 
                waiter = next;
        }
 
-       afb_event_sender_push(afb_daemon_get_event_sender(afbitf->daemon), reason, description);
+       afb_daemon_broadcast_event(afbitf->daemon, reason, description);
 }
 
 /*
 }
 
 /*
@@ -586,7 +586,7 @@ static void wait(struct afb_req req)
 static const struct AFB_verb_desc_v1 plugin_verbs[] = {
    /* VERB'S NAME     SESSION MANAGEMENT          FUNCTION TO CALL  SHORT DESCRIPTION */
    { .name= "new",   .session= AFB_SESSION_NONE, .callback= new,   .info= "Starts a new game" },
 static const struct AFB_verb_desc_v1 plugin_verbs[] = {
    /* VERB'S NAME     SESSION MANAGEMENT          FUNCTION TO CALL  SHORT DESCRIPTION */
    { .name= "new",   .session= AFB_SESSION_NONE, .callback= new,   .info= "Starts a new game" },
-   { .name= "play",  .session= AFB_SESSION_NONE, .callback= play,  .info= "Tells the server to play" },
+   { .name= "play",  .session= AFB_SESSION_NONE, .callback= play,  .info= "Asks the server to play" },
    { .name= "move",  .session= AFB_SESSION_NONE, .callback= move,  .info= "Tells the client move" },
    { .name= "board", .session= AFB_SESSION_NONE, .callback= board, .info= "Get the current board" },
    { .name= "level", .session= AFB_SESSION_NONE, .callback= level, .info= "Set the server level" },
    { .name= "move",  .session= AFB_SESSION_NONE, .callback= move,  .info= "Tells the client move" },
    { .name= "board", .session= AFB_SESSION_NONE, .callback= board, .info= "Get the current board" },
    { .name= "level", .session= AFB_SESSION_NONE, .callback= level, .info= "Set the server level" },