aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/FAQ.html28
-rw-r--r--doc/FAQ.md1
-rw-r--r--doc/afb-application-writing.html250
-rw-r--r--doc/afb-application-writing.md67
-rw-r--r--doc/afb-bindings-overview.html154
-rw-r--r--doc/afb-bindings-overview.md45
-rw-r--r--doc/afb-bindings-writing.html974
-rw-r--r--doc/afb-bindings-writing.md852
-rw-r--r--doc/afb-daemon-vocabulary.html79
-rw-r--r--doc/afb-daemon-vocabulary.md50
-rw-r--r--doc/afb-events-guide.html282
-rw-r--r--doc/afb-events-guide.md79
-rw-r--r--doc/afb-overview.html316
-rw-r--r--doc/afb-overview.md107
-rw-r--r--doc/afb-tests-overview.html76
-rw-r--r--doc/afb-tests-overview.md2
-rw-r--r--doc/doc.css40
l---------doc/index.md1
-rw-r--r--doc/pictures/AFB_for_services.svg238
-rw-r--r--doc/pictures/AFB_overview.svg140
-rw-r--r--doc/pictures/signaling-basis.svg (renamed from doc/signaling-basis.svg)0
-rw-r--r--doc/pictures/tic-tac-toe.svg289
-rw-r--r--doc/pictures/triskel_iot_bzh.svg (renamed from doc/triskel_iot_bzh.svg)0
-rwxr-xr-xdoc/updt.sh53
-rw-r--r--mkdocs.yml11
25 files changed, 1353 insertions, 2781 deletions
diff --git a/doc/FAQ.html b/doc/FAQ.html
deleted file mode 100644
index f3584e0e..00000000
--- a/doc/FAQ.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <meta name="generator" content="pandoc">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
- <meta name="author" content="José Bollo">
- <title>Frequently Asked Question about AFB-DAEMON</title>
- <style type="text/css">code{white-space: pre;}</style>
- <link rel="stylesheet" href="doc.css">
- <!--[if lt IE 9]>
- <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
- <![endif]-->
-</head>
-<body>
-<header>
-<h1 class="title">Frequently Asked Question about AFB-DAEMON</h1>
-<h2 class="author">José Bollo</h2>
-<h3 class="date">24 juin 2016</h3>
-</header>
-<nav id="TOC">
-<ul>
-<li><a href="#frequently-asked-question-about-afb-daemon">Frequently Asked Question about AFB-DAEMON</a></li>
-</ul>
-</nav>
-<h1 id="frequently-asked-question-about-afb-daemon">Frequently Asked Question about AFB-DAEMON</h1>
-</body>
-</html>
diff --git a/doc/FAQ.md b/doc/FAQ.md
index d485c97e..5063ed74 100644
--- a/doc/FAQ.md
+++ b/doc/FAQ.md
@@ -1,4 +1,3 @@
-
Frequently Asked Question about AFB-DAEMON
==========================================
diff --git a/doc/afb-application-writing.html b/doc/afb-application-writing.html
deleted file mode 100644
index 9d051d5e..00000000
--- a/doc/afb-application-writing.html
+++ /dev/null
@@ -1,250 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <meta name="generator" content="pandoc">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
- <meta name="author" content="José Bollo">
- <meta name="author" content="Fulup Ar Foll">
- <title>HOWTO WRITE an APPLICATION above AGL FRAMEWORK</title>
- <style type="text/css">code{white-space: pre;}</style>
- <style type="text/css">
-div.sourceCode { overflow-x: auto; }
-table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
- margin: 0; padding: 0; vertical-align: baseline; border: none; }
-table.sourceCode { width: 100%; line-height: 100%; }
-td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
-td.sourceCode { padding-left: 5px; }
-code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
-code > span.dt { color: #902000; } /* DataType */
-code > span.dv { color: #40a070; } /* DecVal */
-code > span.bn { color: #40a070; } /* BaseN */
-code > span.fl { color: #40a070; } /* Float */
-code > span.ch { color: #4070a0; } /* Char */
-code > span.st { color: #4070a0; } /* String */
-code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
-code > span.ot { color: #007020; } /* Other */
-code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
-code > span.fu { color: #06287e; } /* Function */
-code > span.er { color: #ff0000; font-weight: bold; } /* Error */
-code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
-code > span.cn { color: #880000; } /* Constant */
-code > span.sc { color: #4070a0; } /* SpecialChar */
-code > span.vs { color: #4070a0; } /* VerbatimString */
-code > span.ss { color: #bb6688; } /* SpecialString */
-code > span.im { } /* Import */
-code > span.va { color: #19177c; } /* Variable */
-code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
-code > span.op { color: #666666; } /* Operator */
-code > span.bu { } /* BuiltIn */
-code > span.ex { } /* Extension */
-code > span.pp { color: #bc7a00; } /* Preprocessor */
-code > span.at { color: #7d9029; } /* Attribute */
-code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
-code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
-code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
-code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
- </style>
- <link rel="stylesheet" href="doc.css">
- <!--[if lt IE 9]>
- <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
- <![endif]-->
-</head>
-<body>
-<header>
-<h1 class="title">HOWTO WRITE an APPLICATION above AGL FRAMEWORK</h1>
-<h2 class="author">José Bollo</h2>
-<h2 class="author">Fulup Ar Foll</h2>
-<h3 class="date">24 juin 2016</h3>
-</header>
-<nav id="TOC">
-<ul>
-<li><a href="#howto-write-an-application-above-agl-framework">HOWTO WRITE an APPLICATION above AGL FRAMEWORK</a><ul>
-<li><a href="#programmation-languages-for-applications">Programmation Languages for Applications</a><ul>
-<li><a href="#writing-an-html5-application">Writing an HTML5 application</a></li>
-<li><a href="#writing-a-qt-application">Writing a Qt application</a></li>
-<li><a href="#writing-c-application">Writing &quot;C&quot; application</a></li>
-</ul></li>
-<li><a href="#handling-sessions-within-applications">Handling sessions within applications</a><ul>
-<li><a href="#handling-sessions">Handling sessions</a></li>
-<li><a href="#exchanging-tokens">Exchanging tokens</a></li>
-<li><a href="#example-of-session-management">Example of session management</a></li>
-</ul></li>
-<li><a href="#format-of-replies">Format of replies</a><ul>
-<li><a href="#template">Template</a></li>
-<li><a href="#field-jtype">Field jtype</a></li>
-<li><a href="#field-request">Field request</a></li>
-<li><a href="#field-response">Field response</a></li>
-</ul></li>
-<li><a href="#format-of-events">Format of events</a><ul>
-<li><a href="#template-1">Template</a></li>
-<li><a href="#field-jtype-1">Field jtype</a></li>
-<li><a href="#field-event">Field event</a></li>
-<li><a href="#field-data">Field data</a></li>
-</ul></li>
-</ul></li>
-</ul>
-</nav>
-<h1 id="howto-write-an-application-above-agl-framework">HOWTO WRITE an APPLICATION above AGL FRAMEWORK</h1>
-<h2 id="programmation-languages-for-applications">Programmation Languages for Applications</h2>
-<h3 id="writing-an-html5-application">Writing an HTML5 application</h3>
-<p>Developers of HTML5 applications (client side) can easily create applications for AGL framework using their preferred HTML5 framework.</p>
-<p>Developers may also take advantage of powerful server side plugins to improve application behavior. Server side plugins return an application/json mine-type and can be accessed though either HTTP or Websockets.</p>
-<p>In a near future, JSON-RPC protocol should be added to complete current x-afb-json1 protocol.</p>
-<p>Two examples of HTML5 applications are given:</p>
-<ul>
-<li><p><a href="https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/app-framework-demo.git;a=tree;f=afb-client">afb-client</a> a simple &quot;hello world&quot; application template</p></li>
-<li><p><a href="https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/app-framework-demo.git;a=tree;f=afm-client">afm-client</a> a simple &quot;Home screen&quot; application template</p></li>
-</ul>
-<h3 id="writing-a-qt-application">Writing a Qt application</h3>
-<p>Writing Qt applications is also supported. Qt offers standard API to send request through HTTP or WebSockets.</p>
-<p>It is also possible to write QML applications. A sample QML application [token-websock] is avaliable..</p>
-<ul>
-<li><a href="https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/app-framework-binder.git;a=blob;f=test/token-websock.qml">token-websock</a> a simple &quot;hello world&quot; application in QML</li>
-</ul>
-<h3 id="writing-c-application">Writing &quot;C&quot; application</h3>
-<p>C applications can use afb-daemon binder through a websocket connection.</p>
-<p>The library <strong>libafbwsc</strong> is provided for C clients that need to connect with an afb-daemon binder.</p>
-<p>The program <strong>afb-client-demo</strong> is the C example that use <strong>libafbwsc</strong> library. Source code is available here <a href="https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/app-framework-binder.git;a=blob;f=src/afb-client-demo.c">src/afb-client-demo.c</a>.</p>
-<p>Current implementation relies on libsystemd and file descriptors. This model might be review in the future to support secure sockets and free the dependency with libsystemd.</p>
-<h2 id="handling-sessions-within-applications">Handling sessions within applications</h2>
-<p>Applications should understand sessions and tokens management when interacting with afb-daemon binder.</p>
-<p>Applications are communicating with their private binder(afb-daemon) using a network connection or potentially any other connection channel. While current version does not yet implement unix domain this feature might be added in a near future. Developers need to be warn that HTTP protocol is a none connected protocol. This prevents from using HTTP socket connection to authenticate clients.</p>
-<p>For this reason, the binder should authenticate the application by using a shared secret. The secret is named &quot;token&quot; and the identification of client is named &quot;session&quot;.</p>
-<p>The examples <strong>token-websock.qml</strong> and <strong>afb-client</strong> are demonstrating how authentication and sessions are managed.</p>
-<h3 id="handling-sessions">Handling sessions</h3>
-<p>Plugins and other binder feature need to keep track of client instances. This is especially important for plugins running as services as they may typically have to keep each client's data separated.</p>
-<p>For HTML5 applications, the web runtime handles the cookie of session that the binder afb-daemon automatically sets.</p>
-<p>Session identifier can be set using the parameter <strong>uuid</strong> or <strong>x-afb-uuid</strong> in URI requests. Within current version of the framework session UUID is supported by both HTTP requests and websocket negotiation.</p>
-<h3 id="exchanging-tokens">Exchanging tokens</h3>
-<p>At application start, AGL framework communicates a shared secret to both binder and client application. This initial secret is called the &quot;initial token&quot;.</p>
-<p>For each of its client application, the binder manages a current active token for session management. This authentication token can be use to restrict access to some plugin's methods.</p>
-<p>The token must be included in URI request on HTTP or during websockets connection using parameter <strong>token</strong> or <strong>x-afb-token</strong>.</p>
-<p>To ensure security, tokens must be refreshed periodically.</p>
-<h3 id="example-of-session-management">Example of session management</h3>
-<p>In following examples, we suppose that <strong>afb-daemon</strong> is launched with something equivalent to:</p>
-<pre><code>$ afb-daemon --port=1234 --token=123456 [...]</code></pre>
-<p>making the expectation that <strong>AuthLogin</strong> plugin is requested as default.</p>
-<h4 id="using-curl">Using curl</h4>
-<p>First, connects with the initial token, 123456:</p>
-<pre><code>$ curl http://localhost:1234/api/auth/connect?token=123456
-{
- &quot;jtype&quot;: &quot;afb-reply&quot;,
- &quot;request&quot;: {
- &quot;status&quot;: &quot;success&quot;,
- &quot;token&quot;: &quot;0aef6841-2ddd-436d-b961-ae78da3b5c5f&quot;,
- &quot;uuid&quot;: &quot;850c4594-1be1-4e9b-9fcc-38cc3e6ff015&quot;
- },
- &quot;response&quot;: {&quot;token&quot;: &quot;A New Token and Session Context Was Created&quot;}
-}</code></pre>
-<p>It returns an answer containing session UUID, 850c4594-1be1-4e9b-9fcc-38cc3e6ff015, and a refreshed token, 850c4594-1be1-4e9b-9fcc-38cc3e6ff015.</p>
-<p>Check if session and token is valid:</p>
-<pre><code>$ curl http://localhost:1234/api/auth/check?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f\&amp;uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
-{
- &quot;jtype&quot;: &quot;afb-reply&quot;,
- &quot;request&quot;: {&quot;status&quot;:&quot;success&quot;},
- &quot;response&quot;: {&quot;isvalid&quot;:true}
-}</code></pre>
-<p>Refresh the token:</p>
-<pre><code>$ curl http://localhost:1234/api/auth/refresh?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f\&amp;uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
-{
- &quot;jtype&quot;: &quot;afb-reply&quot;,
- &quot;request&quot;: {
- &quot;status&quot;:&quot;success&quot;,
- &quot;token&quot;:&quot;b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9&quot;
- },
- &quot;response&quot;: {&quot;token&quot;:&quot;Token was refreshed&quot;}
-}</code></pre>
-<p>Close the session:</p>
-<pre><code>curl http://localhost:1234/api/auth/logout?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9\&amp;uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
-{
- &quot;jtype&quot;: &quot;afb-reply&quot;,
- &quot;request&quot;: {&quot;status&quot;: &quot;success&quot;},
- &quot;response&quot;: {&quot;info&quot;:&quot;Token and all resources are released&quot;}
-}</code></pre>
-<p>Checking on closed session for uuid should be refused:</p>
-<pre><code>curl http://localhost:1234/api/auth/check?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9\&amp;uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
-{
- &quot;jtype&quot;: &quot;afb-reply&quot;,
- &quot;request&quot;: {
- &quot;status&quot;: &quot;failed&quot;,
- &quot;info&quot;: &quot;invalid token&#39;s identity&quot;
- }
-}</code></pre>
-<h4 id="using-afb-client-demo">Using afb-client-demo</h4>
-<blockquote>
-<p>The program is packaged within AGL in the rpm <strong>libafbwsc-dev</strong></p>
-</blockquote>
-<p>Here is an example of exchange using <strong>afb-client-demo</strong>:</p>
-<pre><code>$ afb-client-demo ws://localhost:1234/api?token=123456
-auth connect
-ON-REPLY 1:auth/connect: {&quot;jtype&quot;:&quot;afb-reply&quot;,&quot;request&quot;:{&quot;status&quot;:&quot;success&quot;,
- &quot;token&quot;:&quot;63f71a29-8b52-4f9b-829f-b3028ba46b68&quot;,&quot;uuid&quot;:&quot;5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1&quot;},
- &quot;response&quot;:{&quot;token&quot;:&quot;A New Token and Session Context Was Created&quot;}}
-auth check
-ON-REPLY 2:auth/check: {&quot;jtype&quot;:&quot;afb-reply&quot;,&quot;request&quot;:{&quot;status&quot;:&quot;success&quot;},&quot;response&quot;:{&quot;isvalid&quot;:true}}
-auth refresh
-ON-REPLY 4:auth/refresh: {&quot;jtype&quot;:&quot;afb-reply&quot;,&quot;request&quot;:{&quot;status&quot;:&quot;success&quot;,
- &quot;token&quot;:&quot;8b8ba8f4-1b0c-48fa-962d-4a00a8c9157e&quot;},&quot;response&quot;:{&quot;token&quot;:&quot;Token was refreshed&quot;}}
-auth check
-ON-REPLY 5:auth/check: {&quot;jtype&quot;:&quot;afb-reply&quot;,&quot;request&quot;:{&quot;status&quot;:&quot;success&quot;},&quot;response&quot;:{&quot;isvalid&quot;:true}}
-auth refresh
-ON-REPLY 6:auth/refresh: {&quot;jtype&quot;:&quot;afb-reply&quot;,&quot;request&quot;:{&quot;status&quot;:&quot;success&quot;,
- &quot;token&quot;:&quot;e83b36f8-d945-463d-b983-5d8ed73ba529&quot;},&quot;response&quot;:{&quot;token&quot;:&quot;Token was refreshed&quot;}}</code></pre>
-<p>After closing connection, reconnect as here after:</p>
-<pre><code>$ afb-client-demo ws://localhost:1234/api?token=e83b36f8-d945-463d-b983-5d8ed73ba529\&amp;uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1 auth check
-ON-REPLY 1:auth/check: {&quot;jtype&quot;:&quot;afb-reply&quot;,&quot;request&quot;:{&quot;status&quot;:&quot;success&quot;},&quot;response&quot;:{&quot;isvalid&quot;:true}}</code></pre>
-<p>Same connection check using <strong>curl</strong>:</p>
-<pre><code>$ curl http://localhost:1234/api/auth/check?token=e83b36f8-d945-463d-b983-5d8ed73ba529\&amp;uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1
-{&quot;jtype&quot;:&quot;afb-reply&quot;,&quot;request&quot;:{&quot;status&quot;:&quot;success&quot;},&quot;response&quot;:{&quot;isvalid&quot;:true}}</code></pre>
-<h2 id="format-of-replies">Format of replies</h2>
-<p>Replies use javascript object returned as serialized JSON.</p>
-<p>This object contains at least 2 mandatory fields of name <strong>jtype</strong> and <strong>request</strong> and one optional field of name <strong>response</strong>.</p>
-<h3 id="template">Template</h3>
-<p>This is a template of replies:</p>
-<div class="sourceCode"><pre class="sourceCode json"><code class="sourceCode json"><span class="fu">{</span>
- <span class="dt">&quot;jtype&quot;</span><span class="fu">:</span> <span class="st">&quot;afb-reply&quot;</span><span class="fu">,</span>
- <span class="dt">&quot;request&quot;</span><span class="fu">:</span> <span class="fu">{</span>
- <span class="dt">&quot;status&quot;</span><span class="fu">:</span> <span class="st">&quot;success&quot;</span><span class="fu">,</span>
- <span class="dt">&quot;info&quot;</span><span class="fu">:</span> <span class="st">&quot;informationnal text&quot;</span><span class="fu">,</span>
- <span class="dt">&quot;token&quot;</span><span class="fu">:</span> <span class="st">&quot;e83b36f8-d945-463d-b983-5d8ed73ba52&quot;</span><span class="fu">,</span>
- <span class="dt">&quot;uuid&quot;</span><span class="fu">:</span> <span class="st">&quot;5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1&quot;</span><span class="fu">,</span>
- <span class="dt">&quot;reqid&quot;</span><span class="fu">:</span> <span class="st">&quot;application-generated-id-23456&quot;</span>
- <span class="fu">},</span>
- <span class="dt">&quot;response&quot;</span><span class="fu">:</span> <span class="er">....any</span> <span class="er">response</span> <span class="er">object....</span>
-<span class="fu">}</span></code></pre></div>
-<h3 id="field-jtype">Field jtype</h3>
-<p>The field <strong>jtype</strong> must have a value of type string equal to <strong>&quot;afb-reply&quot;</strong>.</p>
-<h3 id="field-request">Field request</h3>
-<p>The field <strong>request</strong> must have a value of type object. This request object has at least one field named <strong>status</strong> and four optional fields named <strong>info</strong>, <strong>token</strong>, <strong>uuid</strong>, <strong>reqid</strong>.</p>
-<h4 id="subfield-request.status">Subfield request.status</h4>
-<p><strong>status</strong> must have a value of type string. This string is equal to <strong>&quot;success&quot;</strong> only in case of success.</p>
-<h4 id="subfield-request.info">Subfield request.info</h4>
-<p><strong>info</strong> is of type string and represent optional information added to the reply.</p>
-<h4 id="subfield-request.token">Subfield request.token</h4>
-<p><strong>token</strong> is of type string. It is sent either at session creation or when the token is refreshed.</p>
-<h4 id="subfield-request.uuid">Subfield request.uuid</h4>
-<p><strong>uuid</strong> is of type string. It is sent at session creation.</p>
-<h4 id="subfield-request.reqid">Subfield request.reqid</h4>
-<p><strong>reqid</strong> is of type string. It is sent in response to HTTP requests that added a parameter of name <strong>reqid</strong> or <strong>x-afb-reqid</strong> at request time. Value returns in the reply has the exact same value as the one received in the request.</p>
-<h3 id="field-response">Field response</h3>
-<p>This field response optionally contains an object returned when request succeeded.</p>
-<h2 id="format-of-events">Format of events</h2>
-<p>Events are javascript object serialized as JSON.</p>
-<p>This object contains at least 2 mandatory fields of name <strong>jtype</strong> and <strong>event</strong> and one optional field of name <strong>data</strong>.</p>
-<h3 id="template-1">Template</h3>
-<p>Here is a template of event:</p>
-<div class="sourceCode"><pre class="sourceCode json"><code class="sourceCode json"><span class="fu">{</span>
- <span class="dt">&quot;jtype&quot;</span><span class="fu">:</span> <span class="st">&quot;afb-event&quot;</span><span class="fu">,</span>
- <span class="dt">&quot;event&quot;</span><span class="fu">:</span> <span class="st">&quot;sample_api_name/sample_event_name&quot;</span><span class="fu">,</span>
- <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="er">...any</span> <span class="er">event</span> <span class="er">data...</span>
-<span class="fu">}</span></code></pre></div>
-<h3 id="field-jtype-1">Field jtype</h3>
-<p>The field <strong>jtype</strong> must have a value of type string equal to <strong>&quot;afb-event&quot;</strong>.</p>
-<h3 id="field-event">Field event</h3>
-<p>The field <strong>event</strong> carries the event's name.</p>
-<p>The name of the event is made of two parts separated by a slash: the name of the name of the API that generated the event and the name of event within the API.</p>
-<h3 id="field-data">Field data</h3>
-<p>This field data if present holds the data carried by the event.</p>
-</body>
-</html>
diff --git a/doc/afb-application-writing.md b/doc/afb-application-writing.md
index 14199f62..cc513b48 100644
--- a/doc/afb-application-writing.md
+++ b/doc/afb-application-writing.md
@@ -1,8 +1,7 @@
+How to write an application on top of AGL FRAMEWORK
+====================================================
-HOWTO WRITE an APPLICATION above AGL FRAMEWORK
-==============================================
-
-Programmation Languages for Applications
+Programming Languages for Applications
-----------------------------------------
### Writing an HTML5 application
@@ -11,11 +10,12 @@ Developers of HTML5 applications (client side) can easily create
applications for AGL framework using their preferred
HTML5 framework.
-Developers may also take advantage of powerful server side plugins to improve
-application behavior. Server side plugins return an application/json mine-type
+Developers may also take advantage of powerful server side bindings to improve
+application behavior. Server side bindings return an application/json mine-type
and can be accessed though either HTTP or Websockets.
-In a near future, JSON-RPC protocol should be added to complete current x-afb-json1 protocol.
+In a near future, JSON-RPC protocol should be added to complete the current
+x-afb-json1 protocol.
Two examples of HTML5 applications are given:
@@ -25,14 +25,16 @@ Two examples of HTML5 applications are given:
### Writing a Qt application
-Writing Qt applications is also supported. Qt offers standard API to send request through HTTP or WebSockets.
+Writing Qt applications is also supported. Qt offers standard API to send
+request through HTTP or WebSockets.
-It is also possible to write QML applications. A sample QML application [token-websock] is avaliable..
+It is also possible to write QML applications. A sample QML application
+[token-websock] is available:
- [token-websock](https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/app-framework-binder.git;a=blob;f=test/token-websock.qml)
a simple "hello world" application in QML
-### Writing "C" application
+### Writing a "C" application
C applications can use afb-daemon binder through a websocket connection.
@@ -46,18 +48,20 @@ Source code is available here
Current implementation relies on libsystemd and file descriptors.
This model might be review in the future to support secure sockets
-and free the dependency with libsystemd.
+and get rid of libsystemd dependency.
Handling sessions within applications
-------------------------------------
-Applications should understand sessions and tokens management when interacting with afb-daemon binder.
+Applications should understand sessions and token management when interacting
+with afb-daemon binder.
-Applications are communicating with their private binder(afb-daemon) using
-a network connection or potentially any other connection channel. While current version
-does not yet implement unix domain this feature might be added in a near future.
-Developers need to be warn that HTTP protocol is a none connected protocol. This prevents
-from using HTTP socket connection to authenticate clients.
+Applications communicate with their private binder(afb-daemon) using
+a network connection or potentially any other connection channel. While the
+current version does not yet implement Unix socket, this feature might be added
+in the near future. Developers need to be warn that HTTP protocol is a none
+connected protocol and that using HTTP socket connection to authenticate
+clients is not supported.
For this reason, the binder should authenticate the application
by using a shared secret. The secret is named "token" and the identification
@@ -68,25 +72,25 @@ how authentication and sessions are managed.
### Handling sessions
-Plugins and other binder feature need to keep track of client
-instances. This is especially important for plugins running as services
+Bindings and other binder features need to keep track of client
+instances. This is especially important for bindings running as services
as they may typically have to keep each client's data separated.
For HTML5 applications, the web runtime handles the cookie of session
that the binder afb-daemon automatically sets.
-Session identifier can be set using the parameter
-**uuid** or **x-afb-uuid** in URI requests. Within current version of the
-framework session UUID is supported by both HTTP requests and websocket negotiation.
+Session identifier can be set using the parameter **uuid** or **x-afb-uuid** in
+URI requests. Within current version of the framework session UUID is supported
+by both HTTP requests and websocket negotiation.
### Exchanging tokens
At application start, AGL framework communicates a shared secret to both binder
-and client application. This initial secret is called the "initial token".
+and client application. This initial secret is called the "**initial token**".
For each of its client application, the binder manages a current active
token for session management. This authentication token can be use to restrict
-access to some plugin's methods.
+the access to some binding's methods.
The token must be included in URI request on HTTP or during websockets
connection using parameter **token** or **x-afb-token**.
@@ -95,11 +99,12 @@ To ensure security, tokens must be refreshed periodically.
### Example of session management
-In following examples, we suppose that **afb-daemon** is launched with something equivalent to:
+In following examples, we suppose that **afb-daemon** is launched with something
+equivalent to:
$ afb-daemon --port=1234 --token=123456 [...]
-making the expectation that **AuthLogin** plugin is requested as default.
+making the expectation that **AuthLogin** binding is requested as default.
#### Using curl
@@ -197,8 +202,8 @@ Format of replies
Replies use javascript object returned as serialized JSON.
-This object contains at least 2 mandatory fields of name **jtype** and **request**
-and one optional field of name **response**.
+This object contains at least 2 mandatory fields of name **jtype** and
+**request** and one optional field of name **response**.
### Template
@@ -250,11 +255,13 @@ or when the token is refreshed.
**reqid** is of type string. It is sent in response to HTTP requests
that added a parameter of name **reqid** or **x-afb-reqid** at request time.
-Value returns in the reply has the exact same value as the one received in the request.
+Value returns in the reply has the exact same value as the one received in the
+request.
### Field response
-This field response optionally contains an object returned when request succeeded.
+This field response optionally contains an object returned when request
+succeeded.
Format of events
----------------
diff --git a/doc/afb-bindings-overview.html b/doc/afb-bindings-overview.html
deleted file mode 100644
index 0ffc769a..00000000
--- a/doc/afb-bindings-overview.html
+++ /dev/null
@@ -1,154 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <meta name="generator" content="pandoc">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
- <meta name="author" content="José Bollo">
- <title>Overview of bindings shipped with AFB-Daemon</title>
- <style type="text/css">code{white-space: pre;}</style>
- <link rel="stylesheet" href="doc.css">
- <!--[if lt IE 9]>
- <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
- <![endif]-->
-</head>
-<body>
-<header>
-<h1 class="title">Overview of bindings shipped with AFB-Daemon</h1>
-<h2 class="author">José Bollo</h2>
-<h3 class="date">24 juin 2016</h3>
-</header>
-<nav id="TOC">
-<ul>
-<li><a href="#overview-of-bindings-shipped-with-afb-daemon">Overview of bindings shipped with AFB-Daemon</a><ul>
-<li><a href="#list-of-bindings">List of bindings</a></li>
-<li><a href="#detail-of-bindings">Detail of bindings</a><ul>
-<li><a href="#hello-world">Hello World</a></li>
-<li><a href="#authentication">Authentication</a></li>
-<li><a href="#tic-tac-toe">Tic Tac Toe</a></li>
-<li><a href="#audio">Audio</a></li>
-<li><a href="#radio">Radio</a></li>
-<li><a href="#media">Media</a></li>
-</ul></li>
-</ul></li>
-</ul>
-</nav>
-<h1 id="overview-of-bindings-shipped-with-afb-daemon">Overview of bindings shipped with AFB-Daemon</h1>
-<h2 id="list-of-bindings">List of bindings</h2>
-<p>Here are the bindings shipped in the source tree:</p>
-<ul>
-<li>Hello World</li>
-<li>Authentication</li>
-<li>Tic Tac Toe</li>
-<li>Audio <em>(2 backends: ALSA/PulseAudio)</em></li>
-<li>Radio <em>(1 backend: RTLSDR RTL2832U)</em></li>
-<li>Media <em>(1 backend: Rygel UPnP)</em></li>
-</ul>
-<p>All bindings may not be built, depending on the development libraries present on the system at build time.</p>
-<h2 id="detail-of-bindings">Detail of bindings</h2>
-<h3 id="hello-world">Hello World</h3>
-<p>A sample Hello World binding for demonstration and learning purposes.</p>
-<p>This binding provides a few unauthenticated requests, all beginning with &quot;ping&quot;, to demonstrate basic binder capabilities.</p>
-<p><strong>Verbs</strong>:</p>
-<ul>
-<li><em>ping:</em> returns a success response</li>
-<li><em>pingfail:</em> returns a failure response</li>
-<li><em>pingnull:</em> returns a success response, with an empty JSON response field</li>
-<li><em>pingbug:</em> does a memory violation (intercepted by the binder)</li>
-<li><em>pingJson:</em> returns a success response, with a complex JSON response field</li>
-<li><em>pingevent:</em> broadcasts a global event</li>
-</ul>
-<p><br /></p>
-<h3 id="authentication">Authentication</h3>
-<p>An sample Authentication binding for demonstration purposes.</p>
-<p>This binding provides a few requests to demonstrate the binder's token-based security mechanism.</p>
-<p>Calling &quot;<em>connect</em>&quot; with a security token will initiate a session, calling &quot;<em>refresh</em>&quot; will issue a new token and invalidate the previous one, calling &quot;<em>logout</em>&quot; will invalidate all tokens and close the session.</p>
-<p><strong>Verbs</strong>:</p>
-<ul>
-<li><em>ping:</em> returns a success response</li>
-<li><em>connect:</em> creates a session and returns a new token</li>
-<li><em>refresh:</em> returns a new token</li>
-<li><em>check:</em> verifies the passed token is valid</li>
-<li><em>logout:</em> closes the session</li>
-</ul>
-<p><br /></p>
-<h3 id="tic-tac-toe">Tic Tac Toe</h3>
-<p>A sample Tic Tac Toe game binding.</p>
-<p>This binding provides an interactive Tic Tac Toe game where the binder returns the grid as a JSON response.</p>
-<p><strong>Verbs</strong>:</p>
-<ul>
-<li><em>new:</em> starts a new game</li>
-<li><em>play:</em> asks the server to play</li>
-<li><em>move:</em> gives a client move</li>
-<li><em>board:</em> gets the current board state, as a JSON structure</li>
-<li><em>level</em>: sets the server level</li>
-<li><em>join</em>: joins an existing board</li>
-<li><em>undo</em>: undo the last move</li>
-<li><em>wait</em>: wait for a move</li>
-</ul>
-<p><br /></p>
-<h3 id="audio">Audio</h3>
-<p>A sample Audio binding with 2 backends:</p>
-<ul>
-<li>ALSA (mandatory)</li>
-<li>PulseAudio (optional)</li>
-</ul>
-<p>This binding is able to initialize a specific soundcard, define volume levels, channels (mono/stereo...), mute sound, and play a 22,050 Hz PCM stream.</p>
-<p><strong>Verbs</strong>:</p>
-<ul>
-<li><em>ping:</em> returns a success response</li>
-<li><em>init:</em> initializes backend, on the &quot;default&quot; sound card</li>
-<li><em>volume:</em> gets or sets volume, in % (0-100)</li>
-<li><em>channels:</em> gets or sets channels count (1-8)</li>
-<li><em>mute:</em> gets or sets the mute status (on-off)</li>
-<li><em>play</em>: gets or sets the playing status (on-off)</li>
-</ul>
-<p><em>(if PulseAudio development libraries are not found at build time, only ALSA will be available)</em></p>
-<p><em>(if a PulseAudio server is not found at runtime, the binding will dynamically fall back to ALSA)</em></p>
-<p><em>(a specifc backend can be forced by using this syntax before running afb-daemon : <strong>$ export AFB_AUDIO_OUTPUT=Alsa</strong>)</em></p>
-<p><br /></p>
-<h3 id="radio">Radio</h3>
-<p>A sample AM/FM Radio binding with 1 backend:</p>
-<ul>
-<li>RTLSDR - Realtek RTL2832U dongles (mandatory)</li>
-</ul>
-<p>This binding is able to initialize specific RTL2832U dongles, switch between AM/FM modes, define frequency, mute sound, and play sound (if combining with the <strong>audio</strong> binding).</p>
-<p><strong>Verbs</strong>:</p>
-<ul>
-<li><em>ping:</em> returns a success response</li>
-<li><em>init:</em> initializes backend, looking for plugged-in devices</li>
-<li><em>power:</em> sets device power status (on-off)</li>
-<li><em>mode:</em> sets device reception mode (AM-FM)</li>
-<li><em>freq:</em> sets device frequency (in Hz)</li>
-<li><em>mute</em>: sets device mute status (on-off)</li>
-<li><em>play</em>: sets device playing status (on-off)</li>
-</ul>
-<p><em>(if rtlsdr development libraries are not found at build time, this binding will not be built)</em></p>
-<p><br /></p>
-<h3 id="media">Media</h3>
-<p>A sample Media Server binding with 1 backend:</p>
-<ul>
-<li>Rygel</li>
-</ul>
-<p>This binding is able to detect a local Rygel UPnP media server, list audio files, select an audio file for playback, play/pause/seek in this file, upload an audio file to the server.</p>
-<p><strong>Verbs</strong>:</p>
-<ul>
-<li><em>ping:</em> returns a success response</li>
-<li><em>init:</em> initializes backend, looking for an active local UPnP server</li>
-<li><em>list:</em> returns list of audio files, as a JSON structure</li>
-<li><em>select:</em> select an audio files, by index number (001-...)</li>
-<li><em>play:</em> plays the currently selected audio file</li>
-<li><em>stop:</em> stops the currently selected audio file</li>
-<li><em>pause:</em> pauses the currently selected audio file</li>
-<li><em>seek:</em> seeks in the currently selected audio file, in seconds</li>
-<li><em>upload:</em> uploads an audio file, with a POST request</li>
-</ul>
-<p><em>(if GUPnP/GSSDP development libraries are not fund at build time, this binding will not be built)</em></p>
-<p><br /></p>
-<hr />
-<p><br /></p>
-<p>Sample command-line applications: <em>afb-client-demo</em> (built by default)</p>
-<p>Sample HTML5 applications: **test/*.html<strong>, </strong><a href="https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/app-framework-demo.git;a=tree">afb-client</a><strong>, </strong><a href="https://github.com/iotbzh/afb-radio">afb-radio</a>**</p>
-<p>Sample Qt/QML applications: <em>test/token-websock.qml</em></p>
-</body>
-</html>
diff --git a/doc/afb-bindings-overview.md b/doc/afb-bindings-overview.md
index 1d3632ee..c79e17f4 100644
--- a/doc/afb-bindings-overview.md
+++ b/doc/afb-bindings-overview.md
@@ -14,7 +14,8 @@ Here are the bindings shipped in the source tree:
* Radio _(1 backend: RTLSDR RTL2832U)_
* Media _(1 backend: Rygel UPnP)_
-All bindings may not be built, depending on the development libraries present on the system at build time.
+All bindings may not be built, depending on the development libraries present on
+the system at build time.
Detail of bindings
@@ -24,7 +25,8 @@ Detail of bindings
A sample Hello World binding for demonstration and learning purposes.
-This binding provides a few unauthenticated requests, all beginning with "ping", to demonstrate basic binder capabilities.
+This binding provides a few unauthenticated requests, all beginning with
+"ping", to demonstrate basic binder capabilities.
**Verbs**:
@@ -40,11 +42,14 @@ This binding provides a few unauthenticated requests, all beginning with "ping",
### Authentication
-An sample Authentication binding for demonstration purposes.
+A sample Authentication binding for demonstration purposes.
-This binding provides a few requests to demonstrate the binder's token-based security mechanism.
+This binding provides a few requests to demonstrate the binder's token-based
+security mechanism.
-Calling "_connect_" with a security token will initiate a session, calling "_refresh_" will issue a new token and invalidate the previous one, calling "_logout_" will invalidate all tokens and close the session.
+Calling "_connect_" with a security token will initiate a session, calling
+"_refresh_" will issue a new token and invalidate the previous one, calling
+"_logout_" will invalidate all tokens and close the session.
**Verbs**:
@@ -61,7 +66,8 @@ Calling "_connect_" with a security token will initiate a session, calling "_ref
A sample Tic Tac Toe game binding.
-This binding provides an interactive Tic Tac Toe game where the binder returns the grid as a JSON response.
+This binding provides an interactive Tic Tac Toe game where the binder returns
+the grid as a JSON response.
**Verbs**:
@@ -84,7 +90,8 @@ A sample Audio binding with 2 backends:
* ALSA (mandatory)
* PulseAudio (optional)
-This binding is able to initialize a specific soundcard, define volume levels, channels (mono/stereo...), mute sound, and play a 22,050 Hz PCM stream.
+This binding is able to initialize a specific soundcard, define volume levels,
+channels (mono/stereo...), mute sound, and play a 22,050 Hz PCM stream.
**Verbs**:
@@ -95,11 +102,14 @@ This binding is able to initialize a specific soundcard, define volume levels, c
* _mute:_ gets or sets the mute status (on-off)
* _play_: gets or sets the playing status (on-off)
-_(if PulseAudio development libraries are not found at build time, only ALSA will be available)_
+_(if PulseAudio development libraries are not found at build time, only ALSA
+will be available)_
-_(if a PulseAudio server is not found at runtime, the binding will dynamically fall back to ALSA)_
+_(if a PulseAudio server is not found at runtime, the binding will dynamically
+fall back to ALSA)_
-_(a specifc backend can be forced by using this syntax before running afb-daemon : **$ export AFB_AUDIO_OUTPUT=Alsa**)_
+_(a specifc backend can be forced by using this syntax before running afb-daemon
+: **$ export AFB_AUDIO_OUTPUT=Alsa**)_
<br />
@@ -110,7 +120,9 @@ A sample AM/FM Radio binding with 1 backend:
* RTLSDR - Realtek RTL2832U dongles (mandatory)
-This binding is able to initialize specific RTL2832U dongles, switch between AM/FM modes, define frequency, mute sound, and play sound (if combining with the **audio** binding).
+This binding is able to initialize specific RTL2832U dongles, switch between
+AM/FM modes, define frequency, mute sound, and play sound (if combining with
+the **audio** binding).
**Verbs**:
@@ -122,18 +134,20 @@ This binding is able to initialize specific RTL2832U dongles, switch between AM/
* _mute_: sets device mute status (on-off)
* _play_: sets device playing status (on-off)
-_(if rtlsdr development libraries are not found at build time, this binding will not be built)_
+_(if rtlsdr development libraries are not found at build time, this binding will
+not be built)_
<br />
-
### Media
A sample Media Server binding with 1 backend:
* Rygel
-This binding is able to detect a local Rygel UPnP media server, list audio files, select an audio file for playback, play/pause/seek in this file, upload an audio file to the server.
+This binding is able to detect a local Rygel UPnP media server, list audio
+files, select an audio file for playback, play/pause/seek in this file, upload
+an audio file to the server.
**Verbs**:
@@ -147,7 +161,8 @@ This binding is able to detect a local Rygel UPnP media server, list audio files
* _seek:_ seeks in the currently selected audio file, in seconds
* _upload:_ uploads an audio file, with a POST request
-_(if GUPnP/GSSDP development libraries are not fund at build time, this binding will not be built)_
+_(if GUPnP/GSSDP development libraries are not found at build time, this binding
+will not be built)_
<br />
diff --git a/doc/afb-bindings-writing.html b/doc/afb-bindings-writing.html
deleted file mode 100644
index ea03801f..00000000
--- a/doc/afb-bindings-writing.html
+++ /dev/null
@@ -1,974 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <meta name="generator" content="pandoc">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
- <meta name="author" content="José Bollo">
- <title>HOWTO WRITE a BINDING for AFB-DAEMON</title>
- <style type="text/css">code{white-space: pre;}</style>
- <style type="text/css">
-div.sourceCode { overflow-x: auto; }
-table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
- margin: 0; padding: 0; vertical-align: baseline; border: none; }
-table.sourceCode { width: 100%; line-height: 100%; }
-td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
-td.sourceCode { padding-left: 5px; }
-code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
-code > span.dt { color: #902000; } /* DataType */
-code > span.dv { color: #40a070; } /* DecVal */
-code > span.bn { color: #40a070; } /* BaseN */
-code > span.fl { color: #40a070; } /* Float */
-code > span.ch { color: #4070a0; } /* Char */
-code > span.st { color: #4070a0; } /* String */
-code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
-code > span.ot { color: #007020; } /* Other */
-code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
-code > span.fu { color: #06287e; } /* Function */
-code > span.er { color: #ff0000; font-weight: bold; } /* Error */
-code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
-code > span.cn { color: #880000; } /* Constant */
-code > span.sc { color: #4070a0; } /* SpecialChar */
-code > span.vs { color: #4070a0; } /* VerbatimString */
-code > span.ss { color: #bb6688; } /* SpecialString */
-code > span.im { } /* Import */
-code > span.va { color: #19177c; } /* Variable */
-code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
-code > span.op { color: #666666; } /* Operator */
-code > span.bu { } /* BuiltIn */
-code > span.ex { } /* Extension */
-code > span.pp { color: #bc7a00; } /* Preprocessor */
-code > span.at { color: #7d9029; } /* Attribute */
-code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
-code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
-code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
-code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
- </style>
- <link rel="stylesheet" href="doc.css">
- <!--[if lt IE 9]>
- <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
- <![endif]-->
-</head>
-<body>
-<header>
-<h1 class="title">HOWTO WRITE a BINDING for AFB-DAEMON</h1>
-<h2 class="author">José Bollo</h2>
-<h3 class="date">27 juillet 2016</h3>
-</header>
-<nav id="TOC">
-<ul>
-<li><a href="#howto-write-a-binding-for-afb-daemon">HOWTO WRITE a BINDING for AFB-DAEMON</a><ul>
-<li><a href="#summary">Summary</a><ul>
-<li><a href="#nature-of-a-binding">Nature of a binding</a></li>
-<li><a href="#class-of-bindings">Class of bindings</a></li>
-<li><a href="#live-cycle-of-bindings-within-afb-daemon">Live cycle of bindings within afb-daemon</a></li>
-<li><a href="#binding-contend">Binding Contend</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-binding">Names for API (binding)</a></li>
-<li><a href="#names-for-methods">Names for methods</a></li>
-<li><a href="#names-for-arguments">Names for arguments</a></li>
-<li><a href="#forging-names-widely-available">Forging names widely available</a></li>
-</ul></li>
-<li><a href="#writing-a-synchronous-method-implementation">Writing a synchronous method implementation</a><ul>
-<li><a href="#the-incoming-request">The incoming request</a></li>
-<li><a href="#associating-a-client-context-to-a-session">Associating a client context to a session</a></li>
-<li><a href="#sending-reply-to-a-request">Sending reply to a request</a></li>
-</ul></li>
-<li><a href="#getting-argument-of-invocation">Getting argument of invocation</a><ul>
-<li><a href="#basic-functions-for-querying-arguments">Basic functions for querying arguments</a></li>
-<li><a href="#arguments-for-received-files">Arguments for received files</a></li>
-<li><a href="#arguments-as-a-json-object">Arguments as a JSON object</a></li>
-</ul></li>
-<li><a href="#initialisation-of-the-binding-and-declaration-of-methods">Initialisation of the binding and declaration of methods</a></li>
-<li><a href="#sending-messages-to-the-log-system">Sending messages to the log system</a><ul>
-<li><a href="#verbs-for-logging-messages">Verbs for logging messages</a></li>
-<li><a href="#managing-verbosity">Managing verbosity</a></li>
-<li><a href="#output-format-and-destination">Output format and destination</a></li>
-</ul></li>
-<li><a href="#sending-events">Sending events</a></li>
-<li><a href="#writing-an-asynchronous-method-implementation">Writing an asynchronous method implementation</a></li>
-<li><a href="#how-to-build-a-binding">How to build a binding</a><ul>
-<li><a href="#example-for-cmake-meta-build-system">Example for cmake meta build system</a></li>
-<li><a href="#exporting-the-function-afbbindingv1register">Exporting the function afbBindingV1Register</a></li>
-<li><a href="#building-within-yocto">Building within yocto</a></li>
-</ul></li>
-</ul></li>
-</ul>
-</nav>
-<h1 id="howto-write-a-binding-for-afb-daemon">HOWTO WRITE a BINDING for AFB-DAEMON</h1>
-<h2 id="summary">Summary</h2>
-<p>Afb-daemon binders serve files through HTTP protocol and offers to developers the capability to expose application API methods through HTTP or WebSocket protocol.</p>
-<p>Binder bindings are used to add API to afb-daemon. This part describes how to write a binding for afb-daemon.</p>
-<p>Excepting this summary, this document target developers.</p>
-<p>Before moving further through an example, here after a short overview of binder bindings fundamentals.</p>
-<h3 id="nature-of-a-binding">Nature of a binding</h3>
-<p>A binding is an independent piece of software. A binding is self contain and exposes application logic as sharable library. A binding is intended to be dynamically loaded by afb-daemon to expose application API.</p>
-<p>Technically, a binder binding does not reference and is not linked with any afb-daemon library.</p>
-<h3 id="class-of-bindings">Class of bindings</h3>
-<p>Application binder supports two kinds of bindings: application bindings and service bindings. Technically both class of binding are equivalent are use the same coding convention. Only sharing mode and security context diverge.</p>
-<h4 id="application-bindings">Application-bindings</h4>
-<p>Application-bindings implements the glue in between application's UI and services. Every AGL application has a corresponding binder that typically activates one or many bindings to interface the application logic with lower platform services. When an application is started by the AGL application framework, a dedicate binder is started that loads/activates application binding(s). API expose by application-binding are executed within corresponding application security context.</p>
-<p>Application bindings generally handle a unique context for a unique client. As the application framework start a dedicated instance of afb_daemon for each AGL application, if a given binding is used within multiple application each of those application get a new and private instance of eventually &quot;shared&quot; binding.</p>
-<h4 id="service-bindings">Service-bindings</h4>
-<p>Service-bindings enable API activation within corresponding service security context and not within calling application context. Service-bindings are intended to run as a unique instance. Service-bindings can be shared in between multiple clients.</p>
-<p>Service-bindings can either be stateless or manage client context. When managing context each client get a private context.</p>
-<p>Sharing may either be global to the platform (ie: GPS service) or dedicated to a given user (ie: user preferences)</p>
-<h3 id="live-cycle-of-bindings-within-afb-daemon">Live cycle of bindings within afb-daemon</h3>
-<p>Application and service bindings are loaded and activated each time a new afb-daemon is started.</p>
-<p>At launch time, every loaded binding initialise itself. If a single binding initialisation fail corresponding instance of afb-daemon self aborts.</p>
-<p>Conversely, when a binding initialisation succeeds, it should register its unique name as well as the list of verbs attached to the methods it exposes.</p>
-<p>When initialised, on request from application clients to the right API/verb, binding methods are activated by the afb-daemon attached to the application or service.</p>
-<p>At exit time, no special action is enforced by afb-daemon. When a specific actions is required at afb-daemon stop, developers should use 'atexit/on_exit' during binding initialisation sequence to register a custom exit function.</p>
-<h3 id="binding-contend">Binding Contend</h3>
-<p>Afb-daemon's binding register two classes of objects: names and functions.</p>
-<p>Bindings declare categories of names: - A unique binding name to access all API expose by this binding, - One name for each methods/verbs provided by this binding.</p>
-<p>Bindings declare two categories of functions: - function use for the initialisation - functions implementing exposed API methods</p>
-<p>Afb-daemon parses URI requests to extract the API(binding name) and the VERB(method to activate). As an example, URI <strong>foo/bar</strong> translates to binding named <strong>foo</strong> and method named <strong>bar</strong>. To serve such a request, afb-daemon looks for an active binding named <strong>foo</strong> and then within this binding for a method named <strong>bar</strong>. When find afb-daemon calls corresponding method with attached parameter if any.</p>
-<p>Afb-daemon ignores letter case when parsing URI. Thus <strong>TicTacToe/Board</strong> and <strong>tictactoe/board</strong> are equivalent.</p>
-<h4 id="the-name-of-the-binding">The name of the binding</h4>
-<p>The name of a given binding is also known as the name of the API prefix that defines the binding.</p>
-<p>The name of a binding SHOULD be unique within a given afb-daemon instance.</p>
-<p>For example, when a client of afb-daemon calls a URI named <strong>foo/bar</strong>. Afb-daemon extracts the prefix <strong>foo</strong> and the suffix <strong>bar</strong>. <strong>foo</strong> must match a binding name and <strong>bar</strong> a VERB attached to some method.</p>
-<h4 id="names-of-methods">Names of methods</h4>
-<p>Each binding exposes a set of methods that can be called by the clients of a given afb-daemon.</p>
-<p>VERB's name attached to a given binding (API) MUST be unique within a binding.</p>
-<p>Bindings static declaration link VERBS to corresponding methods. When clients emit requests on a given API/VERB corresponding method is called by afb-daemon.</p>
-<h4 id="initialisation-function">Initialisation function</h4>
-<p>Binding's initialisation function serves several purposes.</p>
-<ol type="1">
-<li><p>It allows afb-daemon to control binding version depending on initialisation function name. As today, the only supported initialisation function is <strong>afbBindingV1Register</strong>. This identifies version &quot;one&quot; of bindings.</p></li>
-<li><p>It allows bindings to initialise itself.</p></li>
-<li><p>It enables names declarations: descriptions, requirements and implementations of exposed API/VERB.</p></li>
-</ol>
-<h4 id="functions-instantiation-of-apiverbs">Functions instantiation of API/VERBs</h4>
-<p>When an API/VERB is called, afb-daemon constructs a request object. Then it passes this request object to the implementation function corresponding to requested method, this within attached API binding.</p>
-<p>An implementation function receives a request object that is used to: get arguments of the request, send answer, store session data.</p>
-<p>A binding MUST set an answer to every received requests.</p>
-<p>Nevertheless it is not mandatory to set the answer before returning from API/VERB implementing function. This behaviour is important for asynchronous actions.</p>
-<p>API/VERB implementation that set an answer before returning are called <em>synchronous implementations</em>. Those that do not systematically set an answer before returning are called <em>asynchronous implementations</em>.</p>
-<p>Asynchronous implementations typically launch asynchronous actions. They record some context at request time and provide answer to the request only at completion of asynchronous actions.</p>
-<h2 id="the-tic-tac-toe-example">The Tic-Tac-Toe example</h2>
-<p>This part explains how to write an afb-binding. For the sake of being practical it uses many examples based on tic-tac-toe. This binding example is in <em>bindings/samples/tic-tac-toe.c</em>.</p>
-<p>This binding is named <strong><em>tictactoe</em></strong>.</p>
-<h2 id="dependencies-when-compiling">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>Print flags use for compilation:</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>Afb-daemon automatically includes dependency to json-c. This is activated through <strong>Requires</strong> keyword in pkg-config. While almost every binding replies on <strong>json-c</strong> this is not a must have dependency.</p>
-<p>Internally, afb-daemon relies on <strong>libsystemd</strong> for its event loop, as well as for its binding to D-Bus. Bindings developers are encouraged to leverage <strong>libsystemd</strong> when possible. Nevertheless there is no hard dependency to <strong>libsystemd</strong> if ever you rather not use it, feel free to do so.</p>
-<blockquote>
-<p>Afb-daemon binding are fully self contain. They do not enforce dependency on any libraries from the application framework. Afb-daemon dependencies requirer to run AGL bindings are given at runtime through pointers leveraging read-only memory feature.</p>
-</blockquote>
-<h2 id="header-files-to-include">Header files to include</h2>
-<p>Binding <em>tictactoe</em> has following includes:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define _GNU_SOURCE</span>
-<span class="ot">#include &lt;stdio.h&gt;</span>
-<span class="ot">#include &lt;string.h&gt;</span>
-<span class="ot">#include &lt;json-c/json.h&gt;</span>
-<span class="ot">#include &lt;afb/afb-binding.h&gt;</span></code></pre></div>
-<p>Header <em>afb/afb-binding.h</em> is the only hard dependency, it includes all features that a binding MUST HAVE. Outside of includes used to support application logic, common external headers used within bindings are:</p>
-<ul>
-<li><em>json-c/json.h</em>: should be include to handle json objects;</li>
-<li><em>systemd/sd-event.h</em>: should be include to access event main loop;</li>
-<li><em>systemd/sd-bus.h</em>: should be include for dbus connections.</li>
-</ul>
-<p>The <em>tictactoe</em> binding does not leverage systemd features, also only json.h is used on top of mandatory afb/afb-binding.h.</p>
-<p>When including <em>afb/afb-binding.h</em>, the macro **_GNU_SOURCE** MUST be defined.</p>
-<h2 id="choosing-names">Choosing names</h2>
-<p>Designers of bindings should define a unique name for every API binding as well as for methods VERBs. They should also define names for request arguments passed as name/value pair in URI.</p>
-<p>While forging names, designers should respect few rules to ensure that created names are valid and easy to use across platforms.</p>
-<p>All names and strings are UTF-8 encoded.</p>
-<h3 id="names-for-api-binding">Names for API (binding)</h3>
-<p>Binding API name are checked. All characters are authorised except:</p>
-<ul>
-<li>the control characters (000 .. 01f)</li>
-<li>the characters of the set { ' ', '&quot;', '#', '%', '&amp;', ''', '/', '?', '`', '7f' }</li>
-</ul>
-<p>In other words the set of forbidden characters is { 000..020, 022, 023, 025..027, 02f, 03f, 060, 07f }.</p>
-<p>Afb-daemon makes no distinction between lower case and upper case when searching for API/VERB.</p>
-<h3 id="names-for-methods">Names for methods</h3>
-<p>The names of methods VERBs are totally free and not checked.</p>
-<p>However, the validity rules for method's VERB name are the same as for Binding API name except that the dot(.) character is forbidden.</p>
-<p>Afb-daemon makes no case distinction when searching for an API by name.</p>
-<h3 id="names-for-arguments">Names for arguments</h3>
-<p>Argument's name are not restricted and can be everything you wish.</p>
-<blockquote>
-<p>Warning arguments search is case sensitive and &quot;index&quot; and &quot;Index&quot; are not two different arguments.</p>
-</blockquote>
-<h3 id="forging-names-widely-available">Forging names widely available</h3>
-<p>The key names of javascript object can be almost anything using the arrayed notation:</p>
-<pre><code>object[key] = value</code></pre>
-<p>Nevertheless this is not the case with javascript dot notation:</p>
-<pre><code>object.key = value</code></pre>
-<p>Using the dot notation, the key must be a valid javascript identifier and dash(-) as well as few other reserved characters cannot be used.</p>
-<p>For this reason, we advise developper to chose name compatible with both javascript and HTML notation.</p>
-<p>It is a good practice, even for arguments not to rely on case sensitivity. This may reduce headache strength at debug time, especially with interpreted language like javascript that may not warn you that a variable was not defined.</p>
-<h2 id="writing-a-synchronous-method-implementation">Writing a synchronous method implementation</h2>
-<p>The method <strong>tictactoe/board</strong> is a synchronous implementation. Here is its listing:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * get the board</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="dt">void</span> board(<span class="kw">struct</span> afb_req req)
-{
- <span class="kw">struct</span> board *board;
- <span class="kw">struct</span> json_object *description;
-
- <span class="co">/* retrieves the context for the session */</span>
- board = board_of_req(req);
- INFO(afbitf, <span class="st">&quot;method &#39;board&#39; called for boardid %d&quot;</span>, board-&gt;id);
-
- <span class="co">/* describe the board */</span>
- description = describe(board);
-
- <span class="co">/* send the board&#39;s description */</span>
- afb_req_success(req, description, NULL);
-}</code></pre></div>
-<p>This example shows many aspects of a synchronous method implementation. Let summarise it:</p>
-<ol type="1">
-<li><p>The function <strong>board_of_req</strong> retrieves the context stored for the binding: the board.</p></li>
-<li><p>The macro <strong>INFO</strong> sends a message of kind <em>INFO</em> to the logging system. The global variable named <strong>afbitf</strong> used represents the interface to afb-daemon.</p></li>
-<li><p>The function <strong>describe</strong> creates a json_object representing the board.</p></li>
-<li><p>The function <strong>afb_req_success</strong> sends the reply, attaching to it the object <em>description</em>.</p></li>
-</ol>
-<h3 id="the-incoming-request">The incoming request</h3>
-<p>For any implementation, the request is received by a structure of type <strong>struct afb_req</strong>.</p>
-<blockquote>
-<p>Note that this is a PLAIN structure, not a pointer to a structure.</p>
-</blockquote>
-<p>The definition of <strong>struct afb_req</strong> is:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Describes the request by bindings from afb-daemon</span>
-<span class="co"> */</span>
-<span class="kw">struct</span> afb_req {
- <span class="dt">const</span> <span class="kw">struct</span> afb_req_itf *itf; <span class="co">/* the interfacing functions */</span>
- <span class="dt">void</span> *closure; <span class="co">/* the closure for functions */</span>
-};</code></pre></div>
-<p>It contains two pointers: first one <em>itf</em>, points to functions used to handle internal request. Second one <em>closure</em> point onto function closure.</p>
-<blockquote>
-<p>The structure must never be used directly. Instead developer should use the intended functions provided by afb-daemon as described here after.</p>
-</blockquote>
-<p><em>req</em> is used to get arguments of the request, to send answer, to store session data.</p>
-<p>This object and its interface is defined and documented in the file names <em>afb/afb-req-itf.h</em></p>
-<p>The above example uses twice <em>req</em> object request.</p>
-<p>The first time, to retrieve the board attached to the session of the request.</p>
-<p>The second time, to send the reply: an object that describes the current board.</p>
-<h3 id="associating-a-client-context-to-a-session">Associating a client context to a session</h3>
-<p>When <em>tic-tac-toe</em> binding receives a request, it musts get the board describing the game associated to the session.</p>
-<p>For a binding, having data associated to a session is common. This data is called &quot;binding context&quot; for the session. Within <em>tic-tac-toe</em> binding the context is the board.</p>
-<p>Requests <em>afb_req</em> offer four functions for storing and retrieving session associated context.</p>
-<p>These functions are:</p>
-<ul>
-<li><p><strong>afb_req_context_get</strong>: retrieves context data stored for current binding.</p></li>
-<li><p><strong>afb_req_context_set</strong>: store context data of current binding.</p></li>
-<li><p><strong>afb_req_context</strong>: if exist retrieves context data of current binding. if context does not yet exist, creates a new context and store it.</p></li>
-<li><p><strong>afb_req_context_clear</strong>: reset the stored context data.</p></li>
-</ul>
-<p>The binding <em>tictactoe</em> use a convenient function to retrieve its context: the board. This function is <em>board_of_req</em>:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * retrieves the board of the request</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="kw">inline</span> <span class="kw">struct</span> board *board_of_req(<span class="kw">struct</span> afb_req req)
-{
- <span class="kw">return</span> afb_req_context(req, (<span class="dt">void</span>*)get_new_board, (<span class="dt">void</span>*)release_board);
-}</code></pre></div>
-<p>The function <strong>afb_req_context</strong> ensures an existing context for the session of the request. Its two last arguments are functions to allocate and free context. Note function type casts to avoid compilation warnings.</p>
-<p>Here is the definition of the function <strong>afb_req_context</strong></p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Gets the pointer stored by the binding for the session of &#39;req&#39;.</span>
-<span class="co"> * If the stored pointer is NULL, indicating that no pointer was</span>
-<span class="co"> * already stored, afb_req_context creates a new context by calling</span>
-<span class="co"> * the function &#39;create_context&#39; and stores it with the freeing function</span>
-<span class="co"> * &#39;free_context&#39;.</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="kw">inline</span> <span class="dt">void</span> *afb_req_context(<span class="kw">struct</span> afb_req req, <span class="dt">void</span> *(*create_context)(), <span class="dt">void</span> (*free_context)(<span class="dt">void</span>*))
-{
- <span class="dt">void</span> *result = afb_req_context_get(req);
- <span class="kw">if</span> (result == NULL) {
- result = create_context();
- afb_req_context_set(req, result, free_context);
- }
- <span class="kw">return</span> result;
-}</code></pre></div>
-<p>The second argument if the function that creates the context. For binding <em>tic-tac-toe</em> (function <strong>get_new_board</strong>). The function <strong>get_new_board</strong> creates a new board and set usage its count to 1. The boards are checking usage count to free resources when not used.</p>
-<p>The third argument is a function that frees context resources. For binding <em>tic-tac-toe</em> (function <strong>release_board</strong>). The function <strong>release_board</strong> decrease usage count of the board passed in argument. When usage count falls to zero, data board are freed.</p>
-<p>Definition of other functions dealing with contexts:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Gets the pointer stored by the binding for the session of &#39;req&#39;.</span>
-<span class="co"> * When the binding has not yet recorded a pointer, NULL is returned.</span>
-<span class="co"> */</span>
-<span class="dt">void</span> *afb_req_context_get(<span class="kw">struct</span> afb_req req);
-
-<span class="co">/*</span>
-<span class="co"> * Stores for the binding the pointer &#39;context&#39; to the session of &#39;req&#39;.</span>
-<span class="co"> * The function &#39;free_context&#39; will be called when the session is closed</span>
-<span class="co"> * or if binding stores an other pointer.</span>
-<span class="co"> */</span>
-<span class="dt">void</span> afb_req_context_set(<span class="kw">struct</span> afb_req req, <span class="dt">void</span> *context, <span class="dt">void</span> (*free_context)(<span class="dt">void</span>*));
-
-<span class="co">/*</span>
-<span class="co"> * Frees the pointer stored by the binding for the session of &#39;req&#39;</span>
-<span class="co"> * and sets it to NULL.</span>
-<span class="co"> *</span>
-<span class="co"> * Shortcut for: afb_req_context_set(req, NULL, NULL)</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="kw">inline</span> <span class="dt">void</span> afb_req_context_clear(<span class="kw">struct</span> afb_req req)
-{
- afb_req_context_set(req, NULL, NULL);
-}</code></pre></div>
-<h3 id="sending-reply-to-a-request">Sending reply to a request</h3>
-<p>Two kinds of replies: successful or failure.</p>
-<blockquote>
-<p>Sending a reply to a request MUST be done once and only once.</p>
-</blockquote>
-<p>It exists two functions for &quot;success&quot; replies: <strong>afb_req_success</strong> and <strong>afb_req_success_f</strong>.</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Sends a reply of kind success to the request &#39;req&#39;.</span>
-<span class="co"> * The status of the reply is automatically set to &quot;success&quot;.</span>
-<span class="co"> * Its send the object &#39;obj&#39; (can be NULL) with an</span>
-<span class="co"> * informationnal comment &#39;info (can also be NULL).</span>
-<span class="co"> *</span>
-<span class="co"> * For convenience, the function calls &#39;json_object_put&#39; for &#39;obj&#39;.</span>
-<span class="co"> * Thus, in the case where &#39;obj&#39; should remain available after</span>
-<span class="co"> * the function returns, the function &#39;json_object_get&#39; shall be used.</span>
-<span class="co"> */</span>
-<span class="dt">void</span> afb_req_success(<span class="kw">struct</span> afb_req req, <span class="kw">struct</span> json_object *obj, <span class="dt">const</span> <span class="dt">char</span> *info);
-
-<span class="co">/*</span>
-<span class="co"> * Same as &#39;afb_req_success&#39; but the &#39;info&#39; is a formatting</span>
-<span class="co"> * string followed by arguments.</span>
-<span class="co"> *</span>
-<span class="co"> * For convenience, the function calls &#39;json_object_put&#39; for &#39;obj&#39;.</span>
-<span class="co"> * Thus, in the case where &#39;obj&#39; should remain available after</span>
-<span class="co"> * the function returns, the function &#39;json_object_get&#39; shall be used.</span>
-<span class="co"> */</span>
-<span class="dt">void</span> afb_req_success_f(<span class="kw">struct</span> afb_req req, <span class="kw">struct</span> json_object *obj, <span class="dt">const</span> <span class="dt">char</span> *info, ...);</code></pre></div>
-<p>It exists two functions for &quot;failure&quot; replies: <strong>afb_req_fail</strong> and <strong>afb_req_fail_f</strong>.</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Sends a reply of kind failure to the request &#39;req&#39;.</span>
-<span class="co"> * The status of the reply is set to &#39;status&#39; and an</span>
-<span class="co"> * informational comment &#39;info&#39; (can also be NULL) can be added.</span>
-<span class="co"> *</span>
-<span class="co"> * Note that calling afb_req_fail(&quot;success&quot;, info) is equivalent</span>
-<span class="co"> * to call afb_req_success(NULL, info). Thus even if possible it</span>
-<span class="co"> * is strongly recommended to NEVER use &quot;success&quot; for status.</span>
-<span class="co"> *</span>
-<span class="co"> * For convenience, the function calls &#39;json_object_put&#39; for &#39;obj&#39;.</span>
-<span class="co"> * Thus, in the case where &#39;obj&#39; should remain available after</span>
-<span class="co"> * the function returns, the function &#39;json_object_get&#39; shall be used.</span>
-<span class="co"> */</span>
-<span class="dt">void</span> afb_req_fail(<span class="kw">struct</span> afb_req req, <span class="dt">const</span> <span class="dt">char</span> *status, <span class="dt">const</span> <span class="dt">char</span> *info);
-
-<span class="co">/*</span>
-<span class="co"> * Same as &#39;afb_req_fail&#39; but the &#39;info&#39; is a formatting</span>
-<span class="co"> * string followed by arguments.</span>
-<span class="co"> *</span>
-<span class="co"> * For convenience, the function calls &#39;json_object_put&#39; for &#39;obj&#39;.</span>
-<span class="co"> * Thus, in the case where &#39;obj&#39; should remain available after</span>
-<span class="co"> * the function returns, the function &#39;json_object_get&#39; shall be used.</span>
-<span class="co"> */</span>
-<span class="dt">void</span> afb_req_fail_f(<span class="kw">struct</span> afb_req req, <span class="dt">const</span> <span class="dt">char</span> *status, <span class="dt">const</span> <span class="dt">char</span> *info, ...);</code></pre></div>
-<blockquote>
-<p>For convenience, these functions automatically call <strong>json_object_put</strong> to release <strong>obj</strong>. Because <strong>obj</strong> usage count is null after being passed to a reply function, it SHOULD not be used anymore. If exceptionally <strong>obj</strong> needs to remain usable after reply function then using <strong>json_object_get</strong> on <strong>obj</strong> to increase usage count and cancels the effect the <strong>json_object_put</strong> is possible.</p>
-</blockquote>
-<h2 id="getting-argument-of-invocation">Getting argument of invocation</h2>
-<p>Many methods expect arguments. Afb-daemon's bindings retrieve arguments by name and not by position.</p>
-<p>Arguments are passed by requests through either HTTP or WebSockets.</p>
-<p>For example, the method <strong>join</strong> of binding <strong>tic-tac-toe</strong> expects one argument: the <em>boardid</em> to join. Here is an extract:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Join a board</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="dt">void</span> join(<span class="kw">struct</span> afb_req req)
-{
- <span class="kw">struct</span> board *board, *new_board;
- <span class="dt">const</span> <span class="dt">char</span> *id;
-
- <span class="co">/* retrieves the context for the session */</span>
- board = board_of_req(req);
- INFO(afbitf, <span class="st">&quot;method &#39;join&#39; called for boardid %d&quot;</span>, board-&gt;id);
-
- <span class="co">/* retrieves the argument */</span>
- id = afb_req_value(req, <span class="st">&quot;boardid&quot;</span>);
- <span class="kw">if</span> (id == NULL)
- <span class="kw">goto</span> bad_request;
- ...</code></pre></div>
-<p>The function <strong>afb_req_value</strong> searches in the request <em>req</em> for argument name passed in the second argument. When argument name is not passed, <strong>afb_req_value</strong> returns NULL.</p>
-<blockquote>
-<p>The search is case sensitive and <em>boardid</em> is not equivalent to <em>BoardId</em>. Nevertheless having argument names that only differ by name case is not a good idea.</p>
-</blockquote>
-<h3 id="basic-functions-for-querying-arguments">Basic functions for querying arguments</h3>
-<p>The function <strong>afb_req_value</strong> is defined here after:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Gets from the request &#39;req&#39; the string value of the argument of &#39;name&#39;.</span>
-<span class="co"> * Returns NULL if when there is no argument of &#39;name&#39;.</span>
-<span class="co"> * Returns the value of the argument of &#39;name&#39; otherwise.</span>
-<span class="co"> *</span>
-<span class="co"> * Shortcut for: afb_req_get(req, name).value</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="kw">inline</span> <span class="dt">const</span> <span class="dt">char</span> *afb_req_value(<span class="kw">struct</span> afb_req req, <span class="dt">const</span> <span class="dt">char</span> *name)
-{
- <span class="kw">return</span> afb_req_get(req, name).value;
-}</code></pre></div>
-<p>It is defined as a shortcut to call the function <strong>afb_req_get</strong>. That function is defined here after:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Gets from the request &#39;req&#39; the argument of &#39;name&#39;.</span>
-<span class="co"> * Returns a PLAIN structure of type &#39;struct afb_arg&#39;.</span>
-<span class="co"> * When the argument of &#39;name&#39; is not found, all fields of result are set to NULL.</span>
-<span class="co"> * When the argument of &#39;name&#39; is found, the fields are filled,</span>
-<span class="co"> * in particular, the field &#39;result.name&#39; is set to &#39;name&#39;.</span>
-<span class="co"> *</span>
-<span class="co"> * There is a special name value: the empty string.</span>
-<span class="co"> * The argument of name &quot;&quot; is defined only if the request was made using</span>
-<span class="co"> * an HTTP POST of Content-Type &quot;application/json&quot;. In that case, the</span>
-<span class="co"> * argument of name &quot;&quot; receives the value of the body of the HTTP request.</span>
-<span class="co"> */</span>
-<span class="kw">struct</span> afb_arg afb_req_get(<span class="kw">struct</span> afb_req req, <span class="dt">const</span> <span class="dt">char</span> *name);</code></pre></div>
-<p>That function takes 2 parameters: the request and the name of the argument to retrieve. It returns a PLAIN structure of type <strong>struct afb_arg</strong>.</p>
-<p>There is a special name that is defined when the request is of type HTTP/POST with a Content-Type being application/json. This name is <strong>&quot;&quot;</strong> (the empty string). In that case, the value of this argument of empty name is the string received as a body of the post and is supposed to be a JSON string.</p>
-<p>The definition of <strong>struct afb_arg</strong> is:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Describes an argument (or parameter) of a request</span>
-<span class="co"> */</span>
-<span class="kw">struct</span> afb_arg {
- <span class="dt">const</span> <span class="dt">char</span> *name; <span class="co">/* name of the argument or NULL if invalid */</span>
- <span class="dt">const</span> <span class="dt">char</span> *value; <span class="co">/* string representation of the value of the argument */</span>
- <span class="co">/* original filename of the argument if path != NULL */</span>
- <span class="dt">const</span> <span class="dt">char</span> *path; <span class="co">/* if not NULL, path of the received file for the argument */</span>
- <span class="co">/* when the request is finalized this file is removed */</span>
-};</code></pre></div>
-<p>The structure returns the data arguments that are known for the request. This data include a field named <strong>path</strong>. This <strong>path</strong> can be accessed using the function <strong>afb_req_path</strong> defined here after:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Gets from the request &#39;req&#39; the path for file attached to the argument of &#39;name&#39;.</span>
-<span class="co"> * Returns NULL if when there is no argument of &#39;name&#39; or when there is no file.</span>
-<span class="co"> * Returns the path of the argument of &#39;name&#39; otherwise.</span>
-<span class="co"> *</span>
-<span class="co"> * Shortcut for: afb_req_get(req, name).path</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="kw">inline</span> <span class="dt">const</span> <span class="dt">char</span> *afb_req_path(<span class="kw">struct</span> afb_req req, <span class="dt">const</span> <span class="dt">char</span> *name)
-{
- <span class="kw">return</span> afb_req_get(req, name).path;
-}</code></pre></div>
-<p>The path is only defined for HTTP/POST requests that send file.</p>
-<h3 id="arguments-for-received-files">Arguments for received files</h3>
-<p>As it is explained above, clients can send files using HTTP/POST requests.</p>
-<p>Received files are attached to &quot;file&quot; argument name. For example, the following HTTP fragment (from test/sample-post.html) will send an HTTP/POST request to the method <strong>post/upload-image</strong> with 2 arguments named <em>file</em> and <em>hidden</em>.</p>
-<div class="sourceCode"><pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;h2&gt;</span>Sample Post File<span class="kw">&lt;/h2&gt;</span>
-<span class="kw">&lt;form</span><span class="ot"> enctype=</span><span class="st">&quot;multipart/form-data&quot;</span><span class="kw">&gt;</span>
- <span class="kw">&lt;input</span><span class="ot"> type=</span><span class="st">&quot;file&quot;</span><span class="ot"> name=</span><span class="st">&quot;file&quot;</span> <span class="kw">/&gt;</span>
- <span class="kw">&lt;input</span><span class="ot"> type=</span><span class="st">&quot;hidden&quot;</span><span class="ot"> name=</span><span class="st">&quot;hidden&quot;</span><span class="ot"> value=</span><span class="st">&quot;bollobollo&quot;</span> <span class="kw">/&gt;</span>
- <span class="kw">&lt;br&gt;</span>
- <span class="kw">&lt;button</span><span class="ot"> formmethod=</span><span class="st">&quot;POST&quot;</span><span class="ot"> formaction=</span><span class="st">&quot;api/post/upload-image&quot;</span><span class="kw">&gt;</span>Post File<span class="kw">&lt;/button&gt;</span>
-<span class="kw">&lt;/form&gt;</span></code></pre></div>
-<p>Argument named <strong>file</strong> should have both its value and path defined.</p>
-<p>The value is the name of the file as it was set by the HTTP client. Generally it is the filename on client side.</p>
-<p>The path is the effective path of saved file on the temporary local storage area of the application. This is a randomly generated and unique filename. It is not linked with the original filename as used on client side.</p>
-<p>After success the binding can use the uploaded file directly from local storage path with no restriction: read, write, remove, copy, rename... Nevertheless when request reply is set and query terminated, the uploaded temporary file at path is destroyed.</p>
-<h3 id="arguments-as-a-json-object">Arguments as a JSON object</h3>
-<p>Bindings may also request every arguments of a given call as one single object. This feature is provided by the function <strong>afb_req_json</strong> defined here after:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Gets from the request &#39;req&#39; the json object hashing the arguments.</span>
-<span class="co"> * The returned object must not be released using &#39;json_object_put&#39;.</span>
-<span class="co"> */</span>
-<span class="kw">struct</span> json_object *afb_req_json(<span class="kw">struct</span> afb_req req);</code></pre></div>
-<p>It returns a json object. This object depends on how the request was built:</p>
-<ul>
-<li><p>For HTTP requests, this json object uses key names mapped on argument name. Values are either string for common arguments or object ie: { &quot;file&quot;: &quot;...&quot;, &quot;path&quot;: &quot;...&quot; }</p></li>
-<li><p>For WebSockets requests, returned directly the object as provided by the client.</p></li>
-</ul>
-<blockquote>
-<p>In fact, for Websockets requests, the function <strong>afb_req_value</strong> can be seen as a shortcut to <strong><em>json_object_get_string(json_object_object_get(afb_req_json(req), name))</em></strong></p>
-</blockquote>
-<h2 id="initialisation-of-the-binding-and-declaration-of-methods">Initialisation of the binding and declaration of methods</h2>
-<p>To be active, binding's methods should be declared to afb-daemon. Furthermore, the binding itself must be recorded.</p>
-<p>The registration mechanism is very basic: when afb-need starts, it loads all bindings listed in: command line or configuration file.</p>
-<p>Loading a binding follows the following steps:</p>
-<ol type="1">
-<li><p>Afb-daemon loads the binding with <em>dlopen</em>.</p></li>
-<li><p>Afb-daemon searches for a symbol named <strong>afbBindingV1Register</strong> using <em>dlsym</em>. This symbol is assumed to be the exported initialisation function of the binding.</p></li>
-<li><p>Afb-daemon builds an interface object for the binding.</p></li>
-<li><p>Afb-daemon calls the found function <strong>afbBindingV1Register</strong> with interface pointer as parameter.</p></li>
-<li><p>Function <strong>afbBindingV1Register</strong> setups the binding and initialises it.</p></li>
-<li><p>Function <strong>afbBindingV1Register</strong> returns the pointer to a structure describing the binding: version, name (prefix or API name), and list of methods.</p></li>
-<li><p>Afb-daemon checks that the returned version and name can be managed. If so, binding and its methods are register to become usable as soon as afb-daemon initialisation is finished.</p></li>
-</ol>
-<p>Here after the code used for <strong>afbBindingV1Register</strong> from binding <em>tic-tac-toe</em>:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * activation function for registering the binding called by afb-daemon</span>
-<span class="co"> */</span>
-<span class="dt">const</span> <span class="kw">struct</span> afb_binding *afbBindingV1Register(<span class="dt">const</span> <span class="kw">struct</span> afb_binding_interface *itf)
-{
- afbitf = itf; <span class="co">// records the interface for accessing afb-daemon</span>
- <span class="kw">return</span> &amp;binding_description; <span class="co">// returns the description of the binding</span>
-}</code></pre></div>
-<p>It is a very minimal initialisation function because <em>tic-tac-toe</em> binding doesn't have any application related initialisation step. It merely record daemon's interface and returns its description.</p>
-<p>The variable <strong>afbitf</strong> is a binding global variable. It keeps the interface to afb-daemon that should be used for logging and pushing events. Here is its declaration:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * the interface to afb-daemon</span>
-<span class="co"> */</span>
-<span class="dt">const</span> <span class="kw">struct</span> afb_binding_interface *afbitf;</code></pre></div>
-<p>The description of the binding is defined here after.</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * array of the methods exported to afb-daemon</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="dt">const</span> <span class="kw">struct</span> afb_verb_desc_v1 binding_methods[] = {
- <span class="co">/* VERB&#39;S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */</span>
- { .name= <span class="st">&quot;new&quot;</span>, .session= AFB_SESSION_NONE, .callback= new, .info= <span class="st">&quot;Starts a new game&quot;</span> },
- { .name= <span class="st">&quot;play&quot;</span>, .session= AFB_SESSION_NONE, .callback= play, .info= <span class="st">&quot;Asks the server to play&quot;</span> },
- { .name= <span class="st">&quot;move&quot;</span>, .session= AFB_SESSION_NONE, .callback= move, .info= <span class="st">&quot;Tells the client move&quot;</span> },
- { .name= <span class="st">&quot;board&quot;</span>, .session= AFB_SESSION_NONE, .callback= board, .info= <span class="st">&quot;Get the current board&quot;</span> },
- { .name= <span class="st">&quot;level&quot;</span>, .session= AFB_SESSION_NONE, .callback= level, .info= <span class="st">&quot;Set the server level&quot;</span> },
- { .name= <span class="st">&quot;join&quot;</span>, .session= AFB_SESSION_CHECK,.callback= join, .info= <span class="st">&quot;Join a board&quot;</span> },
- { .name= <span class="st">&quot;undo&quot;</span>, .session= AFB_SESSION_NONE, .callback= undo, .info= <span class="st">&quot;Undo the last move&quot;</span> },
- { .name= <span class="st">&quot;wait&quot;</span>, .session= AFB_SESSION_NONE, .callback= wait, .info= <span class="st">&quot;Wait for a change&quot;</span> },
- { .name= NULL } <span class="co">/* marker for end of the array */</span>
-};
-
-<span class="co">/*</span>
-<span class="co"> * description of the binding for afb-daemon</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="dt">const</span> <span class="kw">struct</span> afb_binding binding_description =
-{
- <span class="co">/* description conforms to VERSION 1 */</span>
- .type= AFB_BINDING_VERSION_1,
- .v1= { <span class="co">/* fills the v1 field of the union when AFB_BINDING_VERSION_1 */</span>
- .prefix= <span class="st">&quot;tictactoe&quot;</span>, <span class="co">/* the API name (or binding name or prefix) */</span>
- .info= <span class="st">&quot;Sample tac-tac-toe game&quot;</span>, <span class="co">/* short description of of the binding */</span>
- .methods = binding_methods <span class="co">/* the array describing the methods of the API */</span>
- }
-};</code></pre></div>
-<p>The structure <strong>binding_description</strong> describes the binding. It declares the type and version of the binding, its name, a short description and its methods list.</p>
-<p>The list of methods is an array of structures describing the methods and terminated by a NULL marker.</p>
-<p>In version one of afb-damon binding, a method description contains 4 fields:</p>
-<ul>
-<li><p>the name of the method,</p></li>
-<li><p>the session management flags,</p></li>
-<li><p>the implementation function to be call for the method,</p></li>
-<li><p>a short description.</p></li>
-</ul>
-<p>The structure describing methods is defined as follows:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Description of one method of the API provided by the binding</span>
-<span class="co"> * This enumeration is valid for bindings of type 1</span>
-<span class="co"> */</span>
-<span class="kw">struct</span> afb_verb_desc_v1
-{
- <span class="dt">const</span> <span class="dt">char</span> *name; <span class="co">/* name of the method */</span>
- <span class="kw">enum</span> AFB_session_v1 session; <span class="co">/* authorisation and session requirements of the method */</span>
- <span class="dt">void</span> (*callback)(<span class="kw">struct</span> afb_req req); <span class="co">/* callback function implementing the method */</span>
- <span class="dt">const</span> <span class="dt">char</span> *info; <span class="co">/* textual description of the method */</span>
-};</code></pre></div>
-<p>For technical reasons, the enumeration <strong>enum AFB_session_v1</strong> is not exactly an enumeration but the wrapper of constant definitions that can be mixed using bitwise or (the C operator |).</p>
-<p>The constants that can bit mixed are:</p>
-<table style="width:100%;">
-<colgroup>
-<col style="width: 29%" />
-<col style="width: 70%" />
-</colgroup>
-<thead>
-<tr class="header">
-<th style="text-align: left;">Constant name</th>
-<th style="text-align: left;">Meaning</th>
-</tr>
-</thead>
-<tbody>
-<tr class="odd">
-<td style="text-align: left;"><strong>AFB_SESSION_CREATE</strong></td>
-<td style="text-align: left;">Equals to AFB_SESSION_LOA_EQ_0</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;"><strong>AFB_SESSION_CLOSE</strong></td>
-<td style="text-align: left;">Closes the session after the reply and set the LOA to 0</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;"><strong>AFB_SESSION_RENEW</strong></td>
-<td style="text-align: left;">Refreshes the token of authentification</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;"><strong>AFB_SESSION_CHECK</strong></td>
-<td style="text-align: left;">Just requires the token authentification</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_LE_0</strong></td>
-<td style="text-align: left;">Requires the current LOA to be lesser then or equal to 0</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_LE_1</strong></td>
-<td style="text-align: left;">Requires the current LOA to be lesser then or equal to 1</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_LE_2</strong></td>
-<td style="text-align: left;">Requires the current LOA to be lesser then or equal to 2</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_LE_3</strong></td>
-<td style="text-align: left;">Requires the current LOA to be lesser then or equal to 3</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_GE_0</strong></td>
-<td style="text-align: left;">Requires the current LOA to be greater then or equal to 0</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_GE_1</strong></td>
-<td style="text-align: left;">Requires the current LOA to be greater then or equal to 1</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_GE_2</strong></td>
-<td style="text-align: left;">Requires the current LOA to be greater then or equal to 2</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_GE_3</strong></td>
-<td style="text-align: left;">Requires the current LOA to be greater then or equal to 3</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_EQ_0</strong></td>
-<td style="text-align: left;">Requires the current LOA to be equal to 0</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_EQ_1</strong></td>
-<td style="text-align: left;">Requires the current LOA to be equal to 1</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_EQ_2</strong></td>
-<td style="text-align: left;">Requires the current LOA to be equal to 2</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;"><strong>AFB_SESSION_LOA_EQ_3</strong></td>
-<td style="text-align: left;">Requires the current LOA to be equal to 3</td>
-</tr>
-</tbody>
-</table>
-<p>If any of this flag is set, afb-daemon requires an authentication token as if <strong>AFB_SESSION_CHECK</strong> flag was also set.</p>
-<p>The special value <strong>AFB_SESSION_NONE</strong> is zero and can be used to bypass token check.</p>
-<blockquote>
-<p>Note that <strong>AFB_SESSION_CREATE</strong> and <strong>AFB_SESSION_CLOSE</strong> might be removed in later versions.</p>
-</blockquote>
-<h2 id="sending-messages-to-the-log-system">Sending messages to the log system</h2>
-<p>Afb-daemon provides 4 levels of verbosity and 5 methods for logging messages.</p>
-<p>The verbosity is managed. Options allow the change the verbosity of afb-daemon and the verbosity of the bindings can be set binding by binding.</p>
-<p>The methods for logging messages are defined as macros that test the verbosity level and that call the real logging function only if the message must be output. This avoid evaluation of arguments of the formatting messages if the message must not be output.</p>
-<h3 id="verbs-for-logging-messages">Verbs for logging messages</h3>
-<p>The 5 logging methods are:</p>
-<table>
-<thead>
-<tr class="header">
-<th style="text-align: left;">Macro</th>
-<th style="text-align: center;">Verbosity</th>
-<th style="text-align: left;">Meaning</th>
-<th style="text-align: center;">syslog level</th>
-</tr>
-</thead>
-<tbody>
-<tr class="odd">
-<td style="text-align: left;">ERROR</td>
-<td style="text-align: center;">0</td>
-<td style="text-align: left;">Error conditions</td>
-<td style="text-align: center;">3</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;">WARNING</td>
-<td style="text-align: center;">1</td>
-<td style="text-align: left;">Warning conditions</td>
-<td style="text-align: center;">4</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;">NOTICE</td>
-<td style="text-align: center;">1</td>
-<td style="text-align: left;">Normal but significant condition</td>
-<td style="text-align: center;">5</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;">INFO</td>
-<td style="text-align: center;">2</td>
-<td style="text-align: left;">Informational</td>
-<td style="text-align: center;">6</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;">DEBUG</td>
-<td style="text-align: center;">3</td>
-<td style="text-align: left;">Debug-level messages</td>
-<td style="text-align: center;">7</td>
-</tr>
-</tbody>
-</table>
-<p>You can note that the 2 methods <strong>WARNING</strong> and <strong>INFO</strong> have the same level of verbosity. But they don't have the same <em>syslog level</em>. It means that they are output with a different level on the logging system.</p>
-<p>All of these methods have the same signature:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span> ERROR(<span class="dt">const</span> <span class="kw">struct</span> afb_binding_interface *afbitf, <span class="dt">const</span> <span class="dt">char</span> *message, ...);</code></pre></div>
-<p>The first argument <strong>afbitf</strong> is the interface to afb daemon that the binding received at initialisation time when <strong>afbBindingV1Register</strong> is called.</p>
-<p>The second argument <strong>message</strong> is a formatting string compatible with printf/sprintf.</p>
-<p>The remaining arguments are arguments of the formating message like with printf.</p>
-<h3 id="managing-verbosity">Managing verbosity</h3>
-<p>Depending on the level of verbosity, the messages are output or not. The following table explains what messages will be output depending ont the verbosity level.</p>
-<table>
-<thead>
-<tr class="header">
-<th style="text-align: center;">Level of verbosity</th>
-<th style="text-align: left;">Outputed macro</th>
-</tr>
-</thead>
-<tbody>
-<tr class="odd">
-<td style="text-align: center;">0</td>
-<td style="text-align: left;">ERROR</td>
-</tr>
-<tr class="even">
-<td style="text-align: center;">1</td>
-<td style="text-align: left;">ERROR + WARNING + NOTICE</td>
-</tr>
-<tr class="odd">
-<td style="text-align: center;">2</td>
-<td style="text-align: left;">ERROR + WARNING + NOTICE + INFO</td>
-</tr>
-<tr class="even">
-<td style="text-align: center;">3</td>
-<td style="text-align: left;">ERROR + WARNING + NOTICE + INFO + DEBUG</td>
-</tr>
-</tbody>
-</table>
-<h3 id="output-format-and-destination">Output format and destination</h3>
-<p>The syslog level is used for forging a prefix to the message. The prefixes are:</p>
-<table>
-<thead>
-<tr class="header">
-<th style="text-align: center;">syslog level</th>
-<th style="text-align: left;">prefix</th>
-</tr>
-</thead>
-<tbody>
-<tr class="odd">
-<td style="text-align: center;">0</td>
-<td style="text-align: left;">&lt;0&gt; EMERGENCY</td>
-</tr>
-<tr class="even">
-<td style="text-align: center;">1</td>
-<td style="text-align: left;">&lt;1&gt; ALERT</td>
-</tr>
-<tr class="odd">
-<td style="text-align: center;">2</td>
-<td style="text-align: left;">&lt;2&gt; CRITICAL</td>
-</tr>
-<tr class="even">
-<td style="text-align: center;">3</td>
-<td style="text-align: left;">&lt;3&gt; ERROR</td>
-</tr>
-<tr class="odd">
-<td style="text-align: center;">4</td>
-<td style="text-align: left;">&lt;4&gt; WARNING</td>
-</tr>
-<tr class="even">
-<td style="text-align: center;">5</td>
-<td style="text-align: left;">&lt;5&gt; NOTICE</td>
-</tr>
-<tr class="odd">
-<td style="text-align: center;">6</td>
-<td style="text-align: left;">&lt;6&gt; INFO</td>
-</tr>
-<tr class="even">
-<td style="text-align: center;">7</td>
-<td style="text-align: left;">&lt;7&gt; DEBUG</td>
-</tr>
-</tbody>
-</table>
-<p>The message is pushed to standard error. The final destination of the message depends on how systemd service was configured through its variable <strong>StandardError</strong>. It can be journal, syslog or kmsg. (See man sd-daemon).</p>
-<h2 id="sending-events">Sending events</h2>
-<p>Since version 0.5, bindings can broadcast events to any potential listener. As today only unattended even are supported. Targeted events are expected for next coming version.</p>
-<p>The binding <em>tic-tac-toe</em> broadcasts events when the board changes. This is done in the function <strong>changed</strong>:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * signals a change of the board</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="dt">void</span> changed(<span class="kw">struct</span> board *board, <span class="dt">const</span> <span class="dt">char</span> *reason)
-{
- ...
- <span class="kw">struct</span> json_object *description;
-
- <span class="co">/* get the description */</span>
- description = describe(board);
-
- ...
-
- afb_daemon_broadcast_event(afbitf-&gt;daemon, reason, description);
-}</code></pre></div>
-<p>The description of the changed board is pushed via the daemon interface.</p>
-<p>Within binding <em>tic-tac-toe</em>, <em>reason</em> indicates the origin of the change. In function <strong>afb_daemon_broadcast_event</strong> the second parameter is the name of broadcasted event. The third argument is the object that is transmitted with the event.</p>
-<p>Function <strong>afb_daemon_broadcast_event</strong> is defined here after:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Broadcasts widely the event of &#39;name&#39; with the data &#39;object&#39;.</span>
-<span class="co"> * &#39;object&#39; can be NULL.</span>
-<span class="co"> * &#39;daemon&#39; MUST be the daemon given in interface when activating the binding.</span>
-<span class="co"> *</span>
-<span class="co"> * For convenience, the function calls &#39;json_object_put&#39; for &#39;object&#39;.</span>
-<span class="co"> * Thus, in the case where &#39;object&#39; should remain available after</span>
-<span class="co"> * the function returns, the function &#39;json_object_get&#39; shall be used.</span>
-<span class="co"> */</span>
-<span class="dt">void</span> afb_daemon_broadcast_event(<span class="kw">struct</span> afb_daemon daemon, <span class="dt">const</span> <span class="dt">char</span> *name, <span class="kw">struct</span> json_object *object);</code></pre></div>
-<blockquote>
-<p>Be aware, as with reply functions <strong>object</strong> is automatically released using <strong>json_object_put</strong> when using this function. Call <strong>json_object_get</strong> before calling <strong>afb_daemon_broadcast_event</strong> to keep <strong>object</strong> available after function returns.</p>
-</blockquote>
-<p>Event name received by listeners is prefixed with binding name. So when a change occurs after a move, the reason is <strong>move</strong> and every clients receive an event <strong>tictactoe/move</strong>.</p>
-<blockquote>
-<p>Note that nothing is said about case sensitivity of event names. However, the event is always prefixed with the name that the binding declared, with the same case, followed with a slash /. Thus it is safe to compare event using a case sensitive comparison.</p>
-</blockquote>
-<h2 id="writing-an-asynchronous-method-implementation">Writing an asynchronous method implementation</h2>
-<p>The <em>tic-tac-toe</em> example allows two clients or more to share the same board. This is implemented by the method <strong>join</strong> that illustrated partly how to retrieve arguments.</p>
-<p>When two or more clients are sharing a same board, one of them can wait until the state of the board changes, but this could also be implemented using events because an even is generated each time the board changes.</p>
-<p>In this case, the reply to the wait is sent only when the board changes. See the diagram below:</p>
-<pre><code>CLIENT A CLIENT B TIC-TAC-TOE
- | | |
- +--------------|-----------------&gt;| wait . . . . . . . .
- | | | .
- : : : .
- : : : .
- | | | .
- | +-----------------&gt;| move . . . .
- | | | V .
- | |&lt;-----------------+ success of move .
- | | | .
- |&lt;-------------|------------------+ success of wait &lt;</code></pre>
-<p>Here, this is an invocation of the binding by an other client that unblock the suspended <em>wait</em> call. Nevertheless in most case this should be a timer, a hardware event, a sync with a concurrent process or thread, ...</p>
-<p>Common case of an asynchronous implementation.</p>
-<p>Here is the listing of the function <strong>wait</strong>:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">static</span> <span class="dt">void</span> wait(<span class="kw">struct</span> afb_req req)
-{
- <span class="kw">struct</span> board *board;
- <span class="kw">struct</span> waiter *waiter;
-
- <span class="co">/* retrieves the context for the session */</span>
- board = board_of_req(req);
- INFO(afbitf, <span class="st">&quot;method &#39;wait&#39; called for boardid %d&quot;</span>, board-&gt;id);
-
- <span class="co">/* creates the waiter and enqueues it */</span>
- waiter = calloc(<span class="dv">1</span>, <span class="kw">sizeof</span> *waiter);
- waiter-&gt;req = req;
- waiter-&gt;next = board-&gt;waiters;
- afb_req_addref(req);
- board-&gt;waiters = waiter;
-}</code></pre></div>
-<p>After retrieving the board, the function adds a new waiter to waiters list and returns without setting a reply.</p>
-<p>Before returning, it increases <strong>req</strong> request's reference count using <strong>afb_req_addref</strong> function.</p>
-<blockquote>
-<p>When a method returns without setting a reply, it <strong>MUST</strong> increment request's reference count using <strong>afb_req_addref</strong>. If unpredictable behaviour may pop up.</p>
-</blockquote>
-<p>Later, when a board changes, it calls <em>tic-tac-toe</em> <strong>changed</strong> function with reason of change in parameter.</p>
-<p>Here is the full listing of the function <strong>changed</strong>:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * signals a change of the board</span>
-<span class="co"> */</span>
-<span class="dt">static</span> <span class="dt">void</span> changed(<span class="kw">struct</span> board *board, <span class="dt">const</span> <span class="dt">char</span> *reason)
-{
- <span class="kw">struct</span> waiter *waiter, *next;
- <span class="kw">struct</span> json_object *description;
-
- <span class="co">/* get the description */</span>
- description = describe(board);
-
- waiter = board-&gt;waiters;
- board-&gt;waiters = NULL;
- <span class="kw">while</span> (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></div>
-<p>The list of waiters is walked and a reply is sent to each waiter. After sending the reply, the reference count of the request is decremented using <strong>afb_req_unref</strong> to allow resources to be freed.</p>
-<blockquote>
-<p>The reference count <strong>MUST</strong> be decremented using <strong>afb_req_unref</strong> to free resources and avoid memory leaks. This usage count decrement should happen <strong>AFTER</strong> setting reply or bad things may happen.</p>
-</blockquote>
-<h2 id="how-to-build-a-binding">How to build a binding</h2>
-<p>Afb-daemon provides a <em>pkg-config</em> configuration file that can be queried by providing <strong>afb-daemon</strong> in command line arguments. This configuration file provides data that should be used for bindings compilation. Examples:</p>
-<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash">$ <span class="kw">pkg-config</span> --cflags afb-daemon
-$ <span class="kw">pkg-config</span> --libs afb-daemon</code></pre></div>
-<h3 id="example-for-cmake-meta-build-system">Example for cmake meta build system</h3>
-<p>This example is the extract for building the binding <em>afm-main</em> using <em>CMAKE</em>.</p>
-<div class="sourceCode"><pre class="sourceCode cmake"><code class="sourceCode cmake"><span class="fu">pkg_check_modules</span>(afb afb-daemon)
-<span class="kw">if</span>(afb_FOUND)
- <span class="kw">message</span>(<span class="ot">STATUS</span> <span class="st">&quot;Creation afm-main-binding for AFB-DAEMON&quot;</span>)
- <span class="kw">add_library</span>(afm-main-binding <span class="ot">MODULE</span> afm-main-binding.c)
- <span class="kw">target_compile_options</span>(afm-main-binding <span class="ot">PRIVATE</span> <span class="dv">${afb_CFLAGS}</span>)
- <span class="kw">target_include_directories</span>(afm-main-binding <span class="ot">PRIVATE</span> <span class="dv">${afb_INCLUDE_DIRS}</span>)
- <span class="kw">target_link_libraries</span>(afm-main-binding utils <span class="dv">${afb_LIBRARIES}</span>)
- <span class="kw">set_target_properties</span>(afm-main-binding <span class="ot">PROPERTIES</span>
- <span class="ot">PREFIX</span> <span class="st">&quot;&quot;</span>
- <span class="ot">LINK_FLAGS</span> <span class="st">&quot;-Wl,--version-script=</span><span class="dv">${CMAKE_CURRENT_SOURCE_DIR}</span><span class="st">/afm-main-binding.export-map&quot;</span>
- )
- <span class="kw">install</span>(<span class="ot">TARGETS</span> afm-main-binding <span class="ot">LIBRARY</span> <span class="ot">DESTINATION</span> <span class="dv">${binding_dir}</span>)
-<span class="kw">else</span>()
- <span class="kw">message</span>(<span class="ot">STATUS</span> <span class="st">&quot;Not creating the binding for AFB-DAEMON&quot;</span>)
-<span class="kw">endif</span>()</code></pre></div>
-<p>Let now describe some of these lines.</p>
-<div class="sourceCode"><pre class="sourceCode cmake"><code class="sourceCode cmake"><span class="fu">pkg_check_modules</span>(afb afb-daemon)</code></pre></div>
-<p>This first lines searches to the <em>pkg-config</em> configuration file for <strong>afb-daemon</strong>. Resulting data are stored in the following variables:</p>
-<table style="width:94%;">
-<colgroup>
-<col style="width: 26%" />
-<col style="width: 68%" />
-</colgroup>
-<thead>
-<tr class="header">
-<th style="text-align: left;">Variable</th>
-<th style="text-align: left;">Meaning</th>
-</tr>
-</thead>
-<tbody>
-<tr class="odd">
-<td style="text-align: left;">afb_FOUND</td>
-<td style="text-align: left;">Set to 1 if afb-daemon binding development files exist</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;">afb_LIBRARIES</td>
-<td style="text-align: left;">Only the libraries (w/o the '-l') for compiling afb-daemon bindings</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;">afb_LIBRARY_DIRS</td>
-<td style="text-align: left;">The paths of the libraries (w/o the '-L') for compiling afb-daemon bindings</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;">afb_LDFLAGS</td>
-<td style="text-align: left;">All required linker flags for compiling afb-daemon bindings</td>
-</tr>
-<tr class="odd">
-<td style="text-align: left;">afb_INCLUDE_DIRS</td>
-<td style="text-align: left;">The '-I' preprocessor flags (w/o the '-I') for compiling afb-daemon bindings</td>
-</tr>
-<tr class="even">
-<td style="text-align: left;">afb_CFLAGS</td>
-<td style="text-align: left;">All required cflags for compiling afb-daemon bindings</td>
-</tr>
-</tbody>
-</table>
-<p>If development files are found, the binding can be added to the set of target to build.</p>
-<div class="sourceCode"><pre class="sourceCode cmake"><code class="sourceCode cmake"><span class="kw">add_library</span>(afm-main-binding <span class="ot">MODULE</span> afm-main-binding.c)</code></pre></div>
-<p>This line asks to create a shared library having a single source file named afm-main-binding.c to be compiled. The default name of the created shared object is <strong>libafm-main-binding.so</strong>.</p>
-<div class="sourceCode"><pre class="sourceCode cmake"><code class="sourceCode cmake"><span class="kw">set_target_properties</span>(afm-main-binding <span class="ot">PROPERTIES</span>
- <span class="ot">PREFIX</span> <span class="st">&quot;&quot;</span>
- <span class="ot">LINK_FLAGS</span> <span class="st">&quot;-Wl,--version-script=</span><span class="dv">${CMAKE_CURRENT_SOURCE_DIR}</span><span class="st">/afm-main-binding.export-map&quot;</span>
-)</code></pre></div>
-<p>This lines are doing two things:</p>
-<ol type="1">
-<li><p>It renames the built library from <strong>libafm-main-binding.so</strong> to <strong>afm-main-binding.so</strong> by removing the implicitly added prefix <em>lib</em>. This step is not mandatory because afb-daemon doesn't check names of files at load time. The only filename convention used by afb-daemon relates to <strong>.so</strong> termination. *.so pattern is used when afb-daemon automatically discovers binding from a directory hierarchy.</p></li>
-<li><p>It applies a version script at link time to only export the reserved name <strong>afbBindingV1Register</strong> for registration entry point. By default, when building a shared library linker exports all the public symbols (C functions that are not <strong>static</strong>).</p></li>
-</ol>
-<p>Next line are:</p>
-<div class="sourceCode"><pre class="sourceCode cmake"><code class="sourceCode cmake"><span class="kw">target_include_directories</span>(afm-main-binding <span class="ot">PRIVATE</span> <span class="dv">${afb_INCLUDE_DIRS}</span>)
-<span class="kw">target_link_libraries</span>(afm-main-binding utils <span class="dv">${afb_LIBRARIES}</span>)</code></pre></div>
-<p>As you can see it uses the variables computed by <strong><em>pkg_check_modules(afb afb-daemon)</em></strong> to configure the compiler and the linker.</p>
-<h3 id="exporting-the-function-afbbindingv1register">Exporting the function afbBindingV1Register</h3>
-<p>The function <strong>afbBindingV1Register</strong> MUST be exported. This can be achieved using a version script at link time. Here after is a version script used for <em>tic-tac-toe</em> (bindings/samples/export.map).</p>
-<pre><code>{ global: afbBindingV1Register; local: *; };</code></pre>
-<p>This sample <a href="https://sourceware.org/binutils/docs-2.26/ld/VERSION.html#VERSION">version script</a> exports as global the symbol <em>afbBindingV1Register</em> and hides any other symbols.</p>
-<p>This version script is added to the link options using the option <strong>--version-script=export.map</strong> is given directly to the linker or using the option <strong>-Wl,--version-script=export.map</strong> when the option is given to the C compiler.</p>
-<h3 id="building-within-yocto">Building within yocto</h3>
-<p>Adding a dependency to afb-daemon is enough. See below:</p>
-<pre><code>DEPENDS += &quot; afb-daemon &quot;</code></pre>
-</body>
-</html>
diff --git a/doc/afb-bindings-writing.md b/doc/afb-bindings-writing.md
index 6327734e..1db5a435 100644
--- a/doc/afb-bindings-writing.md
+++ b/doc/afb-bindings-writing.md
@@ -1,16 +1,16 @@
-HOWTO WRITE a BINDING for AFB-DAEMON
+How to write a binding for AFB-DAEMON
===================================
Summary
-------
-Afb-daemon binders serve files through HTTP protocol
-and offers to developers the capability to expose application API methods through
-HTTP or WebSocket protocol.
+The afb-daemon binders serve files through HTTP protocol and offers to
+developers the capability to offer application API methods through HTTP or
+WebSocket protocol.
-Binder bindings are used to add API to afb-daemon.
-This part describes how to write a binding for afb-daemon.
+The bindings are used to add API to ***afb-daemon***.
+This part describes how to write a binding for***afb-daemon***.
Excepting this summary, this document target developers.
@@ -19,132 +19,148 @@ a short overview of binder bindings fundamentals.
### Nature of a binding
-A binding is an independent piece of software. A binding is self contain and exposes application logic as sharable library.
-A binding is intended to be dynamically loaded by afb-daemon to expose application API.
+A binding is an independent piece of software. A binding is self contain and
+exposes application logic as sharable library. A binding is intended to be
+dynamically loaded by ***afb-daemon*** to expose application API.
-Technically, a binder binding does not reference and is not linked with any afb-daemon library.
+Technically, a binder binding does not reference and is not linked with any
+***afb-daemon*** library.
### Class of bindings
-Application binder supports two kinds of bindings: application bindings and service bindings.
-Technically both class of binding are equivalent are use the same coding convention. Only sharing mode and security context diverge.
+Application binder supports two kinds of bindings: application bindings and
+service bindings. Technically both class of binding are equivalent and use the
+same coding convention. Only sharing mode and security context diverge.
#### Application-bindings
-Application-bindings implements the glue in between application's UI and services. Every AGL application
-has a corresponding binder that typically activates one or many bindings to interface the application logic with lower platform services.
-When an application is started by the AGL application framework, a dedicate binder is started that loads/activates application binding(s).
-API expose by application-binding are executed within corresponding application security context.
+Application-bindings implements the glue in between application's UI and
+services. Every AGL application has a corresponding binder that typically
+activates one or many bindings to interface the application logic with lower
+platform services. When an application is started by the AGL application
+framework, a dedicate binder is started that loads/activates application
+binding(s). API expose by application-binding are executed within corresponding
+application security context.
-Application bindings generally handle a unique context for a unique client. As the application framework start
-a dedicated instance of afb_daemon for each AGL application, if a given binding is used within multiple application each of those
-application get a new and private instance of eventually "shared" binding.
+Application bindings generally handle a unique context for a unique client. As
+the application framework start a dedicated instance of afb_daemon for each AGL
+application, if a given binding is used within multiple application each of
+those application get a new and private instance of eventually "shared" binding.
#### Service-bindings
-Service-bindings enable API activation within corresponding service security context and not within calling application context.
-Service-bindings are intended to run as a unique instance. Service-bindings can be shared in between multiple clients.
+Service-bindings enable API activation within corresponding service security
+context and not within calling application context. Service-bindings are
+intended to run as a unique instance. Service-bindings can be shared in between
+multiple clients.
-Service-bindings can either be stateless or manage client context. When managing context each client get a private context.
+Service-bindings can either be stateless or manage client context. When managing
+context each client get a private context. Sharing may either be global to the
+platform (ie: GPS service) or dedicated to a given user (ie: user preferences)
-Sharing may either be global to the platform (ie: GPS service) or dedicated to a given user (ie: user preferences)
-
-### Live cycle of bindings within afb-daemon
+### Live cycle of bindings within ***afb-daemon***
-Application and service bindings are loaded and activated each time a new afb-daemon is started.
+Application and service bindings are loaded and activated each time a new
+***afb-daemon*** is started.
-At launch time, every loaded binding initialise itself.
-If a single binding initialisation fail corresponding instance of afb-daemon self aborts.
+At launch time, every loaded binding initialise itself. If a single binding
+initialisation fails the corresponding instance of ***afb-daemon*** aborts.
-Conversely, when a binding initialisation succeeds, it should register
-its unique name as well as the list of verbs attached to the methods it exposes.
+Conversely, when a binding initialisation succeeds, it should register its
+unique name as well as the list of verbs (methods name from binder point of
+view) attached to the methods it exposes.
-When initialised, on request from application clients to the right API/verb, binding methods
-are activated by the afb-daemon attached to the application or service.
+When initialised, on request from application clients to the right API/verbs
+binding methods are activated by the ***afb-daemon*** attached to the
+application or service.
-At exit time, no special action is enforced by afb-daemon. When a specific actions is required at afb-daemon stop,
-developers should use 'atexit/on_exit' during binding initialisation sequence to register a custom exit function.
+At exit time, no special action is enforced by ***afb-daemon***. When a specific
+actions is required at afb-daemon stop, developers should use 'atexit/on_exit'
+during binding initialisation sequence to register a custom exit function.
-### Binding Contend
+### Binding Content
-Afb-daemon's binding register two classes of objects: names and functions.
+Afb-daemon's bindings register two classes of objects: names and functions.
Bindings declare categories of names:
- - A unique binding name to access all API expose by this binding,
+ - A unique binding name to access all API exposed by this binding,
- One name for each methods/verbs provided by this binding.
Bindings declare two categories of functions:
- - function use for the initialisation
- - functions implementing exposed API methods
+ - function used for initialisation
+ - functions implementing the exposed API methods
-Afb-daemon parses URI requests to extract the API(binding name) and the VERB(method to activate).
-As an example, URI **foo/bar** translates to binding named **foo** and method named **bar**.
-To serve such a request, afb-daemon looks for an active binding named **foo** and then within this binding for a method named **bar**.
-When find afb-daemon calls corresponding method with attached parameter if any.
+Afb-daemon parses URI requests to extract the API(binding name) and the
+VERB(method to activate). As an example, URI **foo/bar** translates to binding
+named **foo** and method named **bar**. To serve such a request,
+***afb-daemon*** looks for an active binding named **foo** and then within this
+binding for a method named **bar**. When found ***afb-daemon*** calls
+the corresponding method with an attached parameter if any.
-Afb-daemon ignores letter case when parsing URI. Thus **TicTacToe/Board** and **tictactoe/board** are equivalent.
+Afb-daemon is case-insensitive when parsing URI. Thus **TicTacToe/Board** and
+**tictactoe/board** are equivalent.
#### The name of the binding
The name of a given binding is also known as the name
of the API prefix that defines the binding.
-The name of a binding SHOULD be unique within a given afb-daemon instance.
+The name of a binding SHOULD be unique within a given ***afb-daemon*** instance.
-For example, when a client of afb-daemon calls a URI named **foo/bar**. Afb-daemon
-extracts the prefix **foo** and the suffix **bar**. **foo** must match a binding name and **bar** a VERB attached to some method.
+For example, when a client of ***afb-daemon*** calls a URI named **foo/bar**.
+Afb-daemon extracts the prefix **foo** and the suffix **bar**. **foo** must
+match a binding name and **bar** has to match a VERB attached to some method.
#### Names of methods
-Each binding exposes a set of methods that can be called
-by the clients of a given afb-daemon.
+Each binding exposes a set of methods that can be called by the clients of a
+given ***afb-daemon***.
VERB's name attached to a given binding (API) MUST be unique within a binding.
-Bindings static declaration link VERBS to corresponding methods.
-When clients emit requests on a given API/VERB corresponding method is called by afb-daemon.
+Bindings static declaration link VERBS to the corresponding methods.
+When clients emit requests on a given API/VERB corresponding method is called
+by ***afb-daemon***.
#### Initialisation function
Binding's initialisation function serves several purposes.
-1. It allows afb-daemon to control binding version depending on initialisation function name.
-As today, the only supported initialisation function is **afbBindingV1Register**. This identifies
-version "one" of bindings.
+1. It allows ***afb-daemon*** to control the binding version depending on
+the initialisation of function name. As today, the only supported initialisation
+function is **afbBindingV1Register**. This identifies version "one" of bindings.
2. It allows bindings to initialise itself.
-3. It enables names declarations: descriptions, requirements and implementations of exposed API/VERB.
+3. It enables names declarations: descriptions, requirements and implementations
+of exposed API/VERB.
#### Functions instantiation of API/VERBs
-When an API/VERB is called, afb-daemon constructs a request object. Then it
-passes this request object to the implementation function corresponding to requested method, this
-within attached API binding.
+When an API/VERB is called, ***afb-daemon*** constructs a request object. Then
+it passes this request object to the implementation function corresponding to
+requested method, this within attached API binding.
-An implementation function receives a request object that
-is used to: get arguments of the request, send
-answer, store session data.
+An implementation function receives a request object used to: get
+the arguments of the request, send an answer, store session data.
A binding MUST set an answer to every received requests.
-Nevertheless it is not mandatory to set the answer
-before returning from API/VERB implementing function.
-This behaviour is important for asynchronous actions.
+Nevertheless, there are two implementations, *synchronous* and *asynchronous*.
+API/VERB implementation that set an answer before returning are called
+*synchronous implementations*. Those that do not systematically set an answer
+before returning are called *asynchronous implementations*.
-API/VERB implementation that set an answer before returning are called *synchronous implementations*.
-Those that do not systematically set an answer before returning are called *asynchronous implementations*.
-
-Asynchronous implementations typically launch asynchronous actions. They record some context at
-request time and provide answer to the request only at completion of asynchronous actions.
+Asynchronous implementations typically launch asynchronous actions. They record
+some context at request time and provide an answer to the request only at
+completion of asynchronous actions.
The Tic-Tac-Toe example
-----------------------
-This part explains how to write an afb-binding.
-For the sake of being practical it uses many
-examples based on tic-tac-toe.
-This binding example is in *bindings/samples/tic-tac-toe.c*.
+This part explains how to write an afb-binding. For the sake of being practical
+it uses many examples based on tic-tac-toe. This binding example is in
+*bindings/samples/tic-tac-toe.c*.
This binding is named ***tictactoe***.
@@ -159,25 +175,27 @@ Typing the command
Print flags use for compilation:
$ pkg-config --cflags afb-daemon
- -I/opt/local/include -I/usr/include/json-c
+ -I/opt/local/include -I/usr/include/json-c
For linking, you should use
$ pkg-config --libs afb-daemon
-ljson-c
-Afb-daemon automatically includes dependency to json-c.
+Afb-daemon automatically includes the dependency to json-c.
This is activated through **Requires** keyword in pkg-config.
-While almost every binding replies on **json-c** this is not a must have dependency.
-
-Internally, afb-daemon relies on **libsystemd** for its event loop, as well
-as for its binding to D-Bus.
-Bindings developers are encouraged to leverage **libsystemd** when possible.
-Nevertheless there is no hard dependency to **libsystemd** if ever
-you rather not use it, feel free to do so.
-
-> Afb-daemon binding are fully self contain. They do not enforce dependency on any libraries from the application framework.
-> Afb-daemon dependencies requirer to run AGL bindings are given at runtime through pointers leveraging read-only
+While almost every binding replies on **json-c** this is not a must have
+dependency.
+
+Internally, ***afb-daemon*** relies on **libsystemd** for its event loop, as
+well as for its binding to D-Bus. Bindings developers are encouraged to leverage
+**libsystemd** when possible. Nevertheless there is no hard dependency to
+**libsystemd** if you do not want to use it, feel free to do so.
+
+> Afb-daemon bindings are fully self contained. They do not enforce dependency
+on any libraries from the application framework.
+> Afb-daemon dependencies requirer to run AGL bindings are given at runtime
+through pointers leveraging read-only
> memory feature.
Header files to include
@@ -266,11 +284,342 @@ Nevertheless this is not the case with javascript dot notation:
Using the dot notation, the key must be a valid javascript
identifier and dash(-) as well as few other reserved characters cannot be used.
-For this reason, we advise developper to chose name compatible with both javascript and HTML notation.
+For this reason, we advise developers to chose name compatible with both
+javascript and HTML notation.
It is a good practice, even for arguments not to rely on case sensitivity.
-This may reduce headache strength at debug time, especially with interpreted language like
-javascript that may not warn you that a variable was not defined.
+This may reduce headache strength at debug time, especially with interpreted
+language like javascript that may not warn you that a variable was not defined.
+
+Declaration of methods and initialisation of the bindings
+---------------------------------------------------------
+
+### Declaration of methods
+
+To be active, binding's methods should be declared to
+***afb-daemon***. Furthermore, the binding itself must be recorded.
+
+The registration mechanism is very basic: when ***afb-daemon*** starts,
+it loads all bindings listed in: command line or configuration file.
+
+Loading a binding follows the following steps:
+
+1. Afb-daemon loads the binding with *dlopen*.
+
+2. Afb-daemon searches for a symbol named **afbBindingV1Register** using *dlsym*.
+This symbol is assumed to be the exported initialisation function of the binding.
+
+3. Afb-daemon builds an interface object for the binding.
+
+4. Afb-daemon calls the found function **afbBindingV1Register** with interface pointer
+as parameter.
+
+5. Function **afbBindingV1Register** setups the binding and initialises it.
+
+6. Function **afbBindingV1Register** returns the pointer to a structure
+describing the binding: version, name (prefix or API name), and list of methods.
+
+7. Afb-daemon checks that the returned version and name can be managed.
+If so, binding and its methods are register to become usable as soon as
+***afb-daemon*** initialisation is finished.
+
+### Initialisation of bindings
+
+The bindings initialisation is the final step made at the end of declaration of
+methods. This will initialize the binding and make its ***afb-daemon***'s
+interface fully functional.
+
+So, afb-daemon binder call **afbBindingV1ServiceInit** as final step to a
+binding. This will allows the binding to call features in its name and as saw in
+[Binder events guide](afb-events-guide.md) you can create an event only at this
+moment and not before. Before that it will fail because afb-daemon doesn't know
+the binding name.
+
+**afbBindingV1ServiceInit** is defined as below:
+
+```C
+/*
+ * When a binding have an exported implementation of the
+ * function 'afbBindingV1ServiceInit', defined below,
+ * the framework calls it for initialising the service after
+ * registration of all bindings.
+ *
+ * The object 'service' should be recorded. It has functions that
+ * allows the binding to call features with its own personality.
+ *
+ * The function should return 0 in case of success or, else, should return
+ * a negative value.
+ */
+extern int afbBindingV1ServiceInit(struct afb_service service);
+```
+
+### Application binding example: tic-tac-toe
+
+If we continue our tic-tac-toe example, here after the code used for
+**afbBindingV1Register** implementation from binding *tic-tac-toe*:
+
+```C
+/*
+ * activation function for registering the binding called by afb-daemon
+ */
+const struct afb_binding *afbBindingV1Register(const struct afb_binding_interface *itf)
+{
+ afbitf = itf; // records the interface for accessing afb-daemon
+ return &binding_description; // returns the description of the binding
+}
+```
+
+It is a very minimal initialisation function because *tic-tac-toe* binding doesn't
+have any application related initialisation step. It merely record daemon's interface
+and returns its description.
+
+The variable **afbitf** is a binding global variable. It keeps the
+interface to ***afb-daemon*** that should be used for logging and pushing events.
+Here is its declaration:
+
+```C
+/*
+ * the interface to afb-daemon
+ */
+const struct afb_binding_interface *afbitf;
+```
+
+The description of the binding is defined here after.
+
+```C
+/*
+ * array of the methods exported to afb-daemon
+ */
+static const struct afb_verb_desc_v1 binding_methods[] = {
+ /* 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= "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= "join", .session= AFB_SESSION_CHECK,.callback= join, .info= "Join a board" },
+ { .name= "undo", .session= AFB_SESSION_NONE, .callback= undo, .info= "Undo the last move" },
+ { .name= "wait", .session= AFB_SESSION_NONE, .callback= wait, .info= "Wait for a change" },
+ { .name= NULL } /* marker for end of the array */
+};
+
+/*
+ * description of the binding for afb-daemon
+ */
+static const struct afb_binding binding_description =
+{
+ /* description conforms to VERSION 1 */
+ .type= AFB_BINDING_VERSION_1,
+ .v1= { /* fills the v1 field of the union when AFB_BINDING_VERSION_1 */
+ .prefix= "tictactoe", /* the API name (or binding name or prefix) */
+ .info= "Sample tac-tac-toe game", /* short description of of the binding */
+ .methods = binding_methods /* the array describing the methods of the API */
+ }
+};
+```
+
+The structure **binding_description** describes the binding.
+It declares the type and version of the binding, its name, a short description
+and its methods list.
+
+The list of methods is an array of structures describing the methods and terminated by a NULL marker.
+
+In version one of afb-damon binding, a method description contains 4 fields:
+
+- the name of the method,
+
+- the session management flags,
+
+- the implementation function to be call for the method,
+
+- a short description.
+
+The structure describing methods is defined as follows:
+
+```C
+/*
+ * Description of one method of the API provided by the binding
+ * This enumeration is valid for bindings of type 1
+ */
+struct afb_verb_desc_v1
+{
+ const char *name; /* name of the method */
+ enum AFB_session_v1 session; /* authorisation and session requirements of the method */
+ void (*callback)(struct afb_req req); /* callback function implementing the method */
+ const char *info; /* textual description of the method */
+};
+```
+
+For technical reasons, the enumeration **enum AFB_session_v1** is not exactly an
+enumeration but the wrapper of constant definitions that can be mixed using bitwise or
+(the C operator |).
+
+The constants that can bit mixed are:
+
+Constant name | Meaning
+-------------------------|-------------------------------------------------------------
+**AFB_SESSION_CREATE** | Equals to AFB_SESSION_LOA_EQ_0|AFB_SESSION_RENEW
+**AFB_SESSION_CLOSE** | Closes the session after the reply and set the LOA to 0
+**AFB_SESSION_RENEW** | Refreshes the token of authentification
+**AFB_SESSION_CHECK** | Just requires the token authentification
+**AFB_SESSION_LOA_LE_0** | Requires the current LOA to be lesser then or equal to 0
+**AFB_SESSION_LOA_LE_1** | Requires the current LOA to be lesser then or equal to 1
+**AFB_SESSION_LOA_LE_2** | Requires the current LOA to be lesser then or equal to 2
+**AFB_SESSION_LOA_LE_3** | Requires the current LOA to be lesser then or equal to 3
+**AFB_SESSION_LOA_GE_0** | Requires the current LOA to be greater then or equal to 0
+**AFB_SESSION_LOA_GE_1** | Requires the current LOA to be greater then or equal to 1
+**AFB_SESSION_LOA_GE_2** | Requires the current LOA to be greater then or equal to 2
+**AFB_SESSION_LOA_GE_3** | Requires the current LOA to be greater then or equal to 3
+**AFB_SESSION_LOA_EQ_0** | Requires the current LOA to be equal to 0
+**AFB_SESSION_LOA_EQ_1** | Requires the current LOA to be equal to 1
+**AFB_SESSION_LOA_EQ_2** | Requires the current LOA to be equal to 2
+**AFB_SESSION_LOA_EQ_3** | Requires the current LOA to be equal to 3
+
+If any of this flag is set, ***afb-daemon*** requires an authentication token
+as if **AFB_SESSION_CHECK** flag was also set.
+
+The special value **AFB_SESSION_NONE** is zero and can be used to bypass token check.
+
+> Note that **AFB_SESSION_CREATE** and **AFB_SESSION_CLOSE** might be removed in later versions.
+
+Sending messages to the log system
+----------------------------------
+
+Afb-daemon provides 4 levels of verbosity and 5 methods for logging messages.
+
+The verbosity is managed. Options allow the change the verbosity of ***afb-daemon***
+and the verbosity of the bindings can be set binding by binding.
+
+The methods for logging messages are defined as macros that test the
+verbosity level and that call the real logging function only if the
+message must be output. This avoid evaluation of arguments of the
+formatting messages if the message must not be output.
+
+### Verbs for logging messages
+
+The 5 logging methods are:
+
+Macro | Verbosity | Meaning | syslog level
+--------|:---------:|-----------------------------------|:-----------:
+ERROR | 0 | Error conditions | 3
+WARNING | 1 | Warning conditions | 4
+NOTICE | 1 | Normal but significant condition | 5
+INFO | 2 | Informational | 6
+DEBUG | 3 | Debug-level messages | 7
+
+You can note that the 2 methods **WARNING** and **NOTICE** have the same level
+of verbosity. But they don't have the same *syslog level*. It means that
+they are output with a different level on the logging system.
+
+All of these methods have the same signature:
+
+```C
+void ERROR(const struct afb_binding_interface *afbitf, const char *message, ...);
+```
+
+The first argument **afbitf** is the interface to afb daemon that the
+binding received at initialisation time when **afbBindingV1Register** is called.
+
+The second argument **message** is a formatting string compatible with printf/sprintf.
+
+The remaining arguments are arguments of the formating message like with printf.
+
+### Managing verbosity
+
+Depending on the level of verbosity, the messages are output or not.
+The following table explains what messages will be output depending
+ont the verbosity level.
+
+Level of verbosity | Outputed macro
+:-----------------:|--------------------------
+0 | ERROR
+1 | ERROR + WARNING + NOTICE
+2 | ERROR + WARNING + NOTICE + INFO
+3 | ERROR + WARNING + NOTICE + INFO + DEBUG
+
+### Output format and destination
+
+The syslog level is used for forging a prefix to the message.
+The prefixes are:
+
+syslog level | prefix
+:-----------:|---------------
+0 | <0> EMERGENCY
+1 | <1> ALERT
+2 | <2> CRITICAL
+3 | <3> ERROR
+4 | <4> WARNING
+5 | <5> NOTICE
+6 | <6> INFO
+7 | <7> DEBUG
+
+
+The message is pushed to standard error.
+The final destination of the message depends on how systemd service
+was configured through its variable **StandardError**. It can be
+journal, syslog or kmsg. (See man sd-daemon).
+
+Sending events
+--------------
+
+Specific documentation exists about [sending events](afb-events-guide.md).
+
+The binding *tic-tac-toe* broadcasts events when the board changes. This is done
+in the function ***changed***:
+
+```C
+/*
+ * 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 binding *tic-tac-toe*, *reason* indicates the origin of
+the change. In function **afb_daemon_broadcast_event** the second
+parameter is the name of broadcasted event. The third argument is the
+object that is transmitted with the event.
+
+Function **afb_daemon_broadcast_event** is defined here after:
+
+```C
+/*
+ * 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 binding.
+ *
+ * For convenience, the function calls 'json_object_put' for 'object'.
+ * Thus, in the case where 'object' should remain available after
+ * the function returns, the function 'json_object_get' shall be used.
+ */
+void afb_daemon_broadcast_event(struct afb_daemon daemon, const char *name, struct json_object *object);
+```
+
+> Be aware, as with reply functions **object** is automatically released using
+> **json_object_put** when using this function. Call **json_object_get** before
+> calling **afb_daemon_broadcast_event** to keep **object** available
+> after function returns.
+
+Event name received by listeners is prefixed with binding name.
+So when a change occurs after a move, the reason is **move** and every clients
+receive an event **tictactoe/move**.
+
+> Note that nothing is said about case sensitivity of event names.
+> However, the event is always prefixed with the name that the binding
+> declared, with the same case, followed with a slash /.
+> Thus it is safe to compare event using a case sensitive comparison.
Writing a synchronous method implementation
-----------------------------------------
@@ -307,7 +656,7 @@ for the binding: the board.
2. The macro **INFO** sends a message of kind *INFO*
to the logging system. The global variable named **afbitf**
-used represents the interface to afb-daemon.
+used represents the interface to ***afb-daemon***.
3. The function **describe** creates a json_object representing
the board.
@@ -335,11 +684,11 @@ struct afb_req {
```
It contains two pointers: first one *itf*, points to functions used
-to handle internal request. Second one *closure* point onto function closure.
+to handle internal request. Second one *closure* point onto function closure.
> The structure must never be used directly.
> Instead developer should use the intended functions provided
-> by afb-daemon as described here after.
+> by ***afb-daemon*** as described here after.
*req* is used to get arguments of the request, to send
answer, to store session data.
@@ -362,7 +711,8 @@ For a binding, having data associated to a session is common.
This data is called "binding context" for the session.
Within *tic-tac-toe* binding the context is the board.
-Requests *afb_req* offer four functions for storing and retrieving session associated context.
+Requests *afb_req* offer four functions for storing and retrieving session
+associated context.
These functions are:
@@ -394,7 +744,7 @@ static inline struct board *board_of_req(struct afb_req req)
The function **afb_req_context** ensures an existing context
for the session of the request.
-Its two last arguments are functions to allocate and free context.
+Its two last arguments are functions to allocate and free context.
Note function type casts to avoid compilation warnings.
Here is the definition of the function **afb_req_context**
@@ -425,8 +775,8 @@ The boards are checking usage count to free resources when not used.
The third argument is a function that frees context resources.
For binding *tic-tac-toe* (function **release_board**).
-The function **release_board** decrease usage count of the board passed in argument.
-When usage count falls to zero, data board are freed.
+The function **release_board** decrease usage count of the board passed in
+argument. When usage count falls to zero, data board are freed.
Definition of other functions dealing with contexts:
@@ -669,7 +1019,7 @@ The value is the name of the file as it was set by the HTTP client.
Generally it is the filename on client side.
The path is the effective path of saved file on the temporary local storage
-area of the application. This is a randomly generated and unique filename.
+area of the application. This is a randomly generated and unique filename.
It is not linked with the original filename as used on client side.
After success the binding can use the uploaded file directly from local storage path with no restriction:
@@ -692,7 +1042,7 @@ struct json_object *afb_req_json(struct afb_req req);
It returns a json object. This object depends on how the request was built:
-- For HTTP requests, this json object uses key names mapped on argument name.
+- For HTTP requests, this json object uses key names mapped on argument name.
Values are either string for common arguments or object ie: { "file": "...", "path": "..." }
- For WebSockets requests, returned directly the object as provided by the client.
@@ -701,168 +1051,106 @@ Values are either string for common arguments or object ie: { "file": "...", "pa
> can be seen as a shortcut to
> ***json_object_get_string(json_object_object_get(afb_req_json(req), name))***
-Initialisation of the binding and declaration of methods
------------------------------------------------------
-
-To be active, binding's methods should be declared to
-afb-daemon. Furthermore, the binding itself must be recorded.
-
-The registration mechanism is very basic: when afb-need starts,
-it loads all bindings listed in: command line or configuration file.
-
-Loading a binding follows the following steps:
-1. Afb-daemon loads the binding with *dlopen*.
+Writing an asynchronous method implementation
+-------------------------------------------
-2. Afb-daemon searches for a symbol named **afbBindingV1Register** using *dlsym*.
-This symbol is assumed to be the exported initialisation function of the binding.
+The *tic-tac-toe* example allows two clients or more to share the same board.
+This is implemented by the method **join** that illustrated partly how to
+retrieve arguments.
-3. Afb-daemon builds an interface object for the binding.
+When two or more clients are sharing a same board, one of them can wait
+until the state of the board changes, but this could also be implemented using
+events because an event is generated each time the board changes.
-4. Afb-daemon calls the found function **afbBindingV1Register** with interface pointer
-as parameter.
+In this case, the reply to the wait is sent only when the board changes.
+See the diagram below:
-5. Function **afbBindingV1Register** setups the binding and initialises it.
+![tic-tac-toe_diagram][tic-tac-toe_diagram]
-6. Function **afbBindingV1Register** returns the pointer to a structure
-describing the binding: version, name (prefix or API name), and list of methods.
+Here, this is an invocation of the binding by an other client that
+unblock the suspended *wait* call.
+Nevertheless in most case this should be a timer, a hardware event, a sync with
+a concurrent process or thread, ...
-7. Afb-daemon checks that the returned version and name can be managed.
-If so, binding and its methods are register to become usable as soon as
-afb-daemon initialisation is finished.
+Common case of an asynchronous implementation.
-Here after the code used for **afbBindingV1Register** from binding *tic-tac-toe*:
+Here is the listing of the function **wait**:
```C
-/*
- * activation function for registering the binding called by afb-daemon
- */
-const struct afb_binding *afbBindingV1Register(const struct afb_binding_interface *itf)
+static void wait(struct afb_req req)
{
- afbitf = itf; // records the interface for accessing afb-daemon
- return &binding_description; // returns the description of the binding
-}
-```
-
-It is a very minimal initialisation function because *tic-tac-toe* binding doesn't
-have any application related initialisation step. It merely record daemon's interface
-and returns its description.
-
-The variable **afbitf** is a binding global variable. It keeps the
-interface to afb-daemon that should be used for logging and pushing events.
-Here is its declaration:
-
-```C
-/*
- * the interface to afb-daemon
- */
-const struct afb_binding_interface *afbitf;
-```
-
-The description of the binding is defined here after.
+ struct board *board;
+ struct waiter *waiter;
-```C
-/*
- * array of the methods exported to afb-daemon
- */
-static const struct afb_verb_desc_v1 binding_methods[] = {
- /* 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= "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= "join", .session= AFB_SESSION_CHECK,.callback= join, .info= "Join a board" },
- { .name= "undo", .session= AFB_SESSION_NONE, .callback= undo, .info= "Undo the last move" },
- { .name= "wait", .session= AFB_SESSION_NONE, .callback= wait, .info= "Wait for a change" },
- { .name= NULL } /* marker for end of the array */
-};
+ /* retrieves the context for the session */
+ board = board_of_req(req);
+ INFO(afbitf, "method 'wait' called for boardid %d", board->id);
-/*
- * description of the binding for afb-daemon
- */
-static const struct afb_binding binding_description =
-{
- /* description conforms to VERSION 1 */
- .type= AFB_BINDING_VERSION_1,
- .v1= { /* fills the v1 field of the union when AFB_BINDING_VERSION_1 */
- .prefix= "tictactoe", /* the API name (or binding name or prefix) */
- .info= "Sample tac-tac-toe game", /* short description of of the binding */
- .methods = binding_methods /* the array describing the methods of the API */
- }
-};
+ /* creates the waiter and enqueues it */
+ waiter = calloc(1, sizeof *waiter);
+ waiter->req = req;
+ waiter->next = board->waiters;
+ afb_req_addref(req);
+ board->waiters = waiter;
+}
```
-The structure **binding_description** describes the binding.
-It declares the type and version of the binding, its name, a short description
-and its methods list.
-
-The list of methods is an array of structures describing the methods and terminated by a NULL marker.
-
-In version one of afb-damon binding, a method description contains 4 fields:
-
-- the name of the method,
+After retrieving the board, the function adds a new waiter to
+waiters list and returns without setting a reply.
-- the session management flags,
+Before returning, it increases **req** request's reference count using **afb_req_addref** function.
-- the implementation function to be call for the method,
+> When a method returns without setting a reply,
+> it **MUST** increment request's reference count
+> using **afb_req_addref**. If unpredictable behaviour may pop up.
-- a short description.
+Later, when a board changes, it calls *tic-tac-toe* **changed** function
+with reason of change in parameter.
-The structure describing methods is defined as follows:
+Here is the full listing of the function **changed**:
```C
/*
- * Description of one method of the API provided by the binding
- * This enumeration is valid for bindings of type 1
+ * signals a change of the board
*/
-struct afb_verb_desc_v1
+static void changed(struct board *board, const char *reason)
{
- const char *name; /* name of the method */
- enum AFB_session_v1 session; /* authorisation and session requirements of the method */
- void (*callback)(struct afb_req req); /* callback function implementing the method */
- const char *info; /* textual description of the method */
-};
-```
-
-For technical reasons, the enumeration **enum AFB_session_v1** is not exactly an
-enumeration but the wrapper of constant definitions that can be mixed using bitwise or
-(the C operator |).
+ struct waiter *waiter, *next;
+ struct json_object *description;
-The constants that can bit mixed are:
+ /* get the description */
+ description = describe(board);
-Constant name | Meaning
--------------------------|-------------------------------------------------------------
-**AFB_SESSION_CREATE** | Equals to AFB_SESSION_LOA_EQ_0|AFB_SESSION_RENEW
-**AFB_SESSION_CLOSE** | Closes the session after the reply and set the LOA to 0
-**AFB_SESSION_RENEW** | Refreshes the token of authentification
-**AFB_SESSION_CHECK** | Just requires the token authentification
-**AFB_SESSION_LOA_LE_0** | Requires the current LOA to be lesser then or equal to 0
-**AFB_SESSION_LOA_LE_1** | Requires the current LOA to be lesser then or equal to 1
-**AFB_SESSION_LOA_LE_2** | Requires the current LOA to be lesser then or equal to 2
-**AFB_SESSION_LOA_LE_3** | Requires the current LOA to be lesser then or equal to 3
-**AFB_SESSION_LOA_GE_0** | Requires the current LOA to be greater then or equal to 0
-**AFB_SESSION_LOA_GE_1** | Requires the current LOA to be greater then or equal to 1
-**AFB_SESSION_LOA_GE_2** | Requires the current LOA to be greater then or equal to 2
-**AFB_SESSION_LOA_GE_3** | Requires the current LOA to be greater then or equal to 3
-**AFB_SESSION_LOA_EQ_0** | Requires the current LOA to be equal to 0
-**AFB_SESSION_LOA_EQ_1** | Requires the current LOA to be equal to 1
-**AFB_SESSION_LOA_EQ_2** | Requires the current LOA to be equal to 2
-**AFB_SESSION_LOA_EQ_3** | Requires the current LOA to be equal to 3
+ 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;
+ }
-If any of this flag is set, afb-daemon requires an authentication token
-as if **AFB_SESSION_CHECK** flag was also set.
+ afb_event_sender_push(afb_daemon_get_event_sender(afbitf->daemon), reason, description);
+}
+```
-The special value **AFB_SESSION_NONE** is zero and can be used to bypass token check.
+The list of waiters is walked and a reply is sent to each waiter.
+After sending the reply, the reference count of the request
+is decremented using **afb_req_unref** to allow resources to be freed.
-> Note that **AFB_SESSION_CREATE** and **AFB_SESSION_CLOSE** might be removed in later versions.
+> The reference count **MUST** be decremented using **afb_req_unref** to free
+> resources and avoid memory leaks.
+> This usage count decrement should happen **AFTER** setting reply or
+> bad things may happen.
Sending messages to the log system
----------------------------------
Afb-daemon provides 4 levels of verbosity and 5 methods for logging messages.
-The verbosity is managed. Options allow the change the verbosity of afb-daemon
+The verbosity is managed. Options allow the change the verbosity of ***afb-daemon***
and the verbosity of the bindings can be set binding by binding.
The methods for logging messages are defined as macros that test the
@@ -882,7 +1170,7 @@ NOTICE | 1 | Normal but significant condition | 5
INFO | 2 | Informational | 6
DEBUG | 3 | Debug-level messages | 7
-You can note that the 2 methods **WARNING** and **INFO** have the same level
+You can note that the 2 methods **WARNING** and **NOTICE** have the same level
of verbosity. But they don't have the same *syslog level*. It means that
they are output with a different level on the logging system.
@@ -938,8 +1226,8 @@ Sending events
--------------
Since version 0.5, bindings can broadcast events to any potential listener.
-As today only unattended even are supported. Targeted events are expected for next
-coming version.
+As today only unattended events are supported. Targeted events are expected for
+next coming version.
The binding *tic-tac-toe* broadcasts events when the board changes.
This is done in the function **changed**:
@@ -998,117 +1286,11 @@ receive an event **tictactoe/move**.
> declared, with the same case, followed with a slash /.
> Thus it is safe to compare event using a case sensitive comparison.
-
-
-Writing an asynchronous method implementation
--------------------------------------------
-
-The *tic-tac-toe* example allows two clients or more to share the same board.
-This is implemented by the method **join** that illustrated partly how to
-retrieve arguments.
-
-When two or more clients are sharing a same board, one of them can wait
-until the state of the board changes, but this could also be implemented using
-events because an even is generated each time the board changes.
-
-In this case, the reply to the wait is sent only when the board changes.
-See the diagram below:
-
- CLIENT A CLIENT B TIC-TAC-TOE
- | | |
- +--------------|----------------->| wait . . . . . . . .
- | | | .
- : : : .
- : : : .
- | | | .
- | +----------------->| move . . . .
- | | | V .
- | |<-----------------+ success of move .
- | | | .
- |<-------------|------------------+ success of wait <
-
-Here, this is an invocation of the binding by an other client that
-unblock the suspended *wait* call.
-Nevertheless in most case this should be a timer, a hardware event, a sync with
-a concurrent process or thread, ...
-
-Common case of an asynchronous implementation.
-
-Here is the listing of the function **wait**:
-
-```C
-static void wait(struct afb_req req)
-{
- struct board *board;
- struct waiter *waiter;
-
- /* retrieves the context for the session */
- board = board_of_req(req);
- INFO(afbitf, "method 'wait' called for boardid %d", board->id);
-
- /* creates the waiter and enqueues it */
- waiter = calloc(1, sizeof *waiter);
- waiter->req = req;
- waiter->next = board->waiters;
- afb_req_addref(req);
- board->waiters = waiter;
-}
-```
-
-After retrieving the board, the function adds a new waiter to
-waiters list and returns without setting a reply.
-
-Before returning, it increases **req** request's reference count using **afb_req_addref** function.
-
-> When a method returns without setting a reply,
-> it **MUST** increment request's reference count
-> using **afb_req_addref**. If unpredictable behaviour may pop up.
-
-Later, when a board changes, it calls *tic-tac-toe* **changed** function
-with reason of change in parameter.
-
-Here is the full listing of the function **changed**:
-
-```C
-/*
- * 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);
-}
-```
-
-The list of waiters is walked and a reply is sent to each waiter.
-After sending the reply, the reference count of the request
-is decremented using **afb_req_unref** to allow resources to be freed.
-
-> The reference count **MUST** be decremented using **afb_req_unref** to free
-> resources and avoid memory leaks.
-> This usage count decrement should happen **AFTER** setting reply or
-> bad things may happen.
-
How to build a binding
---------------------
Afb-daemon provides a *pkg-config* configuration file that can be
-queried by providing **afb-daemon** in command line arguments.
+queried by providing ***afb-daemon*** in command line arguments.
This configuration file provides data that should be used
for bindings compilation. Examples:
@@ -1185,7 +1367,7 @@ The only filename convention used by afb-daemon relates to **.so** termination.
*.so pattern is used when afb-daemon automatically discovers binding from a directory hierarchy.
2. It applies a version script at link time to only export the reserved name
-**afbBindingV1Register** for registration entry point. By default, when building
+**afbBindingV1Register** for registration entry point. By default, when building
a shared library linker exports all the public symbols (C functions that are not **static**).
Next line are:
@@ -1221,3 +1403,5 @@ Adding a dependency to afb-daemon is enough. See below:
DEPENDS += " afb-daemon "
+
+[tic-tac-toe_diagram]: pictures/tic-tac-toe.svg (Tic-Tac-Toe sequences diagram)
diff --git a/doc/afb-daemon-vocabulary.html b/doc/afb-daemon-vocabulary.html
deleted file mode 100644
index 5a585c23..00000000
--- a/doc/afb-daemon-vocabulary.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <meta name="generator" content="pandoc">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
- <meta name="author" content="José Bollo">
- <title>Vocabulary for AFB-DAEMON</title>
- <style type="text/css">code{white-space: pre;}</style>
- <link rel="stylesheet" href="doc.css">
- <!--[if lt IE 9]>
- <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
- <![endif]-->
-</head>
-<body>
-<header>
-<h1 class="title">Vocabulary for AFB-DAEMON</h1>
-<h2 class="author">José Bollo</h2>
-<h3 class="date">24 juin 2016</h3>
-</header>
-<nav id="TOC">
-<ul>
-<li><a href="#vocabulary-for-afb-daemon">Vocabulary for AFB-DAEMON</a><ul>
-<li><a href="#binding">Binding</a></li>
-<li><a href="#event">Event</a></li>
-<li><a href="#level-of-assurance-loa">Level of assurance (LOA)</a></li>
-<li><a href="#plugin">Plugin</a></li>
-<li><a href="#request">Request</a></li>
-<li><a href="#replyresponse">Reply/Response</a></li>
-<li><a href="#service">Service</a></li>
-<li><a href="#session">Session</a></li>
-<li><a href="#token">Token</a></li>
-<li><a href="#uuid">UUID</a></li>
-<li><a href="#x-afb-reqid">x-afb-reqid</a></li>
-<li><a href="#x-afb-token">x-afb-token</a></li>
-<li><a href="#x-afb-uuid">x-afb-uuid</a></li>
-</ul></li>
-</ul>
-</nav>
-<h1 id="vocabulary-for-afb-daemon">Vocabulary for AFB-DAEMON</h1>
-<h2 id="binding">Binding</h2>
-<p>A shared library object intended to be add a functionnality to an afb-daemon instance. It implements an API. It may provide a service.</p>
-<p>Binding made for services can have specific entry point called after initialisation and before serving.</p>
-<h2 id="event">Event</h2>
-<p>Message with data propagated from the services to the client and not expecting any reply.</p>
-<p>The current implementation allows to widely broadcast events to all clients.</p>
-<h2 id="level-of-assurance-loa">Level of assurance (LOA)</h2>
-<p>This level that can be from 0 to 3 represent the level of assurance that the services can expect from the session.</p>
-<p>The exact definition of the meaning of this levels and of how to use it remains to be achived.</p>
-<h2 id="plugin">Plugin</h2>
-<p>Old name for binding, see binding.</p>
-<h2 id="request">Request</h2>
-<p>A request is an invocation by a client to a method of a binding using a message transfered through some protocol: HTTP, WebSocket, DBUS... served by afb-daemon</p>
-<h2 id="replyresponse">Reply/Response</h2>
-<p>This is a message sent to client as the result of the request.</p>
-<h2 id="service">Service</h2>
-<p>Service are made of binding runnning by their side on their binder. It can serve many client. Each one being attached to one session.</p>
-<p>The framework establishes the connection between the services and the clients. Using DBus currently but other protocols are considered.</p>
-<h2 id="session">Session</h2>
-<p>A session is meant to be the unic context of an instance of client, identifying that instance across requests.</p>
-<p>Each session has an identifier. Session identifier generated by afb-daemon are UUIDs.</p>
-<p>Internally, afb-daemon offers a mechanism to attach data to sessions. When the session is closed or disappears, the data attached to that session are freed.</p>
-<h2 id="token">Token</h2>
-<p>The token is an identifier that the the client must give to be authentificated.</p>
-<p>At start, afb-daemon get an initial token. This initial token must be presented incoming client to be authentificated.</p>
-<p>A token is valid only for a period.</p>
-<p>The token must be renewed periodically. When the token is renewed, afb-daemon sends the new token to the client.</p>
-<p>Tokens generated by afb-daemon are UUIDs.</p>
-<h2 id="uuid">UUID</h2>
-<p>It stand for Universal Unic IDentifier.</p>
-<p>Its is designed to create identifier in a way that avoid has much as possible conflicts. It means that if two differents instance create a UUID, the probability that they create the same UUID is very low, near to zero.</p>
-<h2 id="x-afb-reqid">x-afb-reqid</h2>
-<p>Argument name that can be used with HTTP request. When this argument is given, it is automatically added to the &quot;request&quot; object of the answer.</p>
-<h2 id="x-afb-token">x-afb-token</h2>
-<p>Argument name for giving the token without ambiguity. You can also use the name <strong>token</strong> but it may conflicts with other arguments.</p>
-<h2 id="x-afb-uuid">x-afb-uuid</h2>
-<p>Argument name for giving explicitely the session identifier without ambiguity. You can also use the name <strong>uuid</strong> but it may conflicts with other arguments.</p>
-</body>
-</html>
diff --git a/doc/afb-daemon-vocabulary.md b/doc/afb-daemon-vocabulary.md
index 897e4db1..c3b7c1ea 100644
--- a/doc/afb-daemon-vocabulary.md
+++ b/doc/afb-daemon-vocabulary.md
@@ -4,8 +4,8 @@ Vocabulary for AFB-DAEMON
## Binding
-A shared library object intended to be add a functionnality to an afb-daemon
-instance. It implements an API. It may provide a service.
+A shared library object intended to add a functionality to an afb-daemon
+instance. It implements an API and may provide a service.
Binding made for services can have specific entry point called after
initialisation and before serving.
@@ -22,8 +22,8 @@ The current implementation allows to widely broadcast events to all clients.
This level that can be from 0 to 3 represent the level of
assurance that the services can expect from the session.
-The exact definition of the meaning of this levels and of
-how to use it remains to be achived.
+The exact definition of the meaning of these levels and how to use it remains to
+be achieved.
## Plugin
@@ -31,8 +31,9 @@ Old name for binding, see binding.
## Request
-A request is an invocation by a client to a method of a binding using a message
-transfered through some protocol: HTTP, WebSocket, DBUS... served by afb-daemon
+A request is an invocation by a client to a binding method using a message
+transferred through some protocol: HTTP, WebSocket, DBUS... and served by
+***afb-daemon***
## Reply/Response
@@ -40,18 +41,19 @@ This is a message sent to client as the result of the request.
## Service
-Service are made of binding runnning by their side on their binder.
-It can serve many client. Each one being attached to one session.
+Service are made of bindings running by their side on their binder.
+It can serve many client. Each one attached to one session.
-The framework establishes the connection between the services and
+The framework establishes connection between the services and
the clients. Using DBus currently but other protocols are considered.
## Session
-A session is meant to be the unic context of an instance of client,
-identifying that instance across requests.
+A session is meant to be the unique instance context of a client,
+which identify that instance across requests.
-Each session has an identifier. Session identifier generated by afb-daemon are UUIDs.
+Each session has an identifier. Session identifier generated by afb-daemon are
+UUIDs.
Internally, afb-daemon offers a mechanism to attach data to sessions.
When the session is closed or disappears, the data attached to that session
@@ -59,10 +61,10 @@ are freed.
## Token
-The token is an identifier that the the client must give to be authentificated.
+The token is an identifier that the client must give to be authenticated.
At start, afb-daemon get an initial token. This initial token must be presented
-incoming client to be authentificated.
+by incoming client to be authenticated.
A token is valid only for a period.
@@ -73,24 +75,24 @@ Tokens generated by afb-daemon are UUIDs.
## UUID
-It stand for Universal Unic IDentifier.
+It stand for Universal Unique IDentifier.
-Its is designed to create identifier in a way that avoid has much as possible conflicts.
-It means that if two differents instance create a UUID, the probability that they create the same UUID is very low, near to zero.
+It is designed to create identifier in a way that avoid has much as possible
+conflicts. It means that if two different instances create an UUID, the
+probability that they create the same UUID is very low, near to zero.
## x-afb-reqid
-Argument name that can be used with HTTP request.
-When this argument is given, it is automatically added to the "request" object of the
-answer.
+Argument name that can be used with HTTP request. When this argument is given,
+it is automatically added to the "request" object of the answer.
## x-afb-token
-Argument name for giving the token without ambiguity.
-You can also use the name **token** but it may conflicts with other arguments.
+Argument name meant to give the token without ambiguity.
+You can also use the name **token** but it may conflicts with others arguments.
## x-afb-uuid
-Argument name for giving explicitely the session identifier without ambiguity.
-You can also use the name **uuid** but it may conflicts with other arguments.
+Argument name for giving explicitly the session identifier without ambiguity.
+You can also use the name **uuid** but it may conflicts with others arguments.
diff --git a/doc/afb-events-guide.html b/doc/afb-events-guide.html
deleted file mode 100644
index c554feab..00000000
--- a/doc/afb-events-guide.html
+++ /dev/null
@@ -1,282 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <meta name="generator" content="pandoc">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
- <meta name="author" content="José Bollo">
- <title>Guide for developing with events</title>
- <style type="text/css">code{white-space: pre;}</style>
- <style type="text/css">
-div.sourceCode { overflow-x: auto; }
-table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
- margin: 0; padding: 0; vertical-align: baseline; border: none; }
-table.sourceCode { width: 100%; line-height: 100%; }
-td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
-td.sourceCode { padding-left: 5px; }
-code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
-code > span.dt { color: #902000; } /* DataType */
-code > span.dv { color: #40a070; } /* DecVal */
-code > span.bn { color: #40a070; } /* BaseN */
-code > span.fl { color: #40a070; } /* Float */
-code > span.ch { color: #4070a0; } /* Char */
-code > span.st { color: #4070a0; } /* String */
-code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
-code > span.ot { color: #007020; } /* Other */
-code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
-code > span.fu { color: #06287e; } /* Function */
-code > span.er { color: #ff0000; font-weight: bold; } /* Error */
-code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
-code > span.cn { color: #880000; } /* Constant */
-code > span.sc { color: #4070a0; } /* SpecialChar */
-code > span.vs { color: #4070a0; } /* VerbatimString */
-code > span.ss { color: #bb6688; } /* SpecialString */
-code > span.im { } /* Import */
-code > span.va { color: #19177c; } /* Variable */
-code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
-code > span.op { color: #666666; } /* Operator */
-code > span.bu { } /* BuiltIn */
-code > span.ex { } /* Extension */
-code > span.pp { color: #bc7a00; } /* Preprocessor */
-code > span.at { color: #7d9029; } /* Attribute */
-code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
-code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
-code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
-code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
- </style>
- <link rel="stylesheet" href="doc.css">
- <!--[if lt IE 9]>
- <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
- <![endif]-->
-</head>
-<body>
-<header>
-<h1 class="title">Guide for developing with events</h1>
-<h2 class="author">José Bollo</h2>
-<h3 class="date">19 septembre 2016</h3>
-</header>
-<nav id="TOC">
-<ul>
-<li><a href="#guide-for-developing-with-events">Guide for developing with events</a><ul>
-<li><a href="#overview-of-events">Overview of events</a><ul>
-<li><a href="#subscribing-and-unsubscribing">Subscribing and unsubscribing</a></li>
-<li><a href="#generating-and-pushing-signals-and-data">Generating and pushing signals and data</a></li>
-<li><a href="#receiving-the-signals">Receiving the signals</a></li>
-<li><a href="#the-exceptional-case-of-wide-broadcast">The exceptional case of wide broadcast</a></li>
-</ul></li>
-<li><a href="#reference-of-functions">Reference of functions</a><ul>
-<li><a href="#function-afb_event-afb_daemon_make_event">Function afb_event afb_daemon_make_event</a></li>
-<li><a href="#function-afb_event_push">Function afb_event_push</a></li>
-<li><a href="#function-afb_event_drop">Function afb_event_drop</a></li>
-<li><a href="#function-afb_req_subscribe">Function afb_req_subscribe</a></li>
-<li><a href="#function-afb_req_unsubscribe">Function afb_req_unsubscribe</a></li>
-<li><a href="#function-afb_event_broadcast">Function afb_event_broadcast</a></li>
-<li><a href="#function-afb_daemon_broadcast_event">Function afb_daemon_broadcast_event</a></li>
-</ul></li>
-<li><a href="#architectural-digressions">Architectural digressions</a><ul>
-<li><a href="#strict-separation">Strict separation</a></li>
-<li><a href="#soft-composition">Soft composition</a></li>
-</ul></li>
-</ul></li>
-</ul>
-</nav>
-<h1 id="guide-for-developing-with-events">Guide for developing with events</h1>
-<p>Signaling agents are services that send events to any clients that subscribed for receiving it. The sent events carry any data.</p>
-<p>To have a good understanding of how to write a signaling agent, the actions of subscribing, unsubscribing, producing, sending, receiving events must be described and explained.</p>
-<h2 id="overview-of-events">Overview of events</h2>
-<p>The basis of a signaling agent is shown on the following figure:</p>
-<figure>
-<img src="signaling-basis.svg" alt="scenario of using events" /><figcaption>scenario of using events</figcaption>
-</figure>
-<p>This figure shows the main role of the signaling framework for the propagation of events.</p>
-<p>For people not familiar with the framework, a signaling agent and a “binding” are similar.</p>
-<h3 id="subscribing-and-unsubscribing">Subscribing and unsubscribing</h3>
-<p>Subscribing and subscription is the action that makes a client able to receive data from a signaling agent. Subscription must create resources for generating the data and for delivering the data to the client. These two aspects are not handled by the same piece of software: generating the data is the responsibility of the developer of the signaling agent while delivering the data is handled by the framework.</p>
-<p>When a client subscribes for data, the agent must:</p>
-<ol type="1">
-<li>check that the subscription request is correct;</li>
-<li>establish the computation chain of the required data, if not already done;</li>
-<li>create a named event for the computed data, if not already done;</li>
-<li>ask the framework to establish the subscription to the event for the request;</li>
-<li>optionally give indications about the event in the reply to the client.</li>
-</ol>
-<p>The first two steps are not involving the framework. They are linked to the business logic of the binding. The request can be any description of the requested data and the computing stream can be of any nature, this is specific to the binding.</p>
-<p>As said before, the framework uses and integrates “libsystemd” and its event loop. Within the framework, &quot;libsystemd&quot; is the standard API/library for bindings expecting to setup and handle I/O, timer or signal events.</p>
-<p>Steps 3 and 4 are bound to the framework.</p>
-<p>The agent must create an object for handling the propagation of produced data to its clients. That object is called “event” in the framework. An event has a name that allows clients to distinguish it from other events.</p>
-<p>Events are created using the <strong><em>afb_daemon_make_event</em></strong> function that takes the name of the event. Example:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> event = afb_daemon_make_event(afb_daemon, name);</code></pre></div>
-<p>Once created, the event can be used either to push data to its subscribers or to broadcast data to any listener.</p>
-<p>The event must be used to establish the subscription for the requesting client. This is done using the <strong><em>afb_req_subscribe</em></strong> function that takes the current request object and event and associates them together. Example:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> rc = afb_req_subscribe(afb_req, event);</code></pre></div>
-<p>When successful, this function make the connection between the event and the client that emitted the request. The client becomes a subscriber of the event until it unsubscribes or disconnects. The <strong><em>afb_req_subscribe</em></strong> function will fail if the client connection is weak: if the request comes from a HTTP link. To receive signals, the client must be connected. The AGL framework allows connections using WebSocket.</p>
-<p>The name of the event is either a well known name or an ad hoc name forged for the usecase.</p>
-<p>Let's see a basic example: client A expects to receive the speed in km/h every second while client B expects the speed in mph twice a second. In that case, there are two different events because it is not the same unit and it is not the same frequency. Having two different events allows to associate clients to the correct event. But this doesn't tell any word about the name of these events. The designer of the signaling agent has two options for naming:</p>
-<ol type="1">
-<li>names can be the same (“speed” for example) with sent data self-describing itself or having a specific tag (requiring from clients awareness about requesting both kinds of speed isn't safe).</li>
-<li>names of the event include the variations (by example: “speed-km/h-1Hz” and “speed-mph-2Hz”) and, in that case, sent data can self-describe itself or not.</li>
-</ol>
-<p>In both cases, the signaling agent might have to send the name of the event and/or an associated tag to its client in the reply of the subscription. This is part of the step 5 above.</p>
-<p>The framework only uses the event (not its name) for subscription, unsubscription and pushing.</p>
-<p>When the requested data is already generated and the event used for pushing it already exists, the signaling agent must not instantiate a new processing chain and must not create a new event object for pushing data. The signaling agent must reuse the existing chain and event.</p>
-<p>Unsubscribing is made by the signaling agent on a request of its client. The <strong><em>afb_req_unsubscribe</em></strong> function tells the framework to remove the requesting client from the event's list of subscribers. Example:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> afb_req_unsubscribe(afb_req, event);</code></pre></div>
-<p>Subscription count does not matter to the framework: subscribing the same client several times has the same effect that subscribing only one time. Thus, when unsubscribing is invoked, it becomes immediately effective.</p>
-<h4 id="more-on-naming-events">More on naming events</h4>
-<p>Within the AGL framework, a signaling agent is a binding that has an API prefix. This prefix is meant to be unique and to identify the binding API. The names of the events that this signaling agent creates are automatically prefixed by the framework, using the API prefix of the binding.</p>
-<p>Thus, if a signaling agent of API prefix <strong><em>api</em></strong> creates an event of name <strong><em>event</em></strong> and pushes data to that event, the subscribers will receive an event of name <strong><em>api/event</em></strong>.</p>
-<h3 id="generating-and-pushing-signals-and-data">Generating and pushing signals and data</h3>
-<p>This of the responsibility of the designer of the signaling agent to establish the processing chain for generating events. In many cases, this can be achieved using I/O or timer or signal events inserted in the main loop. For this case, the AGL framework uses “libsystemd” and provide a way to integrates to the main loop of this library using afb_daemon_get_event_loop. Example:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> sdev = afb_daemon_get_event_loop(af_daemon);
- rc = sd_event_add_io(sdev, &amp;source, fd, EPOLLIN, myfunction, NULL);</code></pre></div>
-<p>In some other cases, the events are coming from D-Bus. In that case, the framework also uses “libsystemd” internally to access D-Bus. It provides two methods to get the available D-Bus objects, already existing and bound to the main libsystemd event loop. Use either <strong><em>afb_daemon_get_system_bus</em></strong> or <strong><em>afb_daemon_get_user_bus</em></strong> to get the required instance. Then use functions of “libsystemd” to handle D-Bus.</p>
-<p>In some rare cases, the generation of the data requires to start a new thread.</p>
-<p>When a data is generated and ready to be pushed, the signaling agent should call the function <strong><em>afb_event_push</em></strong>. Example:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> rc = afb_event_push(event, json);
- <span class="kw">if</span> (rc == <span class="dv">0</span>) {
- stop_generating(event);
- afb_event_drop(event);
- }</code></pre></div>
-<p>The function <strong><em>afb_event_push</em></strong> pushes json data to all the subscribers. It then returns the count of subscribers. When the count is zero, there is no subscriber listening for the event. The example above shows that in that case, the signaling agent stops to generate data for the event and delete the event using afb_event_drop. This is one possible option. Other valuable options are: do nothing and continue to generate and push the event or just stop to generate and push the data but keep the event existing.</p>
-<h3 id="receiving-the-signals">Receiving the signals</h3>
-<p>Understanding what a client expects when it receives signals, events or data shall be the most important topic of the designer of a signaling agent. The good point here is that because JSON<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a> is the exchange format, structured data can be sent in a flexible way.</p>
-<p>The good design is to allow as much as possible the client to describe what is needed with the goal to optimize the processing to the requirements only.</p>
-<h3 id="the-exceptional-case-of-wide-broadcast">The exceptional case of wide broadcast</h3>
-<p>Some data or events have so much importance that they can be widely broadcasted to alert any listening client. Examples of such an alert are:</p>
-<ul>
-<li>system is entering/leaving “power safe” mode</li>
-<li>system is shutting down</li>
-<li>the car starts/stops moving</li>
-<li>...</li>
-</ul>
-<p>An event can be broadcasted using one of the two following methods: <strong><em>afb_daemon_broadcast_event</em></strong> or <strong><em>afb_event_broadcast</em></strong>.</p>
-<p>Example 1:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> afb_daemon_broadcast_event(afb_daemon, name, json);</code></pre></div>
-<p>Example 2:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> event = afb_daemon_make_event(afb_daemon, name);
- . . . .
- afb_event_broadcast(event, json);</code></pre></div>
-<p>As for other events, the name of events broadcasted using <strong><em>afb_daemon_broadcast_event</em></strong> are automatically prefixed by the framework with API prefix of the binding (signaling agent).</p>
-<h2 id="reference-of-functions">Reference of functions</h2>
-<h3 id="function-afb_event-afb_daemon_make_event">Function afb_event afb_daemon_make_event</h3>
-<p>The function <strong><em>afb_daemon_make_event</em></strong> that is defined as below:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Creates an event of &#39;name&#39; and returns it.</span>
-<span class="co"> * &#39;daemon&#39; MUST be the daemon given in interface when activating the binding.</span>
-<span class="co"> */</span>
-<span class="kw">struct</span> afb_event afb_daemon_make_event(<span class="kw">struct</span> afb_daemon daemon, <span class="dt">const</span> <span class="dt">char</span> *name);</code></pre></div>
-<p>The daemon is the handler to the application framework binder daemon received during initialisation steps of the binding.</p>
-<p>Calling the function <strong><em>afb_daemon_make_event</em></strong> within the initialisation function <strong><em>afbBindingV1Register</em></strong> will <em>fail</em> because the plugin name is not known at this time.</p>
-<p>The correct way to create the event at initialisation is to call the function <strong><em>afb_daemon_make_event</em></strong> within the initialisation function <strong><em>afbBindingV1ServiceInit</em></strong>.</p>
-<h3 id="function-afb_event_push">Function afb_event_push</h3>
-<p>The function <strong><em>afb_event_push</em></strong> is defined as below:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Pushes the &#39;event&#39; with the data &#39;object&#39; to its observers.</span>
-<span class="co"> * &#39;object&#39; can be NULL.</span>
-<span class="co"> *</span>
-<span class="co"> * For convenience, the function calls &#39;json_object_put&#39; for object&#39;.</span>
-<span class="co"> * Thus, in the case where &#39;object&#39; should remain available after</span>
-<span class="co"> * the function returns, the function &#39;json_object_get&#39; shall be used.</span>
-<span class="co"> *</span>
-<span class="co"> * Returns the count of clients that received the event.</span>
-<span class="co"> */</span>
-<span class="dt">int</span> afb_event_push(<span class="kw">struct</span> afb_event event, <span class="kw">struct</span> json_object *object);</code></pre></div>
-<p>As the function <strong><em>afb_event_push</em></strong> returns 0 when there is no more subscriber, a binding can remove such unexpected event using the function <strong><em>afb_event_drop</em></strong>.</p>
-<h3 id="function-afb_event_drop">Function afb_event_drop</h3>
-<p>The function <strong><em>afb_event_drop</em></strong> is defined as below:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Drops the data associated to the event</span>
-<span class="co"> * After calling this function, the event</span>
-<span class="co"> * MUST NOT BE USED ANYMORE.</span>
-<span class="co"> */</span>
-<span class="dt">void</span> afb_event_drop(<span class="kw">struct</span> afb_event event);</code></pre></div>
-<h3 id="function-afb_req_subscribe">Function afb_req_subscribe</h3>
-<p>The function <strong><em>afb_req_subscribe</em></strong> is defined as below:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Establishes for the client link identified by &#39;req&#39; a subscription</span>
-<span class="co"> * to the &#39;event&#39;.</span>
-<span class="co"> * Returns 0 in case of successful subscription or -1 in case of error.</span>
-<span class="co"> */</span>
-<span class="dt">int</span> afb_req_subscribe(<span class="kw">struct</span> afb_req req, <span class="kw">struct</span> afb_event event);</code></pre></div>
-<p>The subscription adds the client of the request to the list of subscribers to the event.</p>
-<h3 id="function-afb_req_unsubscribe">Function afb_req_unsubscribe</h3>
-<p>The function <strong><em>afb_req_unsubscribe</em></strong> is defined as below:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Revokes the subscription established to the &#39;event&#39; for the client</span>
-<span class="co"> * link identified by &#39;req&#39;.</span>
-<span class="co"> * Returns 0 in case of successful unsubscription or -1 in case of error.</span>
-<span class="co"> */</span>
-<span class="dt">int</span> afb_req_unsubscribe(<span class="kw">struct</span> afb_req req, <span class="kw">struct</span> afb_event event);</code></pre></div>
-<p>The unsubscription removes the client of the request of the list of subscribers to the event. When the list of subscribers to the event becomes empty, the function <strong><em>afb_event_push</em></strong> will return zero.</p>
-<h3 id="function-afb_event_broadcast">Function afb_event_broadcast</h3>
-<p>The function <strong><em>afb_event_broadcast</em></strong> is defined as below:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Broadcasts widely the &#39;event&#39; with the data &#39;object&#39;.</span>
-<span class="co"> * &#39;object&#39; can be NULL.</span>
-<span class="co"> *</span>
-<span class="co"> * For convenience, the function calls &#39;json_object_put&#39; for &#39;object&#39;.</span>
-<span class="co"> * Thus, in the case where &#39;object&#39; should remain available after</span>
-<span class="co"> * the function returns, the function &#39;json_object_get&#39; shall be used.</span>
-<span class="co"> *</span>
-<span class="co"> * Returns the count of clients that received the event.</span>
-<span class="co"> */</span>
-<span class="dt">int</span> afb_event_broadcast(<span class="kw">struct</span> afb_event event, <span class="kw">struct</span> json_object *object);</code></pre></div>
-<p>This uses an existing event (created with <strong><em>afb_daemon_make_event</em></strong>) for broadcasting an event having its name.</p>
-<h3 id="function-afb_daemon_broadcast_event">Function afb_daemon_broadcast_event</h3>
-<p>The function <strong><em>afb_daemon_broadcast_event</em></strong> is defined as below:</p>
-<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
-<span class="co"> * Broadcasts widely the event of &#39;name&#39; with the data &#39;object&#39;.</span>
-<span class="co"> * &#39;object&#39; can be NULL.</span>
-<span class="co"> * &#39;daemon&#39; MUST be the daemon given in interface when activating the binding.</span>
-<span class="co"> *</span>
-<span class="co"> * For convenience, the function calls &#39;json_object_put&#39; for &#39;object&#39;.</span>
-<span class="co"> * Thus, in the case where &#39;object&#39; should remain available after</span>
-<span class="co"> * the function returns, the function &#39;json_object_get&#39; shall be used.</span>
-<span class="co"> *</span>
-<span class="co"> * Returns the count of clients that received the event.</span>
-<span class="co"> */</span>
-<span class="dt">int</span> afb_daemon_broadcast_event(<span class="kw">struct</span> afb_daemon daemon, <span class="dt">const</span> <span class="dt">char</span> *name, <span class="kw">struct</span> json_object *object);</code></pre></div>
-<p>The name is given here explicitely. The name is automatically prefixed with the name of the binding. For example, a binding of prefix &quot;xxx&quot; would broadcat the event &quot;xxx/name&quot;.</p>
-<h2 id="architectural-digressions">Architectural digressions</h2>
-<p>Based on their dependencies to hardware, signaling agents can be split into 2 categories: low-level signaling agents and high-level signaling agents.</p>
-<p>Low-level signaling agents are bound to the hardware and focused on interfacing and driving.</p>
-<p>High-level signaling agent are independent of the hardware and ocused on providing service.</p>
-<p>This separation (that may in the corner look artificial) aim to help in the systems design. The main idea here is that high-level signaling agents are providing “business logic”, also known as “application logic”, that is proper to the car industry and that can be reused and that can evolve as a foundation for the future of the industry.</p>
-<p>The implementation of this decomposition may follow 2 paths: strict separation or soft composition.</p>
-<h3 id="strict-separation">Strict separation</h3>
-<p>The strict separation implements the modularity composition of signaling agent through the framework. The high-level signaling agent subscribes to the low level signaling agent using the standard client API.</p>
-<p>Advantages:</p>
-<ul>
-<li>Modularity</li>
-<li>Separation of responsibilities</li>
-<li>Possible aggregation of multiple sources</li>
-<li>Soft binding of agent good for maintenance</li>
-</ul>
-<p>Drawbacks:</p>
-<ul>
-<li>Cost of propagation of data (might serialize)</li>
-<li>Difficulties to abstract low-level signaling agent or to find a trade-of between abstracting and specializing</li>
-</ul>
-<p>The key is modularity versus cost of propagation. It can be partly solved when logical group of signaling agent are launched together in the same binder process. In that particular case, the cost of propagation of data between agents is reduced<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a> because there is no serialization.</p>
-<p>This reduction of the propagation cost (and of the resources used) precludes implementation of strong security between the agents because they share the same memory.</p>
-<h3 id="soft-composition">Soft composition</h3>
-<p>The soft composition implements the business logic of high-level signaling agents as libraries that can then be used directly by the low level signaling agents.</p>
-<p>Advantages:</p>
-<ul>
-<li>No propagation: same memory, sharing of native structures</li>
-</ul>
-<p>Drawbacks:</p>
-<ul>
-<li>Cannot be used for aggregation of several sources</li>
-<li>Difficulties to abstract low-level signaling agent or to find a trade-of between abstracting and specializing</li>
-<li>Source code binding not good for maintenance</li>
-</ul>
-<section class="footnotes">
-<hr />
-<ol>
-<li id="fn1"><p>There are two aspect in using JSON: the first is the flexible data structure that mixes common types (booleans, numbers, strings, arrays, dictionaries, nulls), the second, is the streaming specification. Streaming is often seen as the bottleneck of using JSON (see http://bjson.org). When the agent share the same process, there is no streaming at all.<a href="#fnref1">↩</a></p></li>
-<li id="fn2"><p>Within the same process, there is not serialization, the propagation has the cost of wrapping a json data and calling callbacks with the benefit of having a powerful callback manager: the event mechanism of the framework.<a href="#fnref2">↩</a></p></li>
-</ol>
-</section>
-</body>
-</html>
diff --git a/doc/afb-events-guide.md b/doc/afb-events-guide.md
index f24bef3f..aaa09be1 100644
--- a/doc/afb-events-guide.md
+++ b/doc/afb-events-guide.md
@@ -5,30 +5,30 @@ Signaling agents are services that send events to any clients that
subscribed for receiving it. The sent events carry any data.
To have a good understanding of how to write a signaling agent, the
-actions of subscribing, unsubscribing, producing, sending, receiving
+actions of subscribing, unsubscribing, producing, sending and receiving
events must be described and explained.
Overview of events
------------------
-The basis of a signaling agent is shown on the following figure:
+The basis of a signaling agent is shown in the following figure:
-![scenario of using events](signaling-basis.svg)
+![scenario of using events](pictures/signaling-basis.svg)
-This figure shows the main role of the signaling framework for the
-propagation of events.
+This figure shows the main role of the signaling framework for the events
+propagation.
For people not familiar with the framework, a signaling agent and
a “binding” are similar.
### Subscribing and unsubscribing
-Subscribing and subscription is the action that makes a client able to
-receive data from a signaling agent. Subscription must create resources
-for generating the data and for delivering the data to the client. These
-two aspects are not handled by the same piece of software: generating
-the data is the responsibility of the developer of the signaling agent
-while delivering the data is handled by the framework.
+Subscribing is the action that makes a client able to receive data from a
+signaling agent. Subscription must create resources for generating the data, and
+for delivering the data to the client. These two aspects are not handled by the
+same piece of software. Generating the data is the responsibility of the
+developer of the signaling agent while delivering the data is handled by the
+framework.
When a client subscribes for data, the agent must:
@@ -46,8 +46,8 @@ the business logic of the binding. The request can be any description of
the requested data and the computing stream can be of any nature, this
is specific to the binding.
-As said before, the framework uses and integrates “libsystemd” and its event
-loop. Within the framework, "libsystemd" is the standard API/library for
+As said before, the framework uses and integrates **libsystemd** and its event
+loop. Within the framework, **libsystemd** is the standard API/library for
bindings expecting to setup and handle I/O, timer or signal events.
Steps 3 and 4 are bound to the framework.
@@ -81,11 +81,11 @@ the client that emitted the request. The client becomes a subscriber of
the event until it unsubscribes or disconnects. The
***afb\_req\_subscribe*** function will fail if the client
connection is weak: if the request comes from a HTTP link. To receive
-signals, the client must be connected. The AGL framework allows
-connections using WebSocket.
+signals, the client must be connected. The AGL framework allows connections
+using WebSocket.
The name of the event is either a well known name or an ad hoc name
-forged for the usecase.
+forged for the use case.
Let's see a basic example: client A expects to receive the speed in km/h
every second while client B expects the speed in mph twice a second. In
@@ -96,11 +96,11 @@ any word about the name of these events. The designer of the signaling
agent has two options for naming:
1. names can be the same (“speed” for example) with sent data
- self-describing itself or having a specific tag (requiring from
+ self describing itself or having a specific tag (requiring from
clients awareness about requesting both kinds of speed isn't safe).
2. names of the event include the variations (by example:
“speed-km/h-1Hz” and “speed-mph-2Hz”) and, in that case, sent data
- can self-describe itself or not.
+ can self describe itself or not.
In both cases, the signaling agent might have to send the name of the
event and/or an associated tag to its client in the reply of the
@@ -145,7 +145,7 @@ will receive an event of name ***api/event***.
This of the responsibility of the designer of the signaling agent to
establish the processing chain for generating events. In many cases,
this can be achieved using I/O or timer or signal events inserted in the
-main loop. For this case, the AGL framework uses “libsystemd” and
+main loop. For this case, the AGL framework uses **libsystemd** and
provide a way to integrates to the main loop of this library using
afb\_daemon\_get\_event\_loop. Example:
@@ -155,12 +155,12 @@ afb\_daemon\_get\_event\_loop. Example:
```
In some other cases, the events are coming from D-Bus. In that case, the
-framework also uses “libsystemd” internally to access D-Bus. It provides
+framework also uses **libsystemd** internally to access D-Bus. It provides
two methods to get the available D-Bus objects, already existing and
-bound to the main libsystemd event loop. Use either
+bound to the main**libsystemd**event loop. Use either
***afb\_daemon\_get\_system\_bus*** or
***afb\_daemon\_get\_user\_bus*** to get the required instance. Then
-use functions of “libsystemd” to handle D-Bus.
+use functions of **libsystemd** to handle D-Bus.
In some rare cases, the generation of the data requires to start a new
thread.
@@ -169,7 +169,7 @@ When a data is generated and ready to be pushed, the signaling agent
should call the function ***afb\_event\_push***. Example:
```C
- rc = afb_event_push(event, json);
+ rc = afb_event_push(event, JSON);
if (rc == 0) {
stop_generating(event);
afb_event_drop(event);
@@ -248,7 +248,7 @@ The daemon is the handler to the application framework binder daemon
received during initialisation steps of the binding.
Calling the function ***afb\_daemon\_make\_event*** within the initialisation
-function ***afbBindingV1Register*** will _fail_ because the plugin
+function ***afbBindingV1Register*** will _fail_ because the binding
name is not known at this time.
The correct way to create the event at initialisation is to call the function
@@ -366,10 +366,33 @@ The function ***afb\_daemon\_broadcast\_event*** is defined as below:
int afb_daemon_broadcast_event(struct afb_daemon daemon, const char *name, struct json_object *object);
```
-The name is given here explicitely. The name is automatically prefixed
+The name is given here explicitly. The name is automatically prefixed
with the name of the binding. For example, a binding of prefix "xxx"
would broadcat the event "xxx/name".
+### Function afbBindingV1ServiceEvent
+
+Binding can implement function **afbBindingV1ServiceEvent** which will
+be called when an event is broadcasted or if service subscribed to an event.
+That allow a service to react to an event and do what it is to do if this is
+relevant for it (ie: car back camera detects imminent collision and broadcast
+it, then appropriate service enable parking brake.). Here is the
+**afbBindingV1ServiceEvent** definition:
+
+```C
+/*
+ * When a binding have an implementation of the function 'afbBindingV1ServiceEvent',
+ * defined below, the framework calls that function for any broadcasted event or for
+ * events that the service subscribed to in its name.
+ *
+ * It receive the 'event' name and its related data in 'object' (be aware that 'object'
+ * might be NULL).
+ */
+extern void afbBindingV1ServiceEvent(const char *event, struct json_object *object);
+
+The binding *tic-tac-toe* broadcasts events when the board changes.
+This is done in the function **changed**:
+```
Architectural digressions
-------------------------
@@ -381,7 +404,7 @@ agents.
Low-level signaling agents are bound to the hardware and focused on
interfacing and driving.
-High-level signaling agent are independent of the hardware and ocused on
+High-level signaling agent are independent of the hardware and focused on
providing service.
This separation (that may in the corner look artificial) aim to help in
@@ -410,7 +433,7 @@ Drawbacks:
- Cost of propagation of data (might serialize)
- Difficulties to abstract low-level signaling agent or to find a
- trade-of between abstracting and specializing
+ trade-off between abstracting and specializing
The key is modularity versus cost of propagation. It can be partly
solved when logical group of signaling agent are launched together in
@@ -436,7 +459,7 @@ Drawbacks:
- Cannot be used for aggregation of several sources
- Difficulties to abstract low-level signaling agent or to find a
- trade-of between abstracting and specializing
+ trade-off between abstracting and specializing
- Source code binding not good for maintenance
[^1]: There are two aspect in using JSON: the first is the flexible data
diff --git a/doc/afb-overview.html b/doc/afb-overview.html
deleted file mode 100644
index 707443cc..00000000
--- a/doc/afb-overview.html
+++ /dev/null
@@ -1,316 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <meta name="generator" content="pandoc">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
- <meta name="author" content="José Bollo">
- <title>Overview of AFB-DAEMON</title>
- <style type="text/css">code{white-space: pre;}</style>
- <link rel="stylesheet" href="doc.css">
- <!--[if lt IE 9]>
- <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
- <![endif]-->
-</head>
-<body>
-<header>
-<h1 class="title">Overview of AFB-DAEMON</h1>
-<h2 class="author">José Bollo</h2>
-<h3 class="date">24 juin 2016</h3>
-</header>
-<nav id="TOC">
-<ul>
-<li><a href="#overview-of-afb-daemon">Overview of AFB-DAEMON</a><ul>
-<li><a href="#roles-of-afb-daemon">Roles of afb-daemon</a></li>
-<li><a href="#use-cases-of-the-binder-afb-daemon">Use cases of the binder afb-daemon</a><ul>
-<li><a href="#remotely-running-application">Remotely running application</a></li>
-<li><a href="#adding-native-features-to-html5qml-applications">Adding native features to HTML5/QML applications</a></li>
-<li><a href="#offering-services-to-the-system">Offering services to the system</a></li>
-</ul></li>
-<li><a href="#the-bindings-of-the-binder-afb-daemon">The bindings of the binder afb-daemon</a></li>
-<li><a href="#launching-the-binder-afb-daemon">Launching the binder afb-daemon</a></li>
-<li><a href="#future-development-of-afb-daemon">Future development of afb-daemon</a></li>
-</ul></li>
-</ul>
-</nav>
-<h1 id="overview-of-afb-daemon">Overview of AFB-DAEMON</h1>
-<h2 id="roles-of-afb-daemon">Roles of afb-daemon</h2>
-<p>The name <strong>afb-daemon</strong> stands for <em>Application Framework Binder Daemon</em>. That is why afb-daemon is also named <strong><em>the binder</em></strong>.</p>
-<p><strong>Afb-daemon</strong> is in charge to bind one instance of an application to the AGL framework and AGL system.</p>
-<p>On the following figure, you can use a typical use of afb-daemon:</p>
-<a id="binder-fig-basis">
-<h4>
-Figure: binder afb-daemon, basis
-</h4>
-<p></a></p>
-<pre><code>. . . . . . . . . . . . . . . . . . . . . . . . . .
-. Isolated security context .
-. .
-. +------------------------------+ .
-. | | .
-. | A P P L I C A T I O N | .
-. | | .
-. +--------------+---------------+ .
-. | .
-. | .
-. +-------------------+----------------------+ .
-. | : | .
-. | b i n d e r : | .
-. | A F B - D A E M O N : BINDINGS | .
-. | : | .
-. +-------------------+----------------------+ .
-. | .
-. . . . . . . . . . . . | . . . . . . . . . . . . .
- |
- v
- AGL SYSTEM</code></pre>
-<p>The application and its companion binder run in secured and isolated environment set for them. Applications are intended to access to AGL system through the binder.</p>
-<p>The binder afb-daemon serves multiple purposes:</p>
-<ol type="1">
-<li><p>It acts as a gateway for the application to access the system;</p></li>
-<li><p>It acts as an HTTP server for serving files to HTML5 applications;</p></li>
-<li><p>It allows HTML5 applications to have native extensions subject to security enforcement for accessing hardware ressources or for speeding parts of algorithm.</p></li>
-</ol>
-<h2 id="use-cases-of-the-binder-afb-daemon">Use cases of the binder afb-daemon</h2>
-<p>This section tries to give a better understanding of the binder usage through several use cases.</p>
-<h3 id="remotely-running-application">Remotely running application</h3>
-<p>One of the most interresting aspect of using the binder afb-daemon is the ability to run applications remotely. This feature is possible because the binder afb-daemon implements native web protocols.</p>
-<p>So the <a href="#binder-fig-1">figure binder, basis</a> would become when the application is run remotely:</p>
-<a id="binder-fig-remote">
-<h4>
-Figure: binder afb-daemon and remotely running application
-</h4>
-<p></a></p>
-<pre><code> +------------------------------+
- | |
- | A P P L I C A T I O N |
- | |
- +--------------+---------------+
- |
- ~ ~ ~ ~ ~ ~
- : NETWORK :
- ~ ~ ~ ~ ~ ~
- |
-. . . . . . . . . . . . . . | . . . . . . . . . . . . . .
-. Isolated security | .
-. context | .
-. | .
-. . . . . . . . . . . . . . . . . . . . . . . . . .
-. . . .
-. . F I R E W A L L . .
-. . . .
-. . . . . . . . . . . . . . . . . . . . . . . . . .
-. | .
-. +-------------------+----------------------+ .
-. | : | .
-. | A F B - D A E M O N : BINDINGS | .
-. | : | .
-. +-------------------+----------------------+ .
-. | .
-. . . . . . . . . . . . . . | . . . . . . . . . . . . . .
- |
- v
- AGL SYSTEM</code></pre>
-<h3 id="adding-native-features-to-html5qml-applications">Adding native features to HTML5/QML applications</h3>
-<p>Applications can provide with their packaged delivery a binding. That binding will be instanciated for each application instance. The methods of the binding will be accessible by applications and will be excuted within the security context.</p>
-<h3 id="offering-services-to-the-system">Offering services to the system</h3>
-<p>It is possible to run the binder afb-daemon as a daemon that provides the API of its bindings.</p>
-<p>This will be used for:</p>
-<ol type="1">
-<li><p>offering common APIs</p></li>
-<li><p>provide application's services (services provided as application)</p></li>
-</ol>
-<p>In that case, the figure showing the whole aspects is</p>
-<a id="binder-fig-remote">
-<h4>
-Figure: binder afb-daemon for services
-</h4>
-<p></a></p>
-<pre><code>. . . . . . . . . . . . . . . . . . . . . .
-. Isolated security context application .
-. .
-. +------------------------------+ .
-. | | .
-. | A P P L I C A T I O N | .
-. | | .
-. +--------------+---------------+ . . . . . . . . . . . . . . . . . . . . . . .
-. | . . Isolated security context A .
-. | . . .
-. +-----------------+------------------+ . . +------------------------------------+ .
-. | : | . . | : | .
-. | b i n d e r : | . . | b i n d e r : service | .
-. | A F B - D A E M O N : BINDINGS | . . | A F B - D A E M O N : BINDINGS | .
-. | : | . . | : A | .
-. +-----------------+------------------+ . . +-----------------+------------------+ .
-. | . . | .
-. . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . .
- | |
- v v
- ================================================================================
- D - B U S &amp; C Y N A R A
- ================================================================================
- ^ ^
- | |
-. . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . .
-. | . . | .
-. +-----------------+------------------+ . . +-----------------+------------------+ .
-. | : | . . | : | .
-. | b i n d e r : service | . . | b i n d e r : service | .
-. | A F B - D A E M O N : BINDINGS | . . | A F B - D A E M O N : BINDINGS | .
-. | : B | . . | : C | .
-. +------------------------------------+ . . +------------------------------------+ .
-. . . .
-. Isolated security context B . . Isolated security context C .
-. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .</code></pre>
-<p>For this case, the binder afb-daemon takes care to attribute one single session context to each client instance. It allows bindings to store and retrieve data associated to each of its client.</p>
-<h2 id="the-bindings-of-the-binder-afb-daemon">The bindings of the binder afb-daemon</h2>
-<p>The binder can instanciate bindings. The primary use of bindings is to add native methods that can be accessed by applications written with any language through web technologies ala JSON RPC.</p>
-<p>This simple idea is declined to serves multiple purposes:</p>
-<ol type="1">
-<li><p>add native feature to applications</p></li>
-<li><p>add common API available by any applications</p></li>
-<li><p>provide customers services</p></li>
-</ol>
-<p>A specific document explains how to write an afb-daemon binder binding: <a href="afb-binding-writing.html">HOWTO WRITE a BINDING for AFB-DAEMON</a></p>
-<h2 id="launching-the-binder-afb-daemon">Launching the binder afb-daemon</h2>
-<p>The launch options for binder <strong>afb-daemon</strong> are:</p>
-<pre><code> --help
-
- Prints help with available options
-
- --version
-
- Display version and copyright
-
- --verbose
-
- Increases the verbosity, can be repeated
-
- --port=xxxx
-
- HTTP listening TCP port [default 1234]
-
- --rootdir=xxxx
-
- HTTP Root Directory [default $AFBDIR or else $HOME/.AFB]
-
- --rootbase=xxxx
-
- Angular Base Root URL [default /opa]
-
- This is used for any application of kind OPA (one page application).
- When set, any missing document whose url has the form /opa/zzz
- is translated to /opa/#!zzz
-
- --rootapi=xxxx
-
- HTML Root API URL [default /api]
-
- The bindings are available within that url.
-
- --alias=xxxx
-
- Maps a path located anywhere in the file system to the
- a subdirectory. The syntax for mapping a PATH to the
- subdirectory NAME is: --alias=/NAME:PATH.
-
- Example: --alias=/icons:/usr/share/icons maps the
- content of /usr/share/icons within the subpath /icons.
-
- This option can be repeated.
-
- --apitimeout=xxxx
-
- binding API timeout in seconds [default 20]
-
- Defines how many seconds maximum a method is allowed to run.
- 0 means no limit.
-
- --cntxtimeout=xxxx
-
- Client Session Timeout in seconds [default 3600]
-
- --cache-eol=xxxx
-
- Client cache end of live [default 100000 that is 27,7 hours]
-
- --sessiondir=xxxx
-
- Sessions file path [default rootdir/sessions]
-
- --session-max=xxxx
-
- Maximum count of simultaneous sessions [default 10]
-
- --ldpaths=xxxx
-
- Load bindings from given paths separated by colons
- as for dir1:dir2:binding1.so:... [default = $libdir/afb]
-
- You can mix path to directories and to bindings.
- The sub-directories of the given directories are searched
- recursively.
-
- The bindings are the files terminated by &#39;.so&#39; (the extension
- so denotes shared object) that contain the public entry symbol.
-
- --binding=xxxx
-
- Load the binding of given path.
-
- --token=xxxx
-
- Initial Secret token to authenticate.
-
- If not set, no client can authenticate.
-
- If set to the empty string, then any initial token is accepted.
-
- --mode=xxxx
-
- Set the mode: either local, remote or global.
-
- The mode indicate if the application is run locally on the host
- or remotely through network.
-
- --readyfd=xxxx
-
- Set the #fd to signal when ready
-
- If set, the binder afb-daemon will write &quot;READY=1\n&quot; on the file
- descriptor whose number if given (/proc/self/fd/xxx).
-
- --dbus-client=xxxx
-
- Transparent binding to a binder afb-daemon service through dbus.
-
- It creates an API of name xxxx that is implemented remotely
- and queried via DBUS.
-
- --dbus-server=xxxx
-
- Provides a binder afb-daemon service through dbus.
-
- The name xxxx must be the name of an API defined by a binding.
- This API is exported through DBUS.
-
- --foreground
-
- Get all in foreground mode (default)
-
- --daemon
-
- Get all in background mode</code></pre>
-<h2 id="future-development-of-afb-daemon">Future development of afb-daemon</h2>
-<ul>
-<li><p>The binder afb-daemon would launch the applications directly.</p></li>
-<li><p>The current setting of mode (local/remote/global) might be reworked to a mechanism for querying configuration variables.</p></li>
-<li><p>Implements &quot;one-shot&quot; initial token. It means that after its first authenticated use, the initial token is removed and no client can connect anymore.</p></li>
-<li><p>Creates some intrinsic APIs.</p></li>
-<li><p>Make the service connection using WebSocket not DBUS.</p></li>
-<li><p>Management of targetted events.</p></li>
-<li><p>Securisation of LOA.</p></li>
-<li><p>Integration of the protocol JSON-RPC for the websockets.</p></li>
-</ul>
-</body>
-</html>
diff --git a/doc/afb-overview.md b/doc/afb-overview.md
index 343a4f30..75703442 100644
--- a/doc/afb-overview.md
+++ b/doc/afb-overview.md
@@ -17,27 +17,7 @@ of afb-daemon:
<a id="binder-fig-basis"><h4>Figure: binder afb-daemon, basis</h4></a>
- . . . . . . . . . . . . . . . . . . . . . . . . . .
- . Isolated security context .
- . .
- . +------------------------------+ .
- . | | .
- . | A P P L I C A T I O N | .
- . | | .
- . +--------------+---------------+ .
- . | .
- . | .
- . +-------------------+----------------------+ .
- . | : | .
- . | b i n d e r : | .
- . | A F B - D A E M O N : BINDINGS | .
- . | : | .
- . +-------------------+----------------------+ .
- . | .
- . . . . . . . . . . . . | . . . . . . . . . . . . .
- |
- v
- AGL SYSTEM
+![binder-basis][binder-basis]
The application and its companion binder run in secured and isolated
environment set for them. Applications are intended to access to AGL
@@ -61,53 +41,23 @@ usage through several use cases.
### Remotely running application
-One of the most interresting aspect of using the binder afb-daemon
+One of the most interesting aspect of using the binder afb-daemon
is the ability to run applications remotely. This feature is
possible because the binder afb-daemon implements native web
protocols.
-So the [figure binder, basis](#binder-fig-1) would become
+So the [figure binder, basis](#binder-fig-basis) would become
when the application is run remotely:
<a id="binder-fig-remote"><h4>Figure: binder afb-daemon and remotely running application</h4></a>
- +------------------------------+
- | |
- | A P P L I C A T I O N |
- | |
- +--------------+---------------+
- |
- ~ ~ ~ ~ ~ ~
- : NETWORK :
- ~ ~ ~ ~ ~ ~
- |
- . . . . . . . . . . . . . . | . . . . . . . . . . . . . .
- . Isolated security | .
- . context | .
- . | .
- . . . . . . . . . . . . . . . . . . . . . . . . . .
- . . . .
- . . F I R E W A L L . .
- . . . .
- . . . . . . . . . . . . . . . . . . . . . . . . . .
- . | .
- . +-------------------+----------------------+ .
- . | : | .
- . | A F B - D A E M O N : BINDINGS | .
- . | : | .
- . +-------------------+----------------------+ .
- . | .
- . . . . . . . . . . . . . . | . . . . . . . . . . . . . .
- |
- v
- AGL SYSTEM
### Adding native features to HTML5/QML applications
Applications can provide with their packaged delivery a binding.
-That binding will be instanciated for each application instance.
+That binding will be instantiated for each application instance.
The methods of the binding will be accessible by applications and
-will be excuted within the security context.
+will be executed within the security context.
### Offering services to the system
@@ -124,43 +74,7 @@ In that case, the figure showing the whole aspects is
<a id="binder-fig-remote"><h4>Figure: binder afb-daemon for services</h4></a>
- . . . . . . . . . . . . . . . . . . . . . .
- . Isolated security context application .
- . .
- . +------------------------------+ .
- . | | .
- . | A P P L I C A T I O N | .
- . | | .
- . +--------------+---------------+ . . . . . . . . . . . . . . . . . . . . . . .
- . | . . Isolated security context A .
- . | . . .
- . +-----------------+------------------+ . . +------------------------------------+ .
- . | : | . . | : | .
- . | b i n d e r : | . . | b i n d e r : service | .
- . | A F B - D A E M O N : BINDINGS | . . | A F B - D A E M O N : BINDINGS | .
- . | : | . . | : A | .
- . +-----------------+------------------+ . . +-----------------+------------------+ .
- . | . . | .
- . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . .
- | |
- v v
- ================================================================================
- D - B U S & C Y N A R A
- ================================================================================
- ^ ^
- | |
- . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . .
- . | . . | .
- . +-----------------+------------------+ . . +-----------------+------------------+ .
- . | : | . . | : | .
- . | b i n d e r : service | . . | b i n d e r : service | .
- . | A F B - D A E M O N : BINDINGS | . . | A F B - D A E M O N : BINDINGS | .
- . | : B | . . | : C | .
- . +------------------------------------+ . . +------------------------------------+ .
- . . . .
- . Isolated security context B . . Isolated security context C .
- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
-
+![afb-for-services][afb-for-services]
For this case, the binder afb-daemon takes care to attribute one single session
context to each client instance. It allows bindings to store and retrieve data
@@ -169,7 +83,7 @@ associated to each of its client.
The bindings of the binder afb-daemon
------------------------------------
-The binder can instanciate bindings. The primary use of bindings
+The binder can instantiate bindings. The primary use of bindings
is to add native methods that can be accessed by applications
written with any language through web technologies ala JSON RPC.
@@ -335,10 +249,11 @@ anymore.
- Make the service connection using WebSocket not DBUS.
-- Management of targetted events.
+- Management of targeted events.
-- Securisation of LOA.
+- Securing LOA.
- Integration of the protocol JSON-RPC for the websockets.
-
+[binder-basis]: pictures/AFB_overview.svg (Binder AFB daemon basis)
+[afb-for-services]: pictures/AFB_for_services.svg (Binder AFB daemon for services)
diff --git a/doc/afb-tests-overview.html b/doc/afb-tests-overview.html
deleted file mode 100644
index 27231a08..00000000
--- a/doc/afb-tests-overview.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8">
- <meta name="generator" content="pandoc">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
- <meta name="author" content="Manuel Bachmann">
- <meta name="author" content="José Bollo">
- <title>Overview of tests shipped with AFB-Daemon</title>
- <style type="text/css">code{white-space: pre;}</style>
- <link rel="stylesheet" href="doc.css">
- <!--[if lt IE 9]>
- <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
- <![endif]-->
-</head>
-<body>
-<header>
-<h1 class="title">Overview of tests shipped with AFB-Daemon</h1>
-<h2 class="author">Manuel Bachmann</h2>
-<h2 class="author">José Bollo</h2>
-<h3 class="date">24 juin 2016</h3>
-</header>
-<nav id="TOC">
-<ul>
-<li><a href="#overview-of-tests-shipped-with-afb-daemon">Overview of tests shipped with AFB-Daemon</a><ul>
-<li><a href="#list-of-tests">List of tests</a></li>
-<li><a href="#detail-of-tests">Detail of tests</a><ul>
-<li><a href="#afb-client-demo-command-line-websockets">afb-client-demo (command-line WebSockets)</a></li>
-<li><a href="#token-websock.qml-qtqml-websockets">token-websock.qml (Qt/QML WebSockets)</a></li>
-<li><a href="#html-html5js-http-rest-websockets">*.html (HTML5/JS HTTP-REST &amp; WebSockets)</a></li>
-</ul></li>
-</ul></li>
-</ul>
-</nav>
-<h1 id="overview-of-tests-shipped-with-afb-daemon">Overview of tests shipped with AFB-Daemon</h1>
-<h2 id="list-of-tests">List of tests</h2>
-<p>Here are the tests shipped in the source tree:</p>
-<ul>
-<li><p><strong>afb-client-demo</strong> (command-line WebSockets)</p></li>
-<li><p><strong>token-websock.qml</strong> (Qt/QML WebSockets)</p></li>
-<li><p>*<strong>.html</strong> (HTML5/JS HTTP-REST &amp; WebSockets)</p></li>
-</ul>
-<h2 id="detail-of-tests">Detail of tests</h2>
-<h3 id="afb-client-demo-command-line-websockets">afb-client-demo (command-line WebSockets)</h3>
-<p>This clients interactively calls bindings APIs from the command line, using the binder <a href="https://en.wikipedia.org/wiki/WebSocket">WebSockets</a> facility.</p>
-<p>If <em>afb-daemon</em> has been launched with the following parameters:</p>
-<pre><code>$ afb-daemon --port=1234 --token=123456 [...]</code></pre>
-<p>Then run the client with :</p>
-<pre><code>afb-client-demo ws://localhost:1234/api?token=123456 [&lt;api&gt; &lt;verb&gt; [&lt;json-data&gt;]]</code></pre>
-<p>For instance, to initialize the Audio binding from the command line :</p>
-<pre><code>afb-client-demo ws://localhost:1234/api?token=123456</code></pre>
-<p>The command doesn't return. You should type requests of type <api> <verb> [<json-data>]. So, try:</p>
-<pre><code>auth connect
-hello pingjson true</code></pre>
-<p><br /></p>
-<h3 id="token-websock.qml-qtqml-websockets">token-websock.qml (Qt/QML WebSockets)</h3>
-<p>If <em>afb-daemon</em> has been launched with the following parameters:</p>
-<pre><code>$ afb-daemon --port=1234 --token=123456 [...]</code></pre>
-<p>and Qt5 is installed.</p>
-<p>For installing Qt5 on <strong>Ubuntu 16.04</strong>:</p>
-<pre><code>$ apt-get install qmlscene qml-module-qtwebsockets qml-module-qtquick-controls</code></pre>
-<p>For installing Qt5 on <strong>Fedora 23</strong> :</p>
-<pre><code>$ dnf install qt5-qtdeclarative-devel qt5-qtwebsockets-devel qt5-qtquickcontrols</code></pre>
-<p>Then run the client with :</p>
-<pre><code>qmlscene test/token-websock.qml</code></pre>
-<p>and interactively press the buttons, &quot;Connect&quot;, &quot;Refresh&quot;, &quot;Logout&quot;.</p>
-<p><br /></p>
-<h3 id="html-html5js-http-rest-websockets">*.html (HTML5/JS HTTP-REST &amp; WebSockets)</h3>
-<p>If <em>afb-daemon</em> has been launched with the following parameters:</p>
-<pre><code>$ afb-daemon --port=1234 --rootdir=$PWD/test [...]</code></pre>
-<p><em>(&quot;$PWD/test</em>&quot; being the &quot;test&quot; subdirectory of the source tree)_</p>
-<p>Then open your preferred Web browser, connect to the following URL:</p>
-<pre><code>http://localhost:1234</code></pre>
-<p>and interactively run the various tests.</p>
-</body>
-</html>
diff --git a/doc/afb-tests-overview.md b/doc/afb-tests-overview.md
index b70eda12..d6f619fe 100644
--- a/doc/afb-tests-overview.md
+++ b/doc/afb-tests-overview.md
@@ -58,7 +58,7 @@ For installing Qt5 on **Ubuntu 16.04**:
$ apt-get install qmlscene qml-module-qtwebsockets qml-module-qtquick-controls
-For installing Qt5 on **Fedora 23** :
+For installing Qt5 on **Fedora >= 22** :
$ dnf install qt5-qtdeclarative-devel qt5-qtwebsockets-devel qt5-qtquickcontrols
diff --git a/doc/doc.css b/doc/doc.css
deleted file mode 100644
index f3d55f9d..00000000
--- a/doc/doc.css
+++ /dev/null
@@ -1,40 +0,0 @@
-body {
- background: #fff url(triskel_iot_bzh.svg) no-repeat fixed right top;
- font-family: "Verdana";
- color: #000;
-}
-
-h1, h2, h3, h4 {
- color: #306;
- text-decoration: underline;
-}
-
-pre {
- border: medium dashed #306;
- border-width: 0.1em;
- background-color: #eee;
- margin-left: 2em;
- margin-right: 2em;
- padding: 1em;
- outline: #555;
-}
-
-blockquote {
- border-left: solid thick black;
- background-color: #ff8;
- font: bolder;
- padding: 0.7em 1.5em;
-}
-
-table {
- margin-left: 2em;
- background-color: #dff;
- outline: 0.25em solid #a6f;
-/* padding: 0.25em;*/
-}
-thead {background-color: #a6f;}
-tr:nth-child(even) {background-color: #aee;}
-td { padding: 0.1em 0.5em; }
-
-figure img {width: 80%;}
-figure {text-align: center;}
diff --git a/doc/index.md b/doc/index.md
new file mode 120000
index 00000000..81c25433
--- /dev/null
+++ b/doc/index.md
@@ -0,0 +1 @@
+afb-overview.md \ No newline at end of file
diff --git a/doc/pictures/AFB_for_services.svg b/doc/pictures/AFB_for_services.svg
new file mode 100644
index 00000000..6e536c50
--- /dev/null
+++ b/doc/pictures/AFB_for_services.svg
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.2" width="259.41mm" height="165.11mm" viewBox="1000 2270 25941 16511" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
+ <defs class="ClipPathGroup">
+ <clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse">
+ <rect x="1000" y="2270" width="25941" height="16511"/>
+ </clipPath>
+ </defs>
+ <defs>
+ <font id="EmbeddedFont_1" horiz-adv-x="2048">
+ <font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1852" descent="423"/>
+ <missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
+ <glyph unicode="y" horiz-adv-x="1033" d="M 604,1 C 579,-64 553,-123 527,-175 500,-227 471,-272 438,-309 405,-346 369,-374 329,-394 289,-413 243,-423 191,-423 168,-423 147,-423 128,-423 109,-423 88,-420 67,-414 L 67,-279 C 80,-282 94,-284 110,-284 126,-284 140,-284 151,-284 204,-284 253,-264 298,-225 343,-186 383,-124 417,-38 L 434,5 5,1082 197,1082 425,484 C 432,466 440,442 451,412 461,382 471,352 482,322 492,292 501,265 509,241 517,217 522,202 523,196 525,203 530,218 538,240 545,261 554,285 564,312 573,339 583,366 593,393 603,420 611,444 618,464 L 830,1082 1020,1082 604,1 Z"/>
+ <glyph unicode="x" horiz-adv-x="1006" d="M 801,0 L 510,444 217,0 23,0 408,556 41,1082 240,1082 510,661 778,1082 979,1082 612,558 1002,0 801,0 Z"/>
+ <glyph unicode="v" horiz-adv-x="1033" d="M 613,0 L 400,0 7,1082 199,1082 437,378 C 442,363 447,346 454,325 460,304 466,282 473,259 480,236 486,215 492,194 497,173 502,155 506,141 510,155 515,173 522,194 528,215 534,236 541,258 548,280 555,302 562,323 569,344 575,361 580,376 L 826,1082 1017,1082 613,0 Z"/>
+ <glyph unicode="u" horiz-adv-x="874" d="M 314,1082 L 314,396 C 314,343 318,299 326,264 333,229 346,200 363,179 380,157 403,142 432,133 460,124 495,119 537,119 580,119 618,127 653,142 687,157 716,178 741,207 765,235 784,270 797,312 810,353 817,401 817,455 L 817,1082 997,1082 997,228 C 997,205 997,181 998,156 998,131 998,107 999,85 1000,62 1000,43 1001,27 1002,11 1002,3 1003,3 L 833,3 C 832,6 832,15 831,30 830,44 830,61 829,79 828,98 827,117 826,136 825,156 825,172 825,185 L 822,185 C 805,154 786,125 765,100 744,75 720,53 693,36 666,18 634,4 599,-6 564,-15 523,-20 476,-20 416,-20 364,-13 321,2 278,17 242,39 214,70 186,101 166,140 153,188 140,236 133,294 133,361 L 133,1082 314,1082 Z"/>
+ <glyph unicode="t" horiz-adv-x="531" d="M 554,8 C 527,1 499,-5 471,-10 442,-14 409,-16 372,-16 228,-16 156,66 156,229 L 156,951 31,951 31,1082 163,1082 216,1324 336,1324 336,1082 536,1082 536,951 336,951 336,268 C 336,216 345,180 362,159 379,138 408,127 450,127 467,127 484,128 501,131 517,134 535,137 554,141 L 554,8 Z"/>
+ <glyph unicode="s" horiz-adv-x="901" d="M 950,299 C 950,248 940,203 921,164 901,124 872,91 835,64 798,37 752,16 698,2 643,-13 581,-20 511,-20 448,-20 392,-15 342,-6 291,4 247,20 209,41 171,62 139,91 114,126 88,161 69,203 57,254 L 216,285 C 231,227 263,185 311,158 359,131 426,117 511,117 550,117 585,120 618,125 650,130 678,140 701,153 724,166 743,183 756,205 769,226 775,253 775,285 775,318 767,345 752,366 737,387 715,404 688,418 661,432 628,444 589,455 550,465 507,476 460,489 417,500 374,513 331,527 288,541 250,560 216,583 181,606 153,634 132,668 111,702 100,745 100,796 100,895 135,970 206,1022 276,1073 378,1099 513,1099 632,1099 727,1078 798,1036 868,994 912,927 931,834 L 769,814 C 763,842 752,866 736,885 720,904 701,919 678,931 655,942 630,951 602,956 573,961 544,963 513,963 432,963 372,951 333,926 294,901 275,864 275,814 275,785 282,761 297,742 311,723 331,707 357,694 382,681 413,669 449,660 485,650 525,640 568,629 597,622 626,614 656,606 686,597 715,587 744,576 772,564 799,550 824,535 849,519 870,500 889,478 908,456 923,430 934,401 945,372 950,338 950,299 Z"/>
+ <glyph unicode="r" horiz-adv-x="530" d="M 142,0 L 142,830 C 142,853 142,876 142,900 141,923 141,946 140,968 139,990 139,1011 138,1030 137,1049 137,1067 136,1082 L 306,1082 C 307,1067 308,1049 309,1030 310,1010 311,990 312,969 313,948 313,929 314,910 314,891 314,874 314,861 L 318,861 C 331,902 344,938 359,969 373,999 390,1024 409,1044 428,1063 451,1078 478,1088 505,1097 537,1102 575,1102 590,1102 604,1101 617,1099 630,1096 641,1094 648,1092 L 648,927 C 636,930 622,933 606,935 590,936 572,937 552,937 511,937 476,928 447,909 418,890 394,865 376,832 357,799 344,759 335,714 326,668 322,618 322,564 L 322,0 142,0 Z"/>
+ <glyph unicode="o" horiz-adv-x="980" d="M 1053,542 C 1053,353 1011,212 928,119 845,26 724,-20 565,-20 490,-20 422,-9 363,14 304,37 254,71 213,118 172,165 140,223 119,294 97,364 86,447 86,542 86,915 248,1102 571,1102 655,1102 728,1090 789,1067 850,1044 900,1009 939,962 978,915 1006,857 1025,787 1044,717 1053,635 1053,542 Z M 864,542 C 864,626 858,695 845,750 832,805 813,848 788,881 763,914 732,937 696,950 660,963 619,969 574,969 528,969 487,962 450,949 413,935 381,912 355,879 329,846 309,802 296,747 282,692 275,624 275,542 275,458 282,389 297,334 312,279 332,235 358,202 383,169 414,146 449,133 484,120 522,113 563,113 609,113 651,120 688,133 725,146 757,168 783,201 809,234 829,278 843,333 857,388 864,458 864,542 Z"/>
+ <glyph unicode="n" horiz-adv-x="874" d="M 825,0 L 825,686 C 825,739 821,783 814,818 806,853 793,882 776,904 759,925 736,941 708,950 679,959 644,963 602,963 559,963 521,956 487,941 452,926 423,904 399,876 374,847 355,812 342,771 329,729 322,681 322,627 L 322,0 142,0 142,853 C 142,876 142,900 142,925 141,950 141,974 140,996 139,1019 139,1038 138,1054 137,1070 137,1078 136,1078 L 306,1078 C 307,1075 307,1066 308,1052 309,1037 310,1021 311,1002 312,984 312,965 313,945 314,926 314,910 314,897 L 317,897 C 334,928 353,957 374,982 395,1007 419,1029 446,1047 473,1064 505,1078 540,1088 575,1097 616,1102 663,1102 723,1102 775,1095 818,1080 861,1065 897,1043 925,1012 953,981 974,942 987,894 1000,845 1006,788 1006,721 L 1006,0 825,0 Z"/>
+ <glyph unicode="l" horiz-adv-x="187" d="M 138,0 L 138,1484 318,1484 318,0 138,0 Z"/>
+ <glyph unicode="i" horiz-adv-x="187" d="M 137,1312 L 137,1484 317,1484 317,1312 137,1312 Z M 137,0 L 137,1082 317,1082 317,0 137,0 Z"/>
+ <glyph unicode="e" horiz-adv-x="980" d="M 276,503 C 276,446 282,394 294,347 305,299 323,258 348,224 372,189 403,163 441,144 479,125 525,115 578,115 656,115 719,131 766,162 813,193 844,233 861,281 L 1019,236 C 1008,206 992,176 972,146 951,115 924,88 890,64 856,39 814,19 763,4 712,-12 650,-20 578,-20 418,-20 296,28 213,123 129,218 87,360 87,548 87,649 100,735 125,806 150,876 185,933 229,977 273,1021 324,1053 383,1073 442,1092 504,1102 571,1102 662,1102 738,1087 799,1058 860,1029 909,988 946,937 983,885 1009,824 1025,754 1040,684 1048,608 1048,527 L 1048,503 276,503 Z M 862,641 C 852,755 823,838 775,891 727,943 658,969 568,969 538,969 507,964 474,955 441,945 410,928 382,903 354,878 330,845 311,803 292,760 281,706 278,641 L 862,641 Z"/>
+ <glyph unicode="d" horiz-adv-x="927" d="M 821,174 C 788,105 744,55 689,25 634,-5 565,-20 484,-20 347,-20 247,26 183,118 118,210 86,349 86,536 86,913 219,1102 484,1102 566,1102 634,1087 689,1057 744,1027 788,979 821,914 L 823,914 C 823,921 823,931 823,946 822,960 822,975 822,991 821,1006 821,1021 821,1035 821,1049 821,1059 821,1065 L 821,1484 1001,1484 1001,219 C 1001,193 1001,168 1002,143 1002,119 1002,97 1003,77 1004,57 1004,40 1005,26 1006,11 1006,4 1007,4 L 835,4 C 834,11 833,20 832,32 831,44 830,58 829,73 828,89 827,105 826,123 825,140 825,157 825,174 L 821,174 Z M 275,542 C 275,467 280,403 289,350 298,297 313,253 334,219 355,184 381,159 413,143 445,127 484,119 530,119 577,119 619,127 656,142 692,157 722,182 747,217 771,251 789,296 802,351 815,406 821,474 821,554 821,631 815,696 802,749 789,802 771,844 746,877 721,910 691,933 656,948 620,962 579,969 532,969 488,969 450,961 418,946 386,931 359,906 338,872 317,838 301,794 291,740 280,685 275,619 275,542 Z"/>
+ <glyph unicode="c" horiz-adv-x="901" d="M 275,546 C 275,484 280,427 289,375 298,323 313,278 334,241 355,203 384,174 419,153 454,132 497,122 548,122 612,122 666,139 709,173 752,206 778,258 788,328 L 970,328 C 964,283 951,239 931,197 911,155 884,118 850,86 815,54 773,28 724,9 675,-10 618,-20 553,-20 468,-20 396,-6 337,23 278,52 230,91 193,142 156,192 129,251 112,320 95,388 87,462 87,542 87,615 93,679 105,735 117,790 134,839 156,881 177,922 203,957 232,986 261,1014 293,1037 328,1054 362,1071 398,1083 436,1091 474,1098 512,1102 551,1102 612,1102 666,1094 713,1077 760,1060 801,1038 836,1009 870,980 898,945 919,906 940,867 955,824 964,779 L 779,765 C 770,825 746,873 708,908 670,943 616,961 546,961 495,961 452,953 418,936 383,919 355,893 334,859 313,824 298,781 289,729 280,677 275,616 275,546 Z"/>
+ <glyph unicode="b" horiz-adv-x="953" d="M 1053,546 C 1053,169 920,-20 655,-20 573,-20 505,-5 451,25 396,54 352,102 318,168 L 316,168 C 316,150 316,132 315,113 314,94 313,77 312,61 311,45 310,31 309,19 308,8 307,2 306,2 L 132,2 C 133,8 133,18 134,32 135,47 135,64 136,84 137,104 137,126 138,150 138,174 138,199 138,225 L 138,1484 318,1484 318,1061 C 318,1041 318,1022 318,1004 317,985 317,969 316,955 315,938 315,923 314,908 L 318,908 C 351,977 396,1027 451,1057 506,1087 574,1102 655,1102 792,1102 892,1056 957,964 1021,872 1053,733 1053,546 Z M 864,540 C 864,615 859,679 850,732 841,785 826,829 805,864 784,898 758,923 726,939 694,955 655,963 609,963 562,963 520,955 484,940 447,925 417,900 393,866 368,832 350,787 337,732 324,677 318,609 318,529 318,452 324,387 337,334 350,281 368,239 393,206 417,173 447,149 483,135 519,120 560,113 607,113 651,113 689,121 721,136 753,151 780,176 801,210 822,244 838,288 849,343 859,397 864,463 864,540 Z"/>
+ <glyph unicode="a" horiz-adv-x="1060" d="M 414,-20 C 305,-20 224,9 169,66 114,124 87,203 87,303 87,375 101,434 128,480 155,526 190,562 234,588 277,614 327,632 383,642 439,652 496,657 554,657 L 797,657 797,717 C 797,762 792,800 783,832 774,863 759,889 740,908 721,928 697,942 668,951 639,960 604,965 565,965 530,965 499,963 471,958 443,953 419,944 398,931 377,918 361,900 348,878 335,855 327,827 323,793 L 135,810 C 142,853 154,892 173,928 192,963 218,994 253,1020 287,1046 330,1066 382,1081 433,1095 496,1102 569,1102 705,1102 807,1071 876,1009 945,946 979,856 979,738 L 979,272 C 979,219 986,179 1000,152 1014,125 1041,111 1080,111 1090,111 1100,112 1110,113 1120,114 1130,116 1139,118 L 1139,6 C 1116,1 1094,-3 1072,-6 1049,-9 1025,-10 1000,-10 966,-10 937,-5 913,4 888,13 868,26 853,45 838,63 826,86 818,113 810,140 805,171 803,207 L 797,207 C 778,172 757,141 734,113 711,85 684,61 653,42 622,22 588,7 549,-4 510,-15 465,-20 414,-20 Z M 455,115 C 512,115 563,125 606,146 649,167 684,194 713,226 741,259 762,294 776,332 790,371 797,408 797,443 L 797,531 600,531 C 556,531 514,528 475,522 435,517 400,506 370,489 340,472 316,449 299,418 281,388 272,349 272,300 272,241 288,195 320,163 351,131 396,115 455,115 Z"/>
+ <glyph unicode="Y" horiz-adv-x="1298" d="M 777,584 L 777,0 587,0 587,584 45,1409 255,1409 684,738 1111,1409 1321,1409 777,584 Z"/>
+ <glyph unicode="T" horiz-adv-x="1192" d="M 720,1253 L 720,0 530,0 530,1253 46,1253 46,1409 1204,1409 1204,1253 720,1253 Z"/>
+ <glyph unicode="S" horiz-adv-x="1192" d="M 1272,389 C 1272,330 1261,275 1238,225 1215,175 1179,132 1131,96 1083,59 1023,31 950,11 877,-10 790,-20 690,-20 515,-20 378,11 280,72 182,133 120,222 93,338 L 278,375 C 287,338 302,305 321,275 340,245 367,219 400,198 433,176 473,159 522,147 571,135 629,129 697,129 754,129 806,134 853,144 900,153 941,168 975,188 1009,208 1036,234 1055,266 1074,297 1083,335 1083,379 1083,425 1073,462 1052,491 1031,520 1001,543 963,562 925,581 880,596 827,609 774,622 716,635 652,650 613,659 573,668 534,679 494,689 456,701 420,716 383,730 349,747 317,766 285,785 257,809 234,836 211,863 192,894 179,930 166,965 159,1006 159,1053 159,1120 173,1177 200,1225 227,1272 264,1311 312,1342 360,1373 417,1395 482,1409 547,1423 618,1430 694,1430 781,1430 856,1423 918,1410 980,1396 1032,1375 1075,1348 1118,1321 1152,1287 1178,1247 1203,1206 1224,1159 1239,1106 L 1051,1073 C 1042,1107 1028,1137 1011,1164 993,1191 970,1213 941,1231 912,1249 878,1263 837,1272 796,1281 747,1286 692,1286 627,1286 572,1280 528,1269 483,1257 448,1241 421,1221 394,1201 374,1178 363,1151 351,1124 345,1094 345,1063 345,1021 356,987 377,960 398,933 426,910 462,892 498,874 540,859 587,847 634,835 685,823 738,811 781,801 825,791 868,781 911,770 952,758 991,744 1030,729 1067,712 1102,693 1136,674 1166,650 1191,622 1216,594 1236,561 1251,523 1265,485 1272,440 1272,389 Z"/>
+ <glyph unicode="R" horiz-adv-x="1244" d="M 1164,0 L 798,585 359,585 359,0 168,0 168,1409 831,1409 C 911,1409 982,1400 1044,1382 1105,1363 1157,1337 1199,1302 1241,1267 1273,1225 1295,1175 1317,1125 1328,1069 1328,1006 1328,961 1322,917 1309,874 1296,831 1275,791 1247,755 1219,719 1183,688 1140,662 1097,636 1045,618 984,607 L 1384,0 1164,0 Z M 1136,1004 C 1136,1047 1129,1084 1114,1115 1099,1146 1078,1173 1050,1194 1022,1215 988,1230 948,1241 908,1251 863,1256 812,1256 L 359,1256 359,736 820,736 C 875,736 922,743 962,757 1002,770 1035,789 1061,813 1086,837 1105,865 1118,898 1130,931 1136,966 1136,1004 Z"/>
+ <glyph unicode="P" horiz-adv-x="1112" d="M 1258,985 C 1258,924 1248,867 1228,814 1207,761 1177,715 1137,676 1096,637 1046,606 985,583 924,560 854,549 773,549 L 359,549 359,0 168,0 168,1409 761,1409 C 844,1409 917,1399 979,1379 1041,1358 1093,1330 1134,1293 1175,1256 1206,1211 1227,1159 1248,1106 1258,1048 1258,985 Z M 1066,983 C 1066,1072 1039,1140 984,1187 929,1233 847,1256 738,1256 L 359,1256 359,700 746,700 C 856,700 937,724 989,773 1040,822 1066,892 1066,983 Z"/>
+ <glyph unicode="O" horiz-adv-x="1430" d="M 1495,711 C 1495,601 1479,501 1448,411 1416,321 1370,244 1310,180 1250,116 1177,67 1090,32 1003,-3 905,-20 795,-20 679,-20 577,-2 490,35 403,71 330,122 272,187 214,252 170,329 141,418 112,507 97,605 97,711 97,821 112,920 143,1009 174,1098 219,1173 278,1236 337,1298 411,1346 498,1380 585,1413 684,1430 797,1430 909,1430 1009,1413 1096,1379 1183,1345 1256,1297 1315,1234 1374,1171 1418,1096 1449,1007 1480,918 1495,820 1495,711 Z M 1300,711 C 1300,796 1289,873 1268,942 1246,1011 1214,1071 1172,1120 1129,1169 1077,1207 1014,1234 951,1261 879,1274 797,1274 713,1274 639,1261 576,1234 513,1207 460,1169 418,1120 375,1071 344,1011 323,942 302,873 291,796 291,711 291,626 302,549 324,479 345,408 377,348 420,297 462,246 515,206 578,178 641,149 713,135 795,135 883,135 959,149 1023,178 1086,207 1139,247 1180,298 1221,349 1251,409 1271,480 1290,551 1300,628 1300,711 Z"/>
+ <glyph unicode="N" horiz-adv-x="1165" d="M 1082,0 L 328,1200 C 329,1167 331,1135 333,1103 334,1076 336,1047 337,1017 338,986 338,959 338,936 L 338,0 168,0 168,1409 390,1409 1152,201 C 1150,234 1148,266 1146,299 1145,327 1143,358 1142,391 1141,424 1140,455 1140,485 L 1140,1409 1312,1409 1312,0 1082,0 Z"/>
+ <glyph unicode="M" horiz-adv-x="1377" d="M 1366,0 L 1366,940 C 1366,974 1366,1009 1367,1044 1368,1079 1369,1112 1370,1141 1371,1175 1373,1208 1375,1240 1366,1206 1356,1172 1346,1139 1337,1110 1328,1080 1318,1048 1307,1015 1297,986 1287,960 L 923,0 789,0 420,960 C 416,970 412,982 408,995 403,1008 399,1023 394,1038 389,1053 384,1068 379,1084 374,1099 369,1115 364,1130 353,1165 342,1202 331,1240 332,1203 333,1166 334,1129 335,1098 336,1065 337,1031 338,996 338,966 338,940 L 338,0 168,0 168,1409 419,1409 794,432 C 799,419 804,402 811,381 818,360 824,338 830,316 836,294 842,273 847,254 852,234 855,219 857,208 859,219 863,234 868,254 873,274 880,295 887,317 894,339 900,360 907,381 914,402 920,419 925,432 L 1293,1409 1538,1409 1538,0 1366,0 Z"/>
+ <glyph unicode="L" horiz-adv-x="927" d="M 168,0 L 168,1409 359,1409 359,156 1071,156 1071,0 168,0 Z"/>
+ <glyph unicode="I" horiz-adv-x="213" d="M 189,0 L 189,1409 380,1409 380,0 189,0 Z"/>
+ <glyph unicode="G" horiz-adv-x="1377" d="M 103,711 C 103,821 118,920 148,1009 177,1098 222,1173 281,1236 340,1298 413,1346 500,1380 587,1413 689,1430 804,1430 891,1430 967,1422 1032,1407 1097,1392 1154,1370 1202,1341 1250,1312 1291,1278 1324,1237 1357,1196 1386,1149 1409,1098 L 1227,1044 C 1210,1079 1189,1110 1165,1139 1140,1167 1111,1191 1076,1211 1041,1231 1001,1247 956,1258 910,1269 858,1274 799,1274 714,1274 640,1261 577,1234 514,1207 461,1169 420,1120 379,1071 348,1011 328,942 307,873 297,796 297,711 297,626 308,549 330,479 352,408 385,348 428,297 471,246 525,206 590,178 654,149 728,135 813,135 868,135 919,140 966,149 1013,158 1055,171 1093,186 1130,201 1163,217 1192,236 1221,254 1245,272 1264,291 L 1264,545 843,545 843,705 1440,705 1440,219 C 1409,187 1372,157 1330,128 1287,99 1240,73 1187,51 1134,29 1077,12 1014,-1 951,-14 884,-20 813,-20 694,-20 591,-2 502,35 413,71 340,122 281,187 222,252 177,329 148,418 118,507 103,605 103,711 Z"/>
+ <glyph unicode="F" horiz-adv-x="1006" d="M 359,1253 L 359,729 1145,729 1145,571 359,571 359,0 168,0 168,1409 1169,1409 1169,1253 359,1253 Z"/>
+ <glyph unicode="E" horiz-adv-x="1138" d="M 168,0 L 168,1409 1237,1409 1237,1253 359,1253 359,801 1177,801 1177,647 359,647 359,156 1278,156 1278,0 168,0 Z"/>
+ <glyph unicode="D" horiz-adv-x="1218" d="M 1381,719 C 1381,602 1363,498 1328,409 1293,319 1244,244 1183,184 1122,123 1049,78 966,47 882,16 792,0 695,0 L 168,0 168,1409 634,1409 C 743,1409 843,1396 935,1369 1026,1342 1105,1300 1171,1244 1237,1187 1289,1116 1326,1029 1363,942 1381,839 1381,719 Z M 1189,719 C 1189,814 1175,896 1148,964 1121,1031 1082,1087 1033,1130 984,1173 925,1205 856,1226 787,1246 712,1256 630,1256 L 359,1256 359,153 673,153 C 747,153 816,165 879,189 942,213 996,249 1042,296 1088,343 1124,402 1150,473 1176,544 1189,626 1189,719 Z"/>
+ <glyph unicode="C" horiz-adv-x="1324" d="M 792,1274 C 712,1274 641,1261 580,1234 518,1207 466,1169 425,1120 383,1071 351,1011 330,942 309,873 298,796 298,711 298,626 310,549 333,479 356,408 389,348 432,297 475,246 527,207 590,179 652,151 722,137 800,137 855,137 905,144 950,159 995,173 1035,193 1072,219 1108,245 1140,276 1169,312 1198,347 1223,387 1245,430 L 1401,352 C 1376,299 1344,250 1307,205 1270,160 1226,120 1176,87 1125,54 1068,28 1005,9 941,-10 870,-20 791,-20 677,-20 577,-2 492,35 406,71 334,122 277,187 219,252 176,329 147,418 118,507 104,605 104,711 104,821 119,920 150,1009 180,1098 224,1173 283,1236 341,1298 413,1346 498,1380 583,1413 681,1430 790,1430 940,1430 1065,1401 1166,1342 1267,1283 1341,1196 1388,1081 L 1207,1021 C 1194,1054 1176,1086 1153,1117 1130,1147 1102,1174 1068,1197 1034,1220 994,1239 949,1253 903,1267 851,1274 792,1274 Z"/>
+ <glyph unicode="B" horiz-adv-x="1112" d="M 1258,397 C 1258,326 1244,265 1216,215 1188,164 1150,123 1103,92 1056,60 1001,37 938,22 875,7 809,0 740,0 L 168,0 168,1409 680,1409 C 758,1409 828,1403 889,1390 950,1377 1002,1356 1045,1328 1088,1300 1120,1265 1143,1222 1165,1179 1176,1127 1176,1067 1176,1028 1171,991 1160,956 1149,921 1132,890 1110,862 1087,833 1059,809 1026,789 992,768 953,753 908,743 965,736 1015,723 1059,704 1102,685 1139,660 1168,630 1197,600 1220,565 1235,526 1250,486 1258,443 1258,397 Z M 984,1044 C 984,1120 958,1174 906,1207 854,1240 779,1256 680,1256 L 359,1256 359,810 680,810 C 736,810 783,816 822,827 861,838 892,853 916,874 940,894 957,918 968,947 979,976 984,1008 984,1044 Z M 1065,412 C 1065,457 1057,495 1041,526 1024,557 1001,583 970,603 939,623 903,638 860,647 817,656 768,661 715,661 L 359,661 359,153 730,153 C 779,153 824,157 865,165 906,173 941,187 971,207 1000,227 1023,254 1040,287 1057,320 1065,362 1065,412 Z"/>
+ <glyph unicode="A" horiz-adv-x="1377" d="M 1167,0 L 1006,412 364,412 202,0 4,0 579,1409 796,1409 1362,0 1167,0 Z M 768,1026 C 757,1053 747,1080 738,1107 728,1134 719,1159 712,1182 705,1204 699,1223 694,1238 689,1253 686,1262 685,1265 684,1262 681,1252 676,1237 671,1222 665,1203 658,1180 650,1157 641,1132 632,1105 622,1078 612,1051 602,1024 L 422,561 949,561 768,1026 Z"/>
+ <glyph unicode="-" horiz-adv-x="531" d="M 91,464 L 91,624 591,624 591,464 91,464 Z"/>
+ <glyph unicode="&amp;" horiz-adv-x="1297" d="M 1193,-12 C 1129,-12 1073,-1 1025,21 977,43 934,74 895,115 875,98 852,81 827,65 802,49 774,35 743,22 712,9 678,-1 642,-9 605,-16 566,-20 523,-20 445,-20 378,-10 321,10 264,30 217,58 180,93 143,128 116,169 99,217 81,264 72,316 72,371 72,424 81,472 98,515 115,558 138,597 169,632 199,667 235,698 277,726 319,753 365,778 415,800 403,823 392,847 383,873 373,898 364,924 357,950 350,976 344,1002 340,1028 336,1054 334,1079 334,1102 334,1146 341,1187 354,1226 367,1264 388,1297 417,1326 445,1354 481,1376 526,1393 570,1409 623,1417 685,1417 734,1417 779,1411 820,1398 861,1385 896,1367 926,1343 956,1319 979,1289 996,1254 1013,1219 1021,1178 1021,1133 1021,1083 1010,1039 988,1000 966,961 936,926 899,895 862,864 818,837 769,812 720,787 667,763 612,741 653,665 698,594 747,527 796,460 848,394 905,329 946,389 980,452 1007,519 1034,585 1057,658 1076,739 L 1221,696 C 1198,603 1168,519 1133,444 1097,368 1056,296 1009,227 1044,191 1080,166 1115,151 1150,136 1184,129 1217,129 1238,129 1259,130 1279,133 1298,135 1317,139 1334,145 L 1334,10 C 1315,3 1294,-3 1269,-7 1244,-10 1218,-12 1193,-12 Z M 869,1133 C 869,1158 865,1180 856,1200 847,1220 834,1237 818,1252 802,1266 783,1277 760,1285 737,1292 711,1296 683,1296 619,1296 570,1279 537,1245 504,1210 487,1163 487,1102 487,1063 493,1022 506,979 518,936 533,895 552,858 595,875 636,893 675,912 714,930 747,950 776,972 805,993 827,1017 844,1044 861,1070 869,1100 869,1133 Z M 795,217 C 736,287 679,360 624,437 569,514 520,593 476,674 401,642 343,601 302,552 261,503 240,443 240,373 240,336 246,302 258,271 269,239 287,211 311,188 335,164 365,145 402,132 438,118 480,111 529,111 558,111 586,114 613,121 639,127 663,135 686,145 709,155 729,166 748,179 766,192 782,204 795,217 Z"/>
+ <glyph unicode=" " horiz-adv-x="556"/>
+ </font>
+ </defs>
+ <defs class="TextShapeIndex">
+ <g ooo:slide="id1" ooo:id-list="id3 id4 id5 id6 id7 id8 id9 id10 id11 id12 id13 id14 id15 id16 id17 id18 id19 id20 id21"/>
+ </defs>
+ <defs class="EmbeddedBulletChars">
+ <g id="bullet-char-template(57356)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
+ </g>
+ <g id="bullet-char-template(57354)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
+ </g>
+ <g id="bullet-char-template(10146)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
+ </g>
+ <g id="bullet-char-template(10132)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
+ </g>
+ <g id="bullet-char-template(10007)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
+ </g>
+ <g id="bullet-char-template(10004)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
+ </g>
+ <g id="bullet-char-template(9679)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
+ </g>
+ <g id="bullet-char-template(8226)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
+ </g>
+ <g id="bullet-char-template(8211)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
+ </g>
+ </defs>
+ <defs class="TextEmbeddedBitmaps"/>
+ <g class="SlideGroup">
+ <g>
+ <g id="id1" class="Slide" clip-path="url(#presentation_clip_path)">
+ <g class="Page">
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id3">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2269" y="2269" width="11433" height="5045"/>
+ <path fill="rgb(153,204,255)" stroke="none" d="M 7985,7312 L 2270,7312 2270,2270 13700,2270 13700,7312 7985,7312 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 7985,7312 L 2270,7312 2270,2270 13700,2270 13700,7312 7985,7312 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="564px" font-weight="400"><tspan class="TextPosition" x="4956" y="2903"><tspan fill="rgb(0,0,0)" stroke="none">Isolated security context</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id4">
+ <rect class="BoundingBox" stroke="none" fill="none" x="3539" y="3110" width="8893" height="927"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 7985,4035 L 3540,4035 3540,3111 12430,3111 12430,4035 7985,4035 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 7985,4035 L 3540,4035 3540,3111 12430,3111 12430,4035 7985,4035 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="5911" y="3794"><tspan fill="rgb(0,0,0)" stroke="none">APPLICATION</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id5">
+ <rect class="BoundingBox" stroke="none" fill="none" x="3538" y="4789" width="6354" height="1685"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 6715,6472 L 3539,6472 3539,4790 9890,4790 9890,6472 6715,6472 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 6715,6472 L 3539,6472 3539,4790 9890,4790 9890,6472 6715,6472 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="5836" y="5496"><tspan fill="rgb(0,0,0)" stroke="none">binder</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="4598" y="6207"><tspan fill="rgb(0,0,0)" stroke="none">AFB-DAEMON</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id6">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9889" y="4789" width="2542" height="1685"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 11160,6472 L 9890,6472 9890,4790 12429,4790 12429,6472 11160,6472 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 11160,6472 L 9890,6472 9890,4790 12429,4790 12429,6472 11160,6472 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="494px" font-weight="400"><tspan class="TextPosition" x="9957" y="5803"><tspan fill="rgb(0,0,0)" stroke="none">BINDINGS</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id7">
+ <rect class="BoundingBox" stroke="none" fill="none" x="8111" y="4034" width="3" height="759"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8112,4035 L 8112,4791"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id8">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7961" y="6470" width="302" height="3421"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 8105,6471 L 8111,9460"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 8112,9890 L 8261,9440 7961,9440 8112,9890 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id9">
+ <rect class="BoundingBox" stroke="none" fill="none" x="999" y="9888" width="25943" height="2670"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 13970,12556 L 1000,12556 1000,9889 26940,9889 26940,12556 13970,12556 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 13970,12556 L 1000,12556 1000,9889 26940,9889 26940,12556 13970,12556 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="11379" y="11443"><tspan fill="rgb(0,0,0)" stroke="none">D-Bus &amp; CYNARA</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id10">
+ <rect class="BoundingBox" stroke="none" fill="none" x="14969" y="3539" width="11433" height="3775"/>
+ <path fill="rgb(153,204,255)" stroke="none" d="M 20685,7312 L 14970,7312 14970,3540 26400,3540 26400,7312 20685,7312 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 20685,7312 L 14970,7312 14970,3540 26400,3540 26400,7312 20685,7312 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="564px" font-weight="400"><tspan class="TextPosition" x="17407" y="4173"><tspan fill="rgb(0,0,0)" stroke="none">Isolated security context A</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id11">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16238" y="4789" width="6354" height="1685"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 19415,6472 L 16239,6472 16239,4790 22590,4790 22590,6472 19415,6472 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 19415,6472 L 16239,6472 16239,4790 22590,4790 22590,6472 19415,6472 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="18536" y="5496"><tspan fill="rgb(0,0,0)" stroke="none">binder</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="17298" y="6207"><tspan fill="rgb(0,0,0)" stroke="none">AFB-DAEMON</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id12">
+ <rect class="BoundingBox" stroke="none" fill="none" x="22589" y="4789" width="2542" height="1685"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 23860,6472 L 22590,6472 22590,4790 25129,4790 25129,6472 23860,6472 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 23860,6472 L 22590,6472 22590,4790 25129,4790 25129,6472 23860,6472 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="388px" font-weight="400"><tspan class="TextPosition" x="23244" y="5334"><tspan fill="rgb(0,0,0)" stroke="none">service</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="388px" font-weight="400"><tspan class="TextPosition" x="22865" y="5766"><tspan fill="rgb(0,0,0)" stroke="none">BINDINGS </tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="388px" font-weight="400"><tspan class="TextPosition" x="23731" y="6198"><tspan fill="rgb(0,0,0)" stroke="none">A</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id13">
+ <rect class="BoundingBox" stroke="none" fill="none" x="20661" y="6470" width="302" height="3421"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 20805,6471 L 20811,9460"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 20812,9890 L 20961,9440 20661,9440 20812,9890 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id14">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2269" y="14969" width="11433" height="3813"/>
+ <path fill="rgb(153,204,255)" stroke="none" d="M 7985,18780 L 2270,18780 2270,14970 13700,14970 13700,18780 7985,18780 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 7985,18780 L 2270,18780 2270,14970 13700,14970 13700,18780 7985,18780 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="564px" font-weight="400"><tspan class="TextPosition" x="4690" y="18536"><tspan fill="rgb(0,0,0)" stroke="none">Isolated security context B</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id15">
+ <rect class="BoundingBox" stroke="none" fill="none" x="3538" y="15985" width="6354" height="1685"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 6715,17668 L 3539,17668 3539,15986 9890,15986 9890,17668 6715,17668 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 6715,17668 L 3539,17668 3539,15986 9890,15986 9890,17668 6715,17668 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="5836" y="16692"><tspan fill="rgb(0,0,0)" stroke="none">binder</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="4598" y="17403"><tspan fill="rgb(0,0,0)" stroke="none">AFB-DAEMON</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id16">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9889" y="15985" width="2542" height="1685"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 11160,17668 L 9890,17668 9890,15986 12429,15986 12429,17668 11160,17668 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 11160,17668 L 9890,17668 9890,15986 12429,15986 12429,17668 11160,17668 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="388px" font-weight="400"><tspan class="TextPosition" x="10544" y="16530"><tspan fill="rgb(0,0,0)" stroke="none">service</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="388px" font-weight="400"><tspan class="TextPosition" x="10165" y="16962"><tspan fill="rgb(0,0,0)" stroke="none">BINDINGS </tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="388px" font-weight="400"><tspan class="TextPosition" x="11031" y="17394"><tspan fill="rgb(0,0,0)" stroke="none">B</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id17">
+ <rect class="BoundingBox" stroke="none" fill="none" x="7835" y="12557" width="301" height="3431"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 7985,15986 L 7985,12987"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 7985,12557 L 7835,13007 8135,13007 7985,12557 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id18">
+ <rect class="BoundingBox" stroke="none" fill="none" x="14969" y="14969" width="11433" height="3813"/>
+ <path fill="rgb(153,204,255)" stroke="none" d="M 20685,18780 L 14970,18780 14970,14970 26400,14970 26400,18780 20685,18780 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 20685,18780 L 14970,18780 14970,14970 26400,14970 26400,18780 20685,18780 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="564px" font-weight="400"><tspan class="TextPosition" x="17375" y="18536"><tspan fill="rgb(0,0,0)" stroke="none">Isolated security context C</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id19">
+ <rect class="BoundingBox" stroke="none" fill="none" x="16238" y="15985" width="6354" height="1685"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 19415,17668 L 16239,17668 16239,15986 22590,15986 22590,17668 19415,17668 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 19415,17668 L 16239,17668 16239,15986 22590,15986 22590,17668 19415,17668 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="18536" y="16692"><tspan fill="rgb(0,0,0)" stroke="none">binder</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="17298" y="17403"><tspan fill="rgb(0,0,0)" stroke="none">AFB-DAEMON</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id20">
+ <rect class="BoundingBox" stroke="none" fill="none" x="22589" y="15985" width="2542" height="1685"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 23860,17668 L 22590,17668 22590,15986 25129,15986 25129,17668 23860,17668 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 23860,17668 L 22590,17668 22590,15986 25129,15986 25129,17668 23860,17668 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="388px" font-weight="400"><tspan class="TextPosition" x="23244" y="16530"><tspan fill="rgb(0,0,0)" stroke="none">service</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="388px" font-weight="400"><tspan class="TextPosition" x="22865" y="16962"><tspan fill="rgb(0,0,0)" stroke="none">BINDINGS </tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="388px" font-weight="400"><tspan class="TextPosition" x="23720" y="17394"><tspan fill="rgb(0,0,0)" stroke="none">C</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id21">
+ <rect class="BoundingBox" stroke="none" fill="none" x="20535" y="12557" width="301" height="3431"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 20685,15986 L 20685,12987"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 20685,12557 L 20535,13007 20835,13007 20685,12557 Z"/>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/doc/pictures/AFB_overview.svg b/doc/pictures/AFB_overview.svg
new file mode 100644
index 00000000..240dae89
--- /dev/null
+++ b/doc/pictures/AFB_overview.svg
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.2" width="114.31mm" height="101.61mm" viewBox="4810 11160 11431 10161" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
+ <defs class="ClipPathGroup">
+ <clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse">
+ <rect x="4810" y="11160" width="11431" height="10161"/>
+ </clipPath>
+ </defs>
+ <defs>
+ <font id="EmbeddedFont_1" horiz-adv-x="2048">
+ <font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1852" descent="423"/>
+ <missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
+ <glyph unicode="y" horiz-adv-x="1033" d="M 604,1 C 579,-64 553,-123 527,-175 500,-227 471,-272 438,-309 405,-346 369,-374 329,-394 289,-413 243,-423 191,-423 168,-423 147,-423 128,-423 109,-423 88,-420 67,-414 L 67,-279 C 80,-282 94,-284 110,-284 126,-284 140,-284 151,-284 204,-284 253,-264 298,-225 343,-186 383,-124 417,-38 L 434,5 5,1082 197,1082 425,484 C 432,466 440,442 451,412 461,382 471,352 482,322 492,292 501,265 509,241 517,217 522,202 523,196 525,203 530,218 538,240 545,261 554,285 564,312 573,339 583,366 593,393 603,420 611,444 618,464 L 830,1082 1020,1082 604,1 Z"/>
+ <glyph unicode="x" horiz-adv-x="1006" d="M 801,0 L 510,444 217,0 23,0 408,556 41,1082 240,1082 510,661 778,1082 979,1082 612,558 1002,0 801,0 Z"/>
+ <glyph unicode="u" horiz-adv-x="874" d="M 314,1082 L 314,396 C 314,343 318,299 326,264 333,229 346,200 363,179 380,157 403,142 432,133 460,124 495,119 537,119 580,119 618,127 653,142 687,157 716,178 741,207 765,235 784,270 797,312 810,353 817,401 817,455 L 817,1082 997,1082 997,228 C 997,205 997,181 998,156 998,131 998,107 999,85 1000,62 1000,43 1001,27 1002,11 1002,3 1003,3 L 833,3 C 832,6 832,15 831,30 830,44 830,61 829,79 828,98 827,117 826,136 825,156 825,172 825,185 L 822,185 C 805,154 786,125 765,100 744,75 720,53 693,36 666,18 634,4 599,-6 564,-15 523,-20 476,-20 416,-20 364,-13 321,2 278,17 242,39 214,70 186,101 166,140 153,188 140,236 133,294 133,361 L 133,1082 314,1082 Z"/>
+ <glyph unicode="t" horiz-adv-x="531" d="M 554,8 C 527,1 499,-5 471,-10 442,-14 409,-16 372,-16 228,-16 156,66 156,229 L 156,951 31,951 31,1082 163,1082 216,1324 336,1324 336,1082 536,1082 536,951 336,951 336,268 C 336,216 345,180 362,159 379,138 408,127 450,127 467,127 484,128 501,131 517,134 535,137 554,141 L 554,8 Z"/>
+ <glyph unicode="s" horiz-adv-x="901" d="M 950,299 C 950,248 940,203 921,164 901,124 872,91 835,64 798,37 752,16 698,2 643,-13 581,-20 511,-20 448,-20 392,-15 342,-6 291,4 247,20 209,41 171,62 139,91 114,126 88,161 69,203 57,254 L 216,285 C 231,227 263,185 311,158 359,131 426,117 511,117 550,117 585,120 618,125 650,130 678,140 701,153 724,166 743,183 756,205 769,226 775,253 775,285 775,318 767,345 752,366 737,387 715,404 688,418 661,432 628,444 589,455 550,465 507,476 460,489 417,500 374,513 331,527 288,541 250,560 216,583 181,606 153,634 132,668 111,702 100,745 100,796 100,895 135,970 206,1022 276,1073 378,1099 513,1099 632,1099 727,1078 798,1036 868,994 912,927 931,834 L 769,814 C 763,842 752,866 736,885 720,904 701,919 678,931 655,942 630,951 602,956 573,961 544,963 513,963 432,963 372,951 333,926 294,901 275,864 275,814 275,785 282,761 297,742 311,723 331,707 357,694 382,681 413,669 449,660 485,650 525,640 568,629 597,622 626,614 656,606 686,597 715,587 744,576 772,564 799,550 824,535 849,519 870,500 889,478 908,456 923,430 934,401 945,372 950,338 950,299 Z"/>
+ <glyph unicode="r" horiz-adv-x="530" d="M 142,0 L 142,830 C 142,853 142,876 142,900 141,923 141,946 140,968 139,990 139,1011 138,1030 137,1049 137,1067 136,1082 L 306,1082 C 307,1067 308,1049 309,1030 310,1010 311,990 312,969 313,948 313,929 314,910 314,891 314,874 314,861 L 318,861 C 331,902 344,938 359,969 373,999 390,1024 409,1044 428,1063 451,1078 478,1088 505,1097 537,1102 575,1102 590,1102 604,1101 617,1099 630,1096 641,1094 648,1092 L 648,927 C 636,930 622,933 606,935 590,936 572,937 552,937 511,937 476,928 447,909 418,890 394,865 376,832 357,799 344,759 335,714 326,668 322,618 322,564 L 322,0 142,0 Z"/>
+ <glyph unicode="o" horiz-adv-x="980" d="M 1053,542 C 1053,353 1011,212 928,119 845,26 724,-20 565,-20 490,-20 422,-9 363,14 304,37 254,71 213,118 172,165 140,223 119,294 97,364 86,447 86,542 86,915 248,1102 571,1102 655,1102 728,1090 789,1067 850,1044 900,1009 939,962 978,915 1006,857 1025,787 1044,717 1053,635 1053,542 Z M 864,542 C 864,626 858,695 845,750 832,805 813,848 788,881 763,914 732,937 696,950 660,963 619,969 574,969 528,969 487,962 450,949 413,935 381,912 355,879 329,846 309,802 296,747 282,692 275,624 275,542 275,458 282,389 297,334 312,279 332,235 358,202 383,169 414,146 449,133 484,120 522,113 563,113 609,113 651,120 688,133 725,146 757,168 783,201 809,234 829,278 843,333 857,388 864,458 864,542 Z"/>
+ <glyph unicode="n" horiz-adv-x="874" d="M 825,0 L 825,686 C 825,739 821,783 814,818 806,853 793,882 776,904 759,925 736,941 708,950 679,959 644,963 602,963 559,963 521,956 487,941 452,926 423,904 399,876 374,847 355,812 342,771 329,729 322,681 322,627 L 322,0 142,0 142,853 C 142,876 142,900 142,925 141,950 141,974 140,996 139,1019 139,1038 138,1054 137,1070 137,1078 136,1078 L 306,1078 C 307,1075 307,1066 308,1052 309,1037 310,1021 311,1002 312,984 312,965 313,945 314,926 314,910 314,897 L 317,897 C 334,928 353,957 374,982 395,1007 419,1029 446,1047 473,1064 505,1078 540,1088 575,1097 616,1102 663,1102 723,1102 775,1095 818,1080 861,1065 897,1043 925,1012 953,981 974,942 987,894 1000,845 1006,788 1006,721 L 1006,0 825,0 Z"/>
+ <glyph unicode="l" horiz-adv-x="187" d="M 138,0 L 138,1484 318,1484 318,0 138,0 Z"/>
+ <glyph unicode="i" horiz-adv-x="187" d="M 137,1312 L 137,1484 317,1484 317,1312 137,1312 Z M 137,0 L 137,1082 317,1082 317,0 137,0 Z"/>
+ <glyph unicode="e" horiz-adv-x="980" d="M 276,503 C 276,446 282,394 294,347 305,299 323,258 348,224 372,189 403,163 441,144 479,125 525,115 578,115 656,115 719,131 766,162 813,193 844,233 861,281 L 1019,236 C 1008,206 992,176 972,146 951,115 924,88 890,64 856,39 814,19 763,4 712,-12 650,-20 578,-20 418,-20 296,28 213,123 129,218 87,360 87,548 87,649 100,735 125,806 150,876 185,933 229,977 273,1021 324,1053 383,1073 442,1092 504,1102 571,1102 662,1102 738,1087 799,1058 860,1029 909,988 946,937 983,885 1009,824 1025,754 1040,684 1048,608 1048,527 L 1048,503 276,503 Z M 862,641 C 852,755 823,838 775,891 727,943 658,969 568,969 538,969 507,964 474,955 441,945 410,928 382,903 354,878 330,845 311,803 292,760 281,706 278,641 L 862,641 Z"/>
+ <glyph unicode="d" horiz-adv-x="927" d="M 821,174 C 788,105 744,55 689,25 634,-5 565,-20 484,-20 347,-20 247,26 183,118 118,210 86,349 86,536 86,913 219,1102 484,1102 566,1102 634,1087 689,1057 744,1027 788,979 821,914 L 823,914 C 823,921 823,931 823,946 822,960 822,975 822,991 821,1006 821,1021 821,1035 821,1049 821,1059 821,1065 L 821,1484 1001,1484 1001,219 C 1001,193 1001,168 1002,143 1002,119 1002,97 1003,77 1004,57 1004,40 1005,26 1006,11 1006,4 1007,4 L 835,4 C 834,11 833,20 832,32 831,44 830,58 829,73 828,89 827,105 826,123 825,140 825,157 825,174 L 821,174 Z M 275,542 C 275,467 280,403 289,350 298,297 313,253 334,219 355,184 381,159 413,143 445,127 484,119 530,119 577,119 619,127 656,142 692,157 722,182 747,217 771,251 789,296 802,351 815,406 821,474 821,554 821,631 815,696 802,749 789,802 771,844 746,877 721,910 691,933 656,948 620,962 579,969 532,969 488,969 450,961 418,946 386,931 359,906 338,872 317,838 301,794 291,740 280,685 275,619 275,542 Z"/>
+ <glyph unicode="c" horiz-adv-x="901" d="M 275,546 C 275,484 280,427 289,375 298,323 313,278 334,241 355,203 384,174 419,153 454,132 497,122 548,122 612,122 666,139 709,173 752,206 778,258 788,328 L 970,328 C 964,283 951,239 931,197 911,155 884,118 850,86 815,54 773,28 724,9 675,-10 618,-20 553,-20 468,-20 396,-6 337,23 278,52 230,91 193,142 156,192 129,251 112,320 95,388 87,462 87,542 87,615 93,679 105,735 117,790 134,839 156,881 177,922 203,957 232,986 261,1014 293,1037 328,1054 362,1071 398,1083 436,1091 474,1098 512,1102 551,1102 612,1102 666,1094 713,1077 760,1060 801,1038 836,1009 870,980 898,945 919,906 940,867 955,824 964,779 L 779,765 C 770,825 746,873 708,908 670,943 616,961 546,961 495,961 452,953 418,936 383,919 355,893 334,859 313,824 298,781 289,729 280,677 275,616 275,546 Z"/>
+ <glyph unicode="b" horiz-adv-x="953" d="M 1053,546 C 1053,169 920,-20 655,-20 573,-20 505,-5 451,25 396,54 352,102 318,168 L 316,168 C 316,150 316,132 315,113 314,94 313,77 312,61 311,45 310,31 309,19 308,8 307,2 306,2 L 132,2 C 133,8 133,18 134,32 135,47 135,64 136,84 137,104 137,126 138,150 138,174 138,199 138,225 L 138,1484 318,1484 318,1061 C 318,1041 318,1022 318,1004 317,985 317,969 316,955 315,938 315,923 314,908 L 318,908 C 351,977 396,1027 451,1057 506,1087 574,1102 655,1102 792,1102 892,1056 957,964 1021,872 1053,733 1053,546 Z M 864,540 C 864,615 859,679 850,732 841,785 826,829 805,864 784,898 758,923 726,939 694,955 655,963 609,963 562,963 520,955 484,940 447,925 417,900 393,866 368,832 350,787 337,732 324,677 318,609 318,529 318,452 324,387 337,334 350,281 368,239 393,206 417,173 447,149 483,135 519,120 560,113 607,113 651,113 689,121 721,136 753,151 780,176 801,210 822,244 838,288 849,343 859,397 864,463 864,540 Z"/>
+ <glyph unicode="a" horiz-adv-x="1060" d="M 414,-20 C 305,-20 224,9 169,66 114,124 87,203 87,303 87,375 101,434 128,480 155,526 190,562 234,588 277,614 327,632 383,642 439,652 496,657 554,657 L 797,657 797,717 C 797,762 792,800 783,832 774,863 759,889 740,908 721,928 697,942 668,951 639,960 604,965 565,965 530,965 499,963 471,958 443,953 419,944 398,931 377,918 361,900 348,878 335,855 327,827 323,793 L 135,810 C 142,853 154,892 173,928 192,963 218,994 253,1020 287,1046 330,1066 382,1081 433,1095 496,1102 569,1102 705,1102 807,1071 876,1009 945,946 979,856 979,738 L 979,272 C 979,219 986,179 1000,152 1014,125 1041,111 1080,111 1090,111 1100,112 1110,113 1120,114 1130,116 1139,118 L 1139,6 C 1116,1 1094,-3 1072,-6 1049,-9 1025,-10 1000,-10 966,-10 937,-5 913,4 888,13 868,26 853,45 838,63 826,86 818,113 810,140 805,171 803,207 L 797,207 C 778,172 757,141 734,113 711,85 684,61 653,42 622,22 588,7 549,-4 510,-15 465,-20 414,-20 Z M 455,115 C 512,115 563,125 606,146 649,167 684,194 713,226 741,259 762,294 776,332 790,371 797,408 797,443 L 797,531 600,531 C 556,531 514,528 475,522 435,517 400,506 370,489 340,472 316,449 299,418 281,388 272,349 272,300 272,241 288,195 320,163 351,131 396,115 455,115 Z"/>
+ <glyph unicode="Y" horiz-adv-x="1298" d="M 777,584 L 777,0 587,0 587,584 45,1409 255,1409 684,738 1111,1409 1321,1409 777,584 Z"/>
+ <glyph unicode="T" horiz-adv-x="1192" d="M 720,1253 L 720,0 530,0 530,1253 46,1253 46,1409 1204,1409 1204,1253 720,1253 Z"/>
+ <glyph unicode="S" horiz-adv-x="1192" d="M 1272,389 C 1272,330 1261,275 1238,225 1215,175 1179,132 1131,96 1083,59 1023,31 950,11 877,-10 790,-20 690,-20 515,-20 378,11 280,72 182,133 120,222 93,338 L 278,375 C 287,338 302,305 321,275 340,245 367,219 400,198 433,176 473,159 522,147 571,135 629,129 697,129 754,129 806,134 853,144 900,153 941,168 975,188 1009,208 1036,234 1055,266 1074,297 1083,335 1083,379 1083,425 1073,462 1052,491 1031,520 1001,543 963,562 925,581 880,596 827,609 774,622 716,635 652,650 613,659 573,668 534,679 494,689 456,701 420,716 383,730 349,747 317,766 285,785 257,809 234,836 211,863 192,894 179,930 166,965 159,1006 159,1053 159,1120 173,1177 200,1225 227,1272 264,1311 312,1342 360,1373 417,1395 482,1409 547,1423 618,1430 694,1430 781,1430 856,1423 918,1410 980,1396 1032,1375 1075,1348 1118,1321 1152,1287 1178,1247 1203,1206 1224,1159 1239,1106 L 1051,1073 C 1042,1107 1028,1137 1011,1164 993,1191 970,1213 941,1231 912,1249 878,1263 837,1272 796,1281 747,1286 692,1286 627,1286 572,1280 528,1269 483,1257 448,1241 421,1221 394,1201 374,1178 363,1151 351,1124 345,1094 345,1063 345,1021 356,987 377,960 398,933 426,910 462,892 498,874 540,859 587,847 634,835 685,823 738,811 781,801 825,791 868,781 911,770 952,758 991,744 1030,729 1067,712 1102,693 1136,674 1166,650 1191,622 1216,594 1236,561 1251,523 1265,485 1272,440 1272,389 Z"/>
+ <glyph unicode="P" horiz-adv-x="1112" d="M 1258,985 C 1258,924 1248,867 1228,814 1207,761 1177,715 1137,676 1096,637 1046,606 985,583 924,560 854,549 773,549 L 359,549 359,0 168,0 168,1409 761,1409 C 844,1409 917,1399 979,1379 1041,1358 1093,1330 1134,1293 1175,1256 1206,1211 1227,1159 1248,1106 1258,1048 1258,985 Z M 1066,983 C 1066,1072 1039,1140 984,1187 929,1233 847,1256 738,1256 L 359,1256 359,700 746,700 C 856,700 937,724 989,773 1040,822 1066,892 1066,983 Z"/>
+ <glyph unicode="O" horiz-adv-x="1430" d="M 1495,711 C 1495,601 1479,501 1448,411 1416,321 1370,244 1310,180 1250,116 1177,67 1090,32 1003,-3 905,-20 795,-20 679,-20 577,-2 490,35 403,71 330,122 272,187 214,252 170,329 141,418 112,507 97,605 97,711 97,821 112,920 143,1009 174,1098 219,1173 278,1236 337,1298 411,1346 498,1380 585,1413 684,1430 797,1430 909,1430 1009,1413 1096,1379 1183,1345 1256,1297 1315,1234 1374,1171 1418,1096 1449,1007 1480,918 1495,820 1495,711 Z M 1300,711 C 1300,796 1289,873 1268,942 1246,1011 1214,1071 1172,1120 1129,1169 1077,1207 1014,1234 951,1261 879,1274 797,1274 713,1274 639,1261 576,1234 513,1207 460,1169 418,1120 375,1071 344,1011 323,942 302,873 291,796 291,711 291,626 302,549 324,479 345,408 377,348 420,297 462,246 515,206 578,178 641,149 713,135 795,135 883,135 959,149 1023,178 1086,207 1139,247 1180,298 1221,349 1251,409 1271,480 1290,551 1300,628 1300,711 Z"/>
+ <glyph unicode="N" horiz-adv-x="1165" d="M 1082,0 L 328,1200 C 329,1167 331,1135 333,1103 334,1076 336,1047 337,1017 338,986 338,959 338,936 L 338,0 168,0 168,1409 390,1409 1152,201 C 1150,234 1148,266 1146,299 1145,327 1143,358 1142,391 1141,424 1140,455 1140,485 L 1140,1409 1312,1409 1312,0 1082,0 Z"/>
+ <glyph unicode="M" horiz-adv-x="1377" d="M 1366,0 L 1366,940 C 1366,974 1366,1009 1367,1044 1368,1079 1369,1112 1370,1141 1371,1175 1373,1208 1375,1240 1366,1206 1356,1172 1346,1139 1337,1110 1328,1080 1318,1048 1307,1015 1297,986 1287,960 L 923,0 789,0 420,960 C 416,970 412,982 408,995 403,1008 399,1023 394,1038 389,1053 384,1068 379,1084 374,1099 369,1115 364,1130 353,1165 342,1202 331,1240 332,1203 333,1166 334,1129 335,1098 336,1065 337,1031 338,996 338,966 338,940 L 338,0 168,0 168,1409 419,1409 794,432 C 799,419 804,402 811,381 818,360 824,338 830,316 836,294 842,273 847,254 852,234 855,219 857,208 859,219 863,234 868,254 873,274 880,295 887,317 894,339 900,360 907,381 914,402 920,419 925,432 L 1293,1409 1538,1409 1538,0 1366,0 Z"/>
+ <glyph unicode="L" horiz-adv-x="927" d="M 168,0 L 168,1409 359,1409 359,156 1071,156 1071,0 168,0 Z"/>
+ <glyph unicode="I" horiz-adv-x="213" d="M 189,0 L 189,1409 380,1409 380,0 189,0 Z"/>
+ <glyph unicode="G" horiz-adv-x="1377" d="M 103,711 C 103,821 118,920 148,1009 177,1098 222,1173 281,1236 340,1298 413,1346 500,1380 587,1413 689,1430 804,1430 891,1430 967,1422 1032,1407 1097,1392 1154,1370 1202,1341 1250,1312 1291,1278 1324,1237 1357,1196 1386,1149 1409,1098 L 1227,1044 C 1210,1079 1189,1110 1165,1139 1140,1167 1111,1191 1076,1211 1041,1231 1001,1247 956,1258 910,1269 858,1274 799,1274 714,1274 640,1261 577,1234 514,1207 461,1169 420,1120 379,1071 348,1011 328,942 307,873 297,796 297,711 297,626 308,549 330,479 352,408 385,348 428,297 471,246 525,206 590,178 654,149 728,135 813,135 868,135 919,140 966,149 1013,158 1055,171 1093,186 1130,201 1163,217 1192,236 1221,254 1245,272 1264,291 L 1264,545 843,545 843,705 1440,705 1440,219 C 1409,187 1372,157 1330,128 1287,99 1240,73 1187,51 1134,29 1077,12 1014,-1 951,-14 884,-20 813,-20 694,-20 591,-2 502,35 413,71 340,122 281,187 222,252 177,329 148,418 118,507 103,605 103,711 Z"/>
+ <glyph unicode="F" horiz-adv-x="1006" d="M 359,1253 L 359,729 1145,729 1145,571 359,571 359,0 168,0 168,1409 1169,1409 1169,1253 359,1253 Z"/>
+ <glyph unicode="E" horiz-adv-x="1138" d="M 168,0 L 168,1409 1237,1409 1237,1253 359,1253 359,801 1177,801 1177,647 359,647 359,156 1278,156 1278,0 168,0 Z"/>
+ <glyph unicode="D" horiz-adv-x="1218" d="M 1381,719 C 1381,602 1363,498 1328,409 1293,319 1244,244 1183,184 1122,123 1049,78 966,47 882,16 792,0 695,0 L 168,0 168,1409 634,1409 C 743,1409 843,1396 935,1369 1026,1342 1105,1300 1171,1244 1237,1187 1289,1116 1326,1029 1363,942 1381,839 1381,719 Z M 1189,719 C 1189,814 1175,896 1148,964 1121,1031 1082,1087 1033,1130 984,1173 925,1205 856,1226 787,1246 712,1256 630,1256 L 359,1256 359,153 673,153 C 747,153 816,165 879,189 942,213 996,249 1042,296 1088,343 1124,402 1150,473 1176,544 1189,626 1189,719 Z"/>
+ <glyph unicode="C" horiz-adv-x="1324" d="M 792,1274 C 712,1274 641,1261 580,1234 518,1207 466,1169 425,1120 383,1071 351,1011 330,942 309,873 298,796 298,711 298,626 310,549 333,479 356,408 389,348 432,297 475,246 527,207 590,179 652,151 722,137 800,137 855,137 905,144 950,159 995,173 1035,193 1072,219 1108,245 1140,276 1169,312 1198,347 1223,387 1245,430 L 1401,352 C 1376,299 1344,250 1307,205 1270,160 1226,120 1176,87 1125,54 1068,28 1005,9 941,-10 870,-20 791,-20 677,-20 577,-2 492,35 406,71 334,122 277,187 219,252 176,329 147,418 118,507 104,605 104,711 104,821 119,920 150,1009 180,1098 224,1173 283,1236 341,1298 413,1346 498,1380 583,1413 681,1430 790,1430 940,1430 1065,1401 1166,1342 1267,1283 1341,1196 1388,1081 L 1207,1021 C 1194,1054 1176,1086 1153,1117 1130,1147 1102,1174 1068,1197 1034,1220 994,1239 949,1253 903,1267 851,1274 792,1274 Z"/>
+ <glyph unicode="B" horiz-adv-x="1112" d="M 1258,397 C 1258,326 1244,265 1216,215 1188,164 1150,123 1103,92 1056,60 1001,37 938,22 875,7 809,0 740,0 L 168,0 168,1409 680,1409 C 758,1409 828,1403 889,1390 950,1377 1002,1356 1045,1328 1088,1300 1120,1265 1143,1222 1165,1179 1176,1127 1176,1067 1176,1028 1171,991 1160,956 1149,921 1132,890 1110,862 1087,833 1059,809 1026,789 992,768 953,753 908,743 965,736 1015,723 1059,704 1102,685 1139,660 1168,630 1197,600 1220,565 1235,526 1250,486 1258,443 1258,397 Z M 984,1044 C 984,1120 958,1174 906,1207 854,1240 779,1256 680,1256 L 359,1256 359,810 680,810 C 736,810 783,816 822,827 861,838 892,853 916,874 940,894 957,918 968,947 979,976 984,1008 984,1044 Z M 1065,412 C 1065,457 1057,495 1041,526 1024,557 1001,583 970,603 939,623 903,638 860,647 817,656 768,661 715,661 L 359,661 359,153 730,153 C 779,153 824,157 865,165 906,173 941,187 971,207 1000,227 1023,254 1040,287 1057,320 1065,362 1065,412 Z"/>
+ <glyph unicode="A" horiz-adv-x="1377" d="M 1167,0 L 1006,412 364,412 202,0 4,0 579,1409 796,1409 1362,0 1167,0 Z M 768,1026 C 757,1053 747,1080 738,1107 728,1134 719,1159 712,1182 705,1204 699,1223 694,1238 689,1253 686,1262 685,1265 684,1262 681,1252 676,1237 671,1222 665,1203 658,1180 650,1157 641,1132 632,1105 622,1078 612,1051 602,1024 L 422,561 949,561 768,1026 Z"/>
+ <glyph unicode="-" horiz-adv-x="531" d="M 91,464 L 91,624 591,624 591,464 91,464 Z"/>
+ <glyph unicode=" " horiz-adv-x="556"/>
+ </font>
+ </defs>
+ <defs class="TextShapeIndex">
+ <g ooo:slide="id1" ooo:id-list="id3 id4 id5 id6 id7 id8 id9"/>
+ </defs>
+ <defs class="EmbeddedBulletChars">
+ <g id="bullet-char-template(57356)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
+ </g>
+ <g id="bullet-char-template(57354)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
+ </g>
+ <g id="bullet-char-template(10146)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
+ </g>
+ <g id="bullet-char-template(10132)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
+ </g>
+ <g id="bullet-char-template(10007)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
+ </g>
+ <g id="bullet-char-template(10004)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
+ </g>
+ <g id="bullet-char-template(9679)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
+ </g>
+ <g id="bullet-char-template(8226)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
+ </g>
+ <g id="bullet-char-template(8211)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
+ </g>
+ </defs>
+ <defs class="TextEmbeddedBitmaps"/>
+ <g class="SlideGroup">
+ <g>
+ <g id="id1" class="Slide" clip-path="url(#presentation_clip_path)">
+ <g class="Page">
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id3">
+ <rect class="BoundingBox" stroke="none" fill="none" x="4809" y="11159" width="11433" height="7623"/>
+ <path fill="rgb(153,204,255)" stroke="none" d="M 10525,18780 L 4810,18780 4810,11160 16240,11160 16240,18780 10525,18780 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 10525,18780 L 4810,18780 4810,11160 16240,11160 16240,18780 10525,18780 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="564px" font-weight="400"><tspan class="TextPosition" x="7496" y="11793"><tspan fill="rgb(0,0,0)" stroke="none">Isolated security context</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id4">
+ <rect class="BoundingBox" stroke="none" fill="none" x="6079" y="12428" width="8893" height="1400"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 10525,13826 L 6080,13826 6080,12429 14970,12429 14970,13826 10525,13826 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 10525,13826 L 6080,13826 6080,12429 14970,12429 14970,13826 10525,13826 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="8451" y="13348"><tspan fill="rgb(0,0,0)" stroke="none">APPLICATION</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id5">
+ <rect class="BoundingBox" stroke="none" fill="none" x="6079" y="14969" width="6353" height="2543"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 9255,17510 L 6080,17510 6080,14970 12430,14970 12430,17510 9255,17510 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 9255,17510 L 6080,17510 6080,14970 12430,14970 12430,17510 9255,17510 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="8377" y="16105"><tspan fill="rgb(0,0,0)" stroke="none">binder</tspan></tspan></tspan><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="7139" y="16816"><tspan fill="rgb(0,0,0)" stroke="none">AFB-DAEMON</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.CustomShape">
+ <g id="id6">
+ <rect class="BoundingBox" stroke="none" fill="none" x="12429" y="14969" width="2543" height="2543"/>
+ <path fill="rgb(114,159,207)" stroke="none" d="M 13700,17510 L 12430,17510 12430,14970 14970,14970 14970,17510 13700,17510 Z"/>
+ <path fill="none" stroke="rgb(52,101,164)" d="M 13700,17510 L 12430,17510 12430,14970 14970,14970 14970,17510 13700,17510 Z"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="493px" font-weight="400"><tspan class="TextPosition" x="12514" y="16410"><tspan fill="rgb(0,0,0)" stroke="none">BINDINGS</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.TextShape">
+ <g id="id7">
+ <rect class="BoundingBox" stroke="none" fill="none" x="8620" y="20177" width="4954" height="1144"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="8870" y="20878"><tspan fill="rgb(0,0,0)" stroke="none">AGL SYSTEM</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id8">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10651" y="13826" width="3" height="1146"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10652,13827 L 10652,14970"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id9">
+ <rect class="BoundingBox" stroke="none" fill="none" x="10495" y="17508" width="301" height="2542"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 10645,17509 L 10645,19619"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 10645,20049 L 10795,19599 10495,19599 10645,20049 Z"/>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/doc/signaling-basis.svg b/doc/pictures/signaling-basis.svg
index b13fcf17..b13fcf17 100644
--- a/doc/signaling-basis.svg
+++ b/doc/pictures/signaling-basis.svg
diff --git a/doc/pictures/tic-tac-toe.svg b/doc/pictures/tic-tac-toe.svg
new file mode 100644
index 00000000..7a5fb84e
--- /dev/null
+++ b/doc/pictures/tic-tac-toe.svg
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.2" width="139.79mm" height="124.79mm" viewBox="1000 1235 13979 12479" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve">
+ <defs class="ClipPathGroup">
+ <clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse">
+ <rect x="1000" y="1235" width="13979" height="12479"/>
+ </clipPath>
+ </defs>
+ <defs>
+ <font id="EmbeddedFont_1" horiz-adv-x="2048">
+ <font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1852" descent="423"/>
+ <missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/>
+ <glyph unicode="w" horiz-adv-x="1509" d="M 1174,0 L 965,0 792,698 C 787,716 781,738 776,765 770,792 764,818 759,843 752,872 746,903 740,934 734,904 728,874 721,845 716,820 710,793 704,766 697,739 691,715 686,694 L 508,0 300,0 -3,1082 175,1082 358,347 C 363,332 367,313 372,291 377,268 381,246 386,225 391,200 396,175 401,149 406,174 412,199 418,223 423,244 429,265 434,286 439,307 444,325 448,339 L 644,1082 837,1082 1026,339 C 1031,322 1036,302 1041,280 1046,258 1051,237 1056,218 1061,195 1067,172 1072,149 1077,174 1083,199 1088,223 1093,244 1098,265 1103,288 1108,310 1112,330 1117,347 L 1308,1082 1484,1082 1174,0 Z"/>
+ <glyph unicode="v" horiz-adv-x="1033" d="M 613,0 L 400,0 7,1082 199,1082 437,378 C 442,363 447,346 454,325 460,304 466,282 473,259 480,236 486,215 492,194 497,173 502,155 506,141 510,155 515,173 522,194 528,215 534,236 541,258 548,280 555,302 562,323 569,344 575,361 580,376 L 826,1082 1017,1082 613,0 Z"/>
+ <glyph unicode="u" horiz-adv-x="874" d="M 314,1082 L 314,396 C 314,343 318,299 326,264 333,229 346,200 363,179 380,157 403,142 432,133 460,124 495,119 537,119 580,119 618,127 653,142 687,157 716,178 741,207 765,235 784,270 797,312 810,353 817,401 817,455 L 817,1082 997,1082 997,228 C 997,205 997,181 998,156 998,131 998,107 999,85 1000,62 1000,43 1001,27 1002,11 1002,3 1003,3 L 833,3 C 832,6 832,15 831,30 830,44 830,61 829,79 828,98 827,117 826,136 825,156 825,172 825,185 L 822,185 C 805,154 786,125 765,100 744,75 720,53 693,36 666,18 634,4 599,-6 564,-15 523,-20 476,-20 416,-20 364,-13 321,2 278,17 242,39 214,70 186,101 166,140 153,188 140,236 133,294 133,361 L 133,1082 314,1082 Z"/>
+ <glyph unicode="t" horiz-adv-x="531" d="M 554,8 C 527,1 499,-5 471,-10 442,-14 409,-16 372,-16 228,-16 156,66 156,229 L 156,951 31,951 31,1082 163,1082 216,1324 336,1324 336,1082 536,1082 536,951 336,951 336,268 C 336,216 345,180 362,159 379,138 408,127 450,127 467,127 484,128 501,131 517,134 535,137 554,141 L 554,8 Z"/>
+ <glyph unicode="s" horiz-adv-x="901" d="M 950,299 C 950,248 940,203 921,164 901,124 872,91 835,64 798,37 752,16 698,2 643,-13 581,-20 511,-20 448,-20 392,-15 342,-6 291,4 247,20 209,41 171,62 139,91 114,126 88,161 69,203 57,254 L 216,285 C 231,227 263,185 311,158 359,131 426,117 511,117 550,117 585,120 618,125 650,130 678,140 701,153 724,166 743,183 756,205 769,226 775,253 775,285 775,318 767,345 752,366 737,387 715,404 688,418 661,432 628,444 589,455 550,465 507,476 460,489 417,500 374,513 331,527 288,541 250,560 216,583 181,606 153,634 132,668 111,702 100,745 100,796 100,895 135,970 206,1022 276,1073 378,1099 513,1099 632,1099 727,1078 798,1036 868,994 912,927 931,834 L 769,814 C 763,842 752,866 736,885 720,904 701,919 678,931 655,942 630,951 602,956 573,961 544,963 513,963 432,963 372,951 333,926 294,901 275,864 275,814 275,785 282,761 297,742 311,723 331,707 357,694 382,681 413,669 449,660 485,650 525,640 568,629 597,622 626,614 656,606 686,597 715,587 744,576 772,564 799,550 824,535 849,519 870,500 889,478 908,456 923,430 934,401 945,372 950,338 950,299 Z"/>
+ <glyph unicode="o" horiz-adv-x="980" d="M 1053,542 C 1053,353 1011,212 928,119 845,26 724,-20 565,-20 490,-20 422,-9 363,14 304,37 254,71 213,118 172,165 140,223 119,294 97,364 86,447 86,542 86,915 248,1102 571,1102 655,1102 728,1090 789,1067 850,1044 900,1009 939,962 978,915 1006,857 1025,787 1044,717 1053,635 1053,542 Z M 864,542 C 864,626 858,695 845,750 832,805 813,848 788,881 763,914 732,937 696,950 660,963 619,969 574,969 528,969 487,962 450,949 413,935 381,912 355,879 329,846 309,802 296,747 282,692 275,624 275,542 275,458 282,389 297,334 312,279 332,235 358,202 383,169 414,146 449,133 484,120 522,113 563,113 609,113 651,120 688,133 725,146 757,168 783,201 809,234 829,278 843,333 857,388 864,458 864,542 Z"/>
+ <glyph unicode="n" horiz-adv-x="874" d="M 825,0 L 825,686 C 825,739 821,783 814,818 806,853 793,882 776,904 759,925 736,941 708,950 679,959 644,963 602,963 559,963 521,956 487,941 452,926 423,904 399,876 374,847 355,812 342,771 329,729 322,681 322,627 L 322,0 142,0 142,853 C 142,876 142,900 142,925 141,950 141,974 140,996 139,1019 139,1038 138,1054 137,1070 137,1078 136,1078 L 306,1078 C 307,1075 307,1066 308,1052 309,1037 310,1021 311,1002 312,984 312,965 313,945 314,926 314,910 314,897 L 317,897 C 334,928 353,957 374,982 395,1007 419,1029 446,1047 473,1064 505,1078 540,1088 575,1097 616,1102 663,1102 723,1102 775,1095 818,1080 861,1065 897,1043 925,1012 953,981 974,942 987,894 1000,845 1006,788 1006,721 L 1006,0 825,0 Z"/>
+ <glyph unicode="m" horiz-adv-x="1457" d="M 768,0 L 768,686 C 768,739 765,783 758,818 751,853 740,882 725,904 709,925 688,941 663,950 638,959 607,963 570,963 532,963 498,956 467,941 436,926 410,904 389,876 367,847 350,812 339,771 327,729 321,681 321,627 L 321,0 142,0 142,853 C 142,876 142,900 142,925 141,950 141,974 140,996 139,1019 139,1038 138,1054 137,1070 137,1078 136,1078 L 306,1078 C 307,1075 307,1066 308,1052 309,1037 310,1021 311,1002 312,984 312,965 313,945 314,926 314,910 314,897 L 317,897 C 333,928 350,957 369,982 388,1007 410,1029 435,1047 460,1064 488,1078 521,1088 553,1097 590,1102 633,1102 715,1102 780,1086 828,1053 875,1020 908,968 927,897 L 930,897 C 946,928 964,957 984,982 1004,1007 1027,1029 1054,1047 1081,1064 1111,1078 1144,1088 1177,1097 1215,1102 1258,1102 1313,1102 1360,1095 1400,1080 1439,1065 1472,1043 1497,1012 1522,981 1541,942 1553,894 1565,845 1571,788 1571,721 L 1571,0 1393,0 1393,686 C 1393,739 1390,783 1383,818 1376,853 1365,882 1350,904 1334,925 1313,941 1288,950 1263,959 1232,963 1195,963 1157,963 1123,956 1092,942 1061,927 1035,906 1014,878 992,850 975,815 964,773 952,731 946,682 946,627 L 946,0 768,0 Z"/>
+ <glyph unicode="l" horiz-adv-x="187" d="M 138,0 L 138,1484 318,1484 318,0 138,0 Z"/>
+ <glyph unicode="i" horiz-adv-x="187" d="M 137,1312 L 137,1484 317,1484 317,1312 137,1312 Z M 137,0 L 137,1082 317,1082 317,0 137,0 Z"/>
+ <glyph unicode="f" horiz-adv-x="557" d="M 361,951 L 361,0 181,0 181,951 29,951 29,1082 181,1082 181,1204 C 181,1243 185,1280 192,1314 199,1347 213,1377 233,1402 252,1427 279,1446 313,1461 347,1475 391,1482 445,1482 466,1482 489,1481 512,1479 535,1477 555,1474 572,1470 L 572,1333 C 561,1335 548,1337 533,1339 518,1340 504,1341 492,1341 465,1341 444,1337 427,1330 410,1323 396,1312 387,1299 377,1285 370,1268 367,1248 363,1228 361,1205 361,1179 L 361,1082 572,1082 572,951 361,951 Z"/>
+ <glyph unicode="e" horiz-adv-x="980" d="M 276,503 C 276,446 282,394 294,347 305,299 323,258 348,224 372,189 403,163 441,144 479,125 525,115 578,115 656,115 719,131 766,162 813,193 844,233 861,281 L 1019,236 C 1008,206 992,176 972,146 951,115 924,88 890,64 856,39 814,19 763,4 712,-12 650,-20 578,-20 418,-20 296,28 213,123 129,218 87,360 87,548 87,649 100,735 125,806 150,876 185,933 229,977 273,1021 324,1053 383,1073 442,1092 504,1102 571,1102 662,1102 738,1087 799,1058 860,1029 909,988 946,937 983,885 1009,824 1025,754 1040,684 1048,608 1048,527 L 1048,503 276,503 Z M 862,641 C 852,755 823,838 775,891 727,943 658,969 568,969 538,969 507,964 474,955 441,945 410,928 382,903 354,878 330,845 311,803 292,760 281,706 278,641 L 862,641 Z"/>
+ <glyph unicode="c" horiz-adv-x="901" d="M 275,546 C 275,484 280,427 289,375 298,323 313,278 334,241 355,203 384,174 419,153 454,132 497,122 548,122 612,122 666,139 709,173 752,206 778,258 788,328 L 970,328 C 964,283 951,239 931,197 911,155 884,118 850,86 815,54 773,28 724,9 675,-10 618,-20 553,-20 468,-20 396,-6 337,23 278,52 230,91 193,142 156,192 129,251 112,320 95,388 87,462 87,542 87,615 93,679 105,735 117,790 134,839 156,881 177,922 203,957 232,986 261,1014 293,1037 328,1054 362,1071 398,1083 436,1091 474,1098 512,1102 551,1102 612,1102 666,1094 713,1077 760,1060 801,1038 836,1009 870,980 898,945 919,906 940,867 955,824 964,779 L 779,765 C 770,825 746,873 708,908 670,943 616,961 546,961 495,961 452,953 418,936 383,919 355,893 334,859 313,824 298,781 289,729 280,677 275,616 275,546 Z"/>
+ <glyph unicode="a" horiz-adv-x="1060" d="M 414,-20 C 305,-20 224,9 169,66 114,124 87,203 87,303 87,375 101,434 128,480 155,526 190,562 234,588 277,614 327,632 383,642 439,652 496,657 554,657 L 797,657 797,717 C 797,762 792,800 783,832 774,863 759,889 740,908 721,928 697,942 668,951 639,960 604,965 565,965 530,965 499,963 471,958 443,953 419,944 398,931 377,918 361,900 348,878 335,855 327,827 323,793 L 135,810 C 142,853 154,892 173,928 192,963 218,994 253,1020 287,1046 330,1066 382,1081 433,1095 496,1102 569,1102 705,1102 807,1071 876,1009 945,946 979,856 979,738 L 979,272 C 979,219 986,179 1000,152 1014,125 1041,111 1080,111 1090,111 1100,112 1110,113 1120,114 1130,116 1139,118 L 1139,6 C 1116,1 1094,-3 1072,-6 1049,-9 1025,-10 1000,-10 966,-10 937,-5 913,4 888,13 868,26 853,45 838,63 826,86 818,113 810,140 805,171 803,207 L 797,207 C 778,172 757,141 734,113 711,85 684,61 653,42 622,22 588,7 549,-4 510,-15 465,-20 414,-20 Z M 455,115 C 512,115 563,125 606,146 649,167 684,194 713,226 741,259 762,294 776,332 790,371 797,408 797,443 L 797,531 600,531 C 556,531 514,528 475,522 435,517 400,506 370,489 340,472 316,449 299,418 281,388 272,349 272,300 272,241 288,195 320,163 351,131 396,115 455,115 Z"/>
+ <glyph unicode="T" horiz-adv-x="1192" d="M 720,1253 L 720,0 530,0 530,1253 46,1253 46,1409 1204,1409 1204,1253 720,1253 Z"/>
+ <glyph unicode="C" horiz-adv-x="1324" d="M 792,1274 C 712,1274 641,1261 580,1234 518,1207 466,1169 425,1120 383,1071 351,1011 330,942 309,873 298,796 298,711 298,626 310,549 333,479 356,408 389,348 432,297 475,246 527,207 590,179 652,151 722,137 800,137 855,137 905,144 950,159 995,173 1035,193 1072,219 1108,245 1140,276 1169,312 1198,347 1223,387 1245,430 L 1401,352 C 1376,299 1344,250 1307,205 1270,160 1226,120 1176,87 1125,54 1068,28 1005,9 941,-10 870,-20 791,-20 677,-20 577,-2 492,35 406,71 334,122 277,187 219,252 176,329 147,418 118,507 104,605 104,711 104,821 119,920 150,1009 180,1098 224,1173 283,1236 341,1298 413,1346 498,1380 583,1413 681,1430 790,1430 940,1430 1065,1401 1166,1342 1267,1283 1341,1196 1388,1081 L 1207,1021 C 1194,1054 1176,1086 1153,1117 1130,1147 1102,1174 1068,1197 1034,1220 994,1239 949,1253 903,1267 851,1274 792,1274 Z"/>
+ <glyph unicode="B" horiz-adv-x="1112" d="M 1258,397 C 1258,326 1244,265 1216,215 1188,164 1150,123 1103,92 1056,60 1001,37 938,22 875,7 809,0 740,0 L 168,0 168,1409 680,1409 C 758,1409 828,1403 889,1390 950,1377 1002,1356 1045,1328 1088,1300 1120,1265 1143,1222 1165,1179 1176,1127 1176,1067 1176,1028 1171,991 1160,956 1149,921 1132,890 1110,862 1087,833 1059,809 1026,789 992,768 953,753 908,743 965,736 1015,723 1059,704 1102,685 1139,660 1168,630 1197,600 1220,565 1235,526 1250,486 1258,443 1258,397 Z M 984,1044 C 984,1120 958,1174 906,1207 854,1240 779,1256 680,1256 L 359,1256 359,810 680,810 C 736,810 783,816 822,827 861,838 892,853 916,874 940,894 957,918 968,947 979,976 984,1008 984,1044 Z M 1065,412 C 1065,457 1057,495 1041,526 1024,557 1001,583 970,603 939,623 903,638 860,647 817,656 768,661 715,661 L 359,661 359,153 730,153 C 779,153 824,157 865,165 906,173 941,187 971,207 1000,227 1023,254 1040,287 1057,320 1065,362 1065,412 Z"/>
+ <glyph unicode="A" horiz-adv-x="1377" d="M 1167,0 L 1006,412 364,412 202,0 4,0 579,1409 796,1409 1362,0 1167,0 Z M 768,1026 C 757,1053 747,1080 738,1107 728,1134 719,1159 712,1182 705,1204 699,1223 694,1238 689,1253 686,1262 685,1265 684,1262 681,1252 676,1237 671,1222 665,1203 658,1180 650,1157 641,1132 632,1105 622,1078 612,1051 602,1024 L 422,561 949,561 768,1026 Z"/>
+ <glyph unicode="-" horiz-adv-x="531" d="M 91,464 L 91,624 591,624 591,464 91,464 Z"/>
+ <glyph unicode=" " horiz-adv-x="556"/>
+ </font>
+ </defs>
+ <defs class="TextShapeIndex">
+ <g ooo:slide="id1" ooo:id-list="id3 id4 id5 id6 id7 id8 id9 id10 id11 id12 id13 id14 id15 id16 id17 id18 id19 id20 id21 id22 id23 id24"/>
+ </defs>
+ <defs class="EmbeddedBulletChars">
+ <g id="bullet-char-template(57356)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/>
+ </g>
+ <g id="bullet-char-template(57354)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/>
+ </g>
+ <g id="bullet-char-template(10146)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/>
+ </g>
+ <g id="bullet-char-template(10132)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/>
+ </g>
+ <g id="bullet-char-template(10007)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/>
+ </g>
+ <g id="bullet-char-template(10004)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/>
+ </g>
+ <g id="bullet-char-template(9679)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/>
+ </g>
+ <g id="bullet-char-template(8226)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/>
+ </g>
+ <g id="bullet-char-template(8211)" transform="scale(0.00048828125,-0.00048828125)">
+ <path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/>
+ </g>
+ </defs>
+ <defs class="TextEmbeddedBitmaps"/>
+ <g class="SlideGroup">
+ <g>
+ <g id="id1" class="Slide" clip-path="url(#presentation_clip_path)">
+ <g class="Page">
+ <g class="Group">
+ <g class="com.sun.star.drawing.ConnectorShape">
+ <g id="id3">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2235" y="2235" width="29" height="3809"/>
+ <path fill="none" stroke="rgb(52,101,164)" stroke-width="28" stroke-linejoin="round" d="M 2249,2249 L 2249,6029"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.ConnectorShape">
+ <g id="id4">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2254" y="8606" width="31" height="5073"/>
+ <path fill="none" stroke="rgb(52,101,164)" stroke-width="28" stroke-linejoin="round" d="M 2270,8620 L 2270,11142 2268,11142 2268,13664"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id5">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2269" y="6079" width="3" height="2543"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,6080 L 2270,6133"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,6186 L 2270,6239"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,6292 L 2270,6345"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,6399 L 2270,6452"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,6505 L 2270,6558"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,6611 L 2270,6664"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,6717 L 2270,6770"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,6823 L 2270,6876"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,6929 L 2270,6983"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7036 L 2270,7089"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7142 L 2270,7195"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7248 L 2270,7301"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7354 L 2270,7407"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7460 L 2270,7513"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7567 L 2270,7620"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7673 L 2270,7726"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7779 L 2270,7832"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7885 L 2270,7938"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,7991 L 2270,8044"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,8097 L 2270,8151"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,8204 L 2270,8257"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,8310 L 2270,8363"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,8416 L 2270,8469"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,8522 L 2270,8575"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.TextShape">
+ <g id="id6">
+ <rect class="BoundingBox" stroke="none" fill="none" x="1000" y="1254" width="2795" height="1017"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="1250" y="1955"><tspan fill="rgb(0,0,0)" stroke="none">Client A</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ </g>
+ <g class="Group">
+ <g class="com.sun.star.drawing.ConnectorShape">
+ <g id="id7">
+ <rect class="BoundingBox" stroke="none" fill="none" x="6066" y="2256" width="29" height="3809"/>
+ <path fill="none" stroke="rgb(52,101,164)" stroke-width="28" stroke-linejoin="round" d="M 6080,2270 L 6080,6050"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.ConnectorShape">
+ <g id="id8">
+ <rect class="BoundingBox" stroke="none" fill="none" x="6066" y="8641" width="34" height="5074"/>
+ <path fill="none" stroke="rgb(52,101,164)" stroke-width="28" stroke-linejoin="round" d="M 6085,8655 L 6085,11178 6080,11178 6080,13700"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id9">
+ <rect class="BoundingBox" stroke="none" fill="none" x="6079" y="6079" width="3" height="2543"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,6080 L 6080,6133"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,6186 L 6080,6239"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,6292 L 6080,6345"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,6399 L 6080,6452"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,6505 L 6080,6558"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,6611 L 6080,6664"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,6717 L 6080,6770"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,6823 L 6080,6876"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,6929 L 6080,6983"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7036 L 6080,7089"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7142 L 6080,7195"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7248 L 6080,7301"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7354 L 6080,7407"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7460 L 6080,7513"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7567 L 6080,7620"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7673 L 6080,7726"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7779 L 6080,7832"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7885 L 6080,7938"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,7991 L 6080,8044"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,8097 L 6080,8151"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,8204 L 6080,8257"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,8310 L 6080,8363"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,8416 L 6080,8469"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,8522 L 6080,8575"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.TextShape">
+ <g id="id10">
+ <rect class="BoundingBox" stroke="none" fill="none" x="4683" y="1254" width="2795" height="1017"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="4933" y="1955"><tspan fill="rgb(0,0,0)" stroke="none">Client B</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ </g>
+ <g class="Group">
+ <g class="com.sun.star.drawing.ConnectorShape">
+ <g id="id11">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9876" y="2286" width="29" height="3809"/>
+ <path fill="none" stroke="rgb(52,101,164)" stroke-width="28" stroke-linejoin="round" d="M 9890,2300 L 9890,6080"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.ConnectorShape">
+ <g id="id12">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9870" y="8606" width="35" height="5092"/>
+ <path fill="none" stroke="rgb(52,101,164)" stroke-width="28" stroke-linejoin="round" d="M 9890,8620 L 9890,11152 9884,11152 9884,13683"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id13">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9889" y="6079" width="3" height="2543"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,6080 L 9890,6133"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,6186 L 9890,6239"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,6292 L 9890,6345"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,6399 L 9890,6452"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,6505 L 9890,6558"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,6611 L 9890,6664"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,6717 L 9890,6770"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,6823 L 9890,6876"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,6929 L 9890,6983"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7036 L 9890,7089"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7142 L 9890,7195"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7248 L 9890,7301"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7354 L 9890,7407"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7460 L 9890,7513"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7567 L 9890,7620"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7673 L 9890,7726"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7779 L 9890,7832"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7885 L 9890,7938"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,7991 L 9890,8044"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,8097 L 9890,8151"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,8204 L 9890,8257"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,8310 L 9890,8363"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,8416 L 9890,8469"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,8522 L 9890,8575"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.TextShape">
+ <g id="id14">
+ <rect class="BoundingBox" stroke="none" fill="none" x="8061" y="1235" width="3811" height="963"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="8311" y="1936"><tspan fill="rgb(0,0,0)" stroke="none">Tic-Tac-Toe</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id15">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2269" y="4025" width="7622" height="301"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 2270,4175 L 9460,4175"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 9890,4175 L 9440,4025 9440,4325 9890,4175 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id16">
+ <rect class="BoundingBox" stroke="none" fill="none" x="6079" y="9105" width="3812" height="301"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 6080,9255 L 9460,9255"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 9890,9255 L 9440,9105 9440,9405 9890,9255 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id17">
+ <rect class="BoundingBox" stroke="none" fill="none" x="6080" y="11010" width="3812" height="301"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,11160 L 6510,11160"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 6080,11160 L 6530,11310 6530,11010 6080,11160 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.LineShape">
+ <g id="id18">
+ <rect class="BoundingBox" stroke="none" fill="none" x="2270" y="12915" width="7622" height="301"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 9890,13065 L 2700,13065"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 2270,13065 L 2720,13215 2720,12915 2270,13065 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.TextShape">
+ <g id="id19">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9890" y="8874" width="1779" height="764"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="458px" font-weight="400"><tspan class="TextPosition" x="10140" y="9414"><tspan fill="rgb(0,0,0)" stroke="none">move</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.TextShape">
+ <g id="id20">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9890" y="3794" width="1398" height="764"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="458px" font-weight="400"><tspan class="TextPosition" x="10140" y="4334"><tspan fill="rgb(0,0,0)" stroke="none">wait</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.TextShape">
+ <g id="id21">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9890" y="10779" width="4573" height="764"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="458px" font-weight="400"><tspan class="TextPosition" x="10140" y="11319"><tspan fill="rgb(0,0,0)" stroke="none">success of move</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.TextShape">
+ <g id="id22">
+ <rect class="BoundingBox" stroke="none" fill="none" x="9890" y="12684" width="3684" height="764"/>
+ <text class="TextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="458px" font-weight="400"><tspan class="TextPosition" x="10140" y="13224"><tspan fill="rgb(0,0,0)" stroke="none">success of wait</tspan></tspan></tspan></text>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.ConnectorShape">
+ <g id="id23">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11667" y="9254" width="660" height="1526"/>
+ <path fill="none" stroke="rgb(0,0,0)" d="M 11668,9255 L 12176,9255 12176,10349"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 12176,10779 L 12326,10329 12026,10329 12176,10779 Z"/>
+ </g>
+ </g>
+ <g class="com.sun.star.drawing.ConnectorShape">
+ <g id="id24">
+ <rect class="BoundingBox" stroke="none" fill="none" x="11278" y="4166" width="3702" height="9064"/>
+ <path fill="none" stroke="rgb(0,0,0)" stroke-width="18" stroke-linejoin="round" d="M 11287,4175 L 14970,4175 14970,13065 14042,13065"/>
+ <path fill="rgb(0,0,0)" stroke="none" d="M 13573,13065 L 14064,13229 14064,12902 13573,13065 Z"/>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/doc/triskel_iot_bzh.svg b/doc/pictures/triskel_iot_bzh.svg
index 096f4244..096f4244 100644
--- a/doc/triskel_iot_bzh.svg
+++ b/doc/pictures/triskel_iot_bzh.svg
diff --git a/doc/updt.sh b/doc/updt.sh
deleted file mode 100755
index d0c02e7a..00000000
--- a/doc/updt.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/bash
-
-title() {
- sed '/^[ \t]*$/d' "$1" |
- sed '/^===/Q' |
- sed '/^---/Q' |
- sed 's/^# //;T;Q' |
- sed 's/^## //;T;Q' |
- sed '/^---/Q'
-}
-
-authors() {
- git log --numstat --format='A %aN' -- "$1" |
- awk '$1=="A"{sub(/^A /,"");a=$0; s[a]+=0; next}NF==3{s[a]+=($1+0)}END{for(a in s)print s[a]" : "a}' |
- sort -nr |
- sed 's/[^:]* : //' |
- sed '1!s/^/; /' |
- tr -d '\n'
-}
-
-dateof() {
- local file="$1"
- local t=$(git log -n 1 --format=%ct "$file")
- [[ -n "$t" ]] || t=$(stat -c %Y "$file")
- LANG= date -d @$t +"%d %B %Y"
-}
-
-meta() {
- local file="$1"
- local t=$(title "$file")
- local a=$(authors "$file")
- local d=$(dateof "$file")
- echo "% $t"
- echo "% $a"
- echo "% $d"
- cat "$file"
-}
-
-
-# make the html file for $1
-mkhtml() {
- local x=$1
- local h=${x%%.md}.html
- echo updating $h from $x
- meta "$x" |
- pandoc --css doc.css -f markdown -t html5 --toc > "$h"
-}
-
-# apply
-for x in *.md; do
- mkhtml $x
-done
-
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 00000000..87bd6230
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,11 @@
+site_name: AGL Application Framework Binder
+theme: readthedocs
+docs_dir: doc
+pages:
+ - 'Overview' : 'index.md'
+ - 'Binder daemon vocabulary' : 'afb-daemon-vocabulary.md'
+ - 'Binder events guide' : 'afb-events-guide.md'
+ - 'Binder Application writing guide' : 'afb-application-writing.md'
+ - 'Binding writing guide' : 'afb-bindings-writing.md'
+ - 'Binder tests overview' : 'afb-tests-overview.md'
+ - 'Bindings samples' : 'afb-bindings-overview.md'