aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephane Desneux <stephane.desneux@iot.bzh>2016-06-08 23:40:18 +0200
committerStephane Desneux <stephane.desneux@iot.bzh>2016-06-09 10:15:01 +0200
commit7e80c8ccdfc2557ea9521f6413b2582403d68dca (patch)
treefaad4e9b0e18dd629b3e22e7e75cab204ddaa49f
parentd0fdae3af6998efdce4c6ba0c5d650898c9c5b27 (diff)
doc: add new document quick-tutorial1.0
Change-Id: I624417d3240504a763b5b45e98ba8f06d5de03e5 Signed-off-by: Stephane Desneux <stephane.desneux@iot.bzh>
-rw-r--r--doc/quick-tutorial.html312
-rw-r--r--doc/quick-tutorial.md217
2 files changed, 529 insertions, 0 deletions
diff --git a/doc/quick-tutorial.html b/doc/quick-tutorial.html
new file mode 100644
index 0000000..ef3e9f7
--- /dev/null
+++ b/doc/quick-tutorial.html
@@ -0,0 +1,312 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>quick-tutorial</title>
+<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
+<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
+</head>
+<body><div class="container"><h1 id="agl-application-framework-a-quick-tutorial">AGL Application Framework: A Quick Tutorial</h1>
+
+<p><div class="toc">
+<ul>
+<li><a href="#agl-application-framework-a-quick-tutorial">AGL Application Framework: A Quick Tutorial</a><ul>
+<li><a href="#introduction">Introduction</a></li>
+<li><a href="#sample-applications">Sample applications</a></li>
+<li><a href="#using-the-cli-tool">Using the CLI tool</a><ul>
+<li><a href="#setup-environment">Setup Environment</a></li>
+<li><a href="#install-an-application">Install an application</a></li>
+<li><a href="#list-installed-applications">List installed applications</a></li>
+<li><a href="#get-information-about-an-application">Get information about an application</a></li>
+<li><a href="#start-application">Start application</a></li>
+<li><a href="#security-context">Security Context</a></li>
+<li><a href="#check-running-applications">Check running applications</a></li>
+<li><a href="#stop-application">Stop application</a></li>
+<li><a href="#uninstall-application">Uninstall application</a></li>
+</ul>
+</li>
+<li><a href="#afm-client-a-sample-html5-homescreen">afm-client: a sample HTML5 ‘Homescreen’</a><ul>
+<li><a href="#installing-an-application">Installing an application</a></li>
+<li><a href="#running-an-application">Running an application</a></li>
+<li><a href="#stopping-an-application">Stopping an application</a></li>
+<li><a href="#uninstalling-an-application">Uninstalling an application</a></li>
+</ul>
+</li>
+<li><a href="#afb-client-a-template-for-angular-applications">afb-client: a template for Angular Applications</a></li>
+</ul>
+</li>
+</ul>
+</div>
+</p>
+
+
+
+<h2 id="introduction">Introduction</h2>
+
+<p>This document proposes a quick tutorial to demonstrate the major functionnalities of the AGL Application Framework. For more complete information, please refer to the inline documentation available in the main git repository: <br>
+<a href="https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-main">https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-main</a> <br>
+<a href="https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-binder">https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-binder</a></p>
+
+<p>For more information on AGL, please visit: <br>
+<a href="https://www.automotivelinux.org/">https://www.automotivelinux.org/</a></p>
+
+<hr>
+
+
+
+<h2 id="sample-applications">Sample applications</h2>
+
+<p>4 sample applications (.wgt files) are prebuilt and available at the following address: <br>
+<a href="https://github.com/iotbzh/afm-widget-examples">https://github.com/iotbzh/afm-widget-examples</a></p>
+
+<p>You can get them by cloning this git repository on your desktop (will be useful later in this tutorial):</p>
+
+
+
+<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-variable">$ </span>git clone <span class="hljs-symbol">https:</span>/<span class="hljs-regexp">/github.com/iotbzh</span><span class="hljs-regexp">/afm-widget-examples</span></code></pre>
+
+
+
+<h2 id="using-the-cli-tool">Using the CLI tool</h2>
+
+
+
+<h3 id="setup-environment">Setup Environment</h3>
+
+<p>Connect your AGL target board to the network and copy some sample widgets on it through SSH (set BOARDIP with your board IP address) :</p>
+
+
+
+<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-variable">$ </span>cd afm-widget-examples
+<span class="hljs-variable">$ </span><span class="hljs-constant">BOARDIP</span>=<span class="hljs-number">1.2</span>.<span class="hljs-number">3.4</span>
+<span class="hljs-variable">$ </span>scp *.wgt root@<span class="hljs-variable">$BOARDIP</span><span class="hljs-symbol">:~/</span></code></pre>
+
+<p>Connect through SSH on the target board and check for Application Framework daemons:</p>
+
+<pre><code>$ ssh root@$BOARDIP
+root@porter:~# ps -ef|grep bin/afm
+afm 409 1 0 13:00 ? 00:00:00 /usr/bin/afm-system-daemon
+root 505 499 0 13:01 ? 00:00:00 /usr/bin/afm-user-daemon
+root 596 550 0 13:22 pts/0 00:00:00 grep afm
+</code></pre>
+
+<p>We can see that there are two daemons running: <br>
+* <strong>afm-system-daemon</strong> runs with a system user ‘afm’ and is responsible for installing/uninstalling packages <br>
+* <strong>afm-user-daemon</strong> runs as a user daemon (currently as root because it’s the only real user on the target board) and is responsible for the whole lifecycle of the applications running inside the user session.</p>
+
+<p>The application framework has a tool running on the Command Line Interface (CLI). Using the <strong>afm-util</strong> command, you can install, uninstall, list, run, stop … applications. </p>
+
+<p>To begin, run ‘<strong>afm-util help</strong>’ to get a quick help on commands:</p>
+
+<pre><code>root@porter:~# afm-util help
+usage: afm-util command [arg]
+
+The commands are:
+
+ list
+ runnables list the runnable widgets installed
+
+ add wgt
+ install wgt install the wgt file
+
+ remove id
+ uninstall id remove the installed widget of id
+
+ info id
+ detail id print detail about the installed widget of id
+
+ ps
+ runners list the running instance
+
+ run id
+ start id start an instance of the widget of id
+
+ kill rid
+ terminate rid terminate the running instance rid
+
+ stop rid
+ pause rid stop the running instance rid
+
+ resume rid
+ continue rid continue the previously rid
+
+ status rid
+ state rid get status of the running instance rid
+</code></pre>
+
+
+
+<h3 id="install-an-application">Install an application</h3>
+
+<p>You can then install your first application:</p>
+
+<pre><code>root@porter:~# afm-util install /home/root/annex.wgt
+{ "added": "webapps-annex@0.0" }
+</code></pre>
+
+<p>Let’s install a second application:</p>
+
+<pre><code>root@porter:~# afm-util install /home/root/memory-match.wgt
+{ "added": "webapps-memory-match@1.1" }
+</code></pre>
+
+<p>Note that usually, <strong>afm-util</strong> will return a <strong>JSON result</strong>, which is the common format for messages returned by the Application Framework daemons.</p>
+
+
+
+<h3 id="list-installed-applications">List installed applications</h3>
+
+<p>You can then list all installed applications:</p>
+
+<pre><code>root@porter:~# afm-util list
+[ { "id": "webapps-annex@0.0", "version": "0.0.10", "width": 0, "height": 0, "name": "Annex", "description": "Reversi\/Othello", "shortname": "", "author": "Todd Brandt &lt;todd.e.brandt@intel.com&gt;" },
+ { "id": "webapps-memory-match@1.1", "version": "1.1.7", "width": 0, "height": 0, "name": "MemoryMatch", "description": "Memory match", "shortname": "", "author": "Todd Brandt &lt;todd.e.brandt@intel.com&gt;" } ]
+</code></pre>
+
+<p>Here, we can see the two previously installed applications.</p>
+
+
+
+<h3 id="get-information-about-an-application">Get information about an application</h3>
+
+<p>Let’s get some details about the first application:</p>
+
+<pre><code>root@porter:~# afm-util info webapps-annex@0.0
+{ "id": "webapps-annex@0.0", "version": "0.0.10", "width": 0, "height": 0, "name": "Annex", "description": "Reversi\/Othello", "shortname": "", "author": "Todd Brandt &lt;todd.e.brandt@intel.com&gt;" }
+</code></pre>
+
+<p>Note that AGL applications are mostly handled by afm-util through their IDs. In our example, the application ID is ‘webapps-annex@0.0’.</p>
+
+
+
+<h3 id="start-application">Start application</h3>
+
+<p>Let’s start the first application Annex:</p>
+
+<pre><code>root@porter:~# afm-util start webapps-annex@0.0
+1
+</code></pre>
+
+<p>As the application is a HTML5 game, you should then get a webview running with QML on the board display.</p>
+
+
+
+<h3 id="security-context">Security Context</h3>
+
+<p>The application has been started in the user session, with a dedicated security context, enforced by SMACK. To illustrate this, we can take a look at the running processes and their respective SMACK labels:</p>
+
+<pre><code>root@porter:~# ps -efZ |grep webapps-annex | grep -v grep
+User::App::webapps-annex root 716 491 0 13:19 ? 00:00:00 /usr/bin/afb-daemon --mode=local --readyfd=8 --alias=/icons /usr/share/afm/icons --port=12348 --rootdir=/usr/share/afm/applications/webapps-annex/0.0 --token=7D6D2F16 --sessiondir=/home/root/app-data/webapps-annex/.afb-daemon
+User::App::webapps-annex root 717 491 0 13:19 ? 00:00:00 /usr/bin/qt5/qmlscene http://localhost:12348/index.html?token=7D6D2F16 /usr/bin/web-runtime-webkit.qml
+</code></pre>
+
+<p>In the previous result, we see that the application is composed of two processes: <br>
+* the application binder (afb-daemon) <br>
+* the application UI (qmlscene …)</p>
+
+<p>While most system processes run with the label ‘System’, we see that the application runs with a specific SMACK label ‘User::App::webapps-annex’: this label is used to force the application to follow a Mandatory Access Control (MAC) scheme. This means that those processes run in their own security context, isolated from the rest of the system (and other applications). Global security rules can then be applied to restrict access to all other user or system resources.</p>
+
+
+
+<h3 id="check-running-applications">Check running applications</h3>
+
+<p>To check for running applications, just run:</p>
+
+<pre><code>root@porter:~# afm-util ps
+[ { "runid": 1, "state": "running", "id": "webapps-annex@0.0" } ]
+</code></pre>
+
+<p>The ‘runid’ is the application instance ID and is used as an argument for the subcommands controlling the application runtime state (kill/stop/resume/status)</p>
+
+
+
+<h3 id="stop-application">Stop application</h3>
+
+<p>To stop the application that was just started (the one with RUNID 1), just run the stop command:</p>
+
+<pre><code>root@porter:~# afm-util terminate 1
+true
+</code></pre>
+
+<p>The application is now stopped, as confirmed by a list of running apps:</p>
+
+<pre><code>root@porter:~# afm-util ps
+[ ]
+</code></pre>
+
+
+
+<h3 id="uninstall-application">Uninstall application</h3>
+
+<p>To uninstall an application, simply use its ID:</p>
+
+<pre><code>root@porter:~# afm-util uninstall webapps-annex@0.0
+true
+</code></pre>
+
+<p>Then list the installed apps to confirm the removal:</p>
+
+<pre><code>root@porter:~# afm-util list
+[ { "id": "webapps-memory-match@1.1", "version": "1.1.7", "width": 0, "height": 0, "name": "MemoryMatch", "description": "Memory match", "shortname": "", "author": "Todd Brandt &lt;todd.e.brandt@intel.com&gt;" } ]
+</code></pre>
+
+
+
+<h2 id="afm-client-a-sample-html5-homescreen">afm-client: a sample HTML5 ‘Homescreen’</h2>
+
+<p><strong>afm-client</strong> is a HTML5 UI that allows to install/uninstall applications as well as starting/stopping them as already demonstrated with afm-util.</p>
+
+<p>The HTML5 UI is accessible remotely through this URL: <br>
+<a href="http://[board_ip]:1234/opa?token=132456789">http://[board_ip]:1234/opa?token=132456789</a></p>
+
+
+
+<h3 id="installing-an-application">Installing an application</h3>
+
+<p>By clicking on the ‘<strong>Upload</strong>’ button on the right, you can send an application package (WGT file) and install it. Select for example the file ‘<strong>rabbit.wgt</strong>’ that was cloned initially from the git repository afm-widget-examples.</p>
+
+<p>Then a popup requester ask for a confirmation: ‘Upload Application rabbit.wgt ?’. Click on the ‘<strong>Install</strong>’ button.</p>
+
+<p>You should then see some changes in the toolbar: a new icon appeared, representing the freshly installed application.</p>
+
+
+
+<h3 id="running-an-application">Running an application</h3>
+
+<p>In the toolbar, click on the button representing the Rabbit application. You’ll get a popup asking to: <br>
+* start the application <br>
+* or get some info about it <br>
+* or uninstall it</p>
+
+<p>Click on the ‘start’ item: the application starts and should be visible as a webview on the target board display. Note that at this point, we could also run the application remotely, that is in the same browser as the Homescreen app. By default, the application framework is configured to run applications ‘locally’ on the board display.</p>
+
+
+
+<h3 id="stopping-an-application">Stopping an application</h3>
+
+<p>In the Homescreen application, click again on the Rabbit application button, then select ‘stop’: the application then stops.</p>
+
+
+
+<h3 id="uninstalling-an-application">Uninstalling an application</h3>
+
+<p>From the same popup menu, you can select ‘uninstall’ to remove the application from the system. As a consequence, the application icon should disappear from the toolbar.</p>
+
+
+
+<h2 id="afb-client-a-template-for-angular-applications">afb-client: a template for Angular Applications</h2>
+
+<p>Another package ‘<strong>afb-client</strong>’ is also available for testing. <br>
+This is a sample HTML5 application demonstrating various basic capabilities of the Binder daemon. It can be used by developers as a template to start writing real AGL Applications.</p>
+
+<p>This application is not available as WGT file yet and it should be started manually without any specific security context:</p>
+
+<pre><code>root@porter:~# /usr/bin/afb-daemon --mode=remote --port=1235 --token='' --sessiondir=/home/root/.afm-daemon --rootdir=/usr/share/agl/afb-client --alias=/icons:/usr/share/afm/icons
+</code></pre>
+
+<p>Then you can access it from a browser: <br>
+<a href="http://[board_ip]:1235/opa/?token=132456789">http://[board_ip]:1235/opa/?token=132456789</a></p>
+
+<p>afb-client is a simple application to demonstrate the built-in capabilities of the binder daemon (handling sessions and security tokens, testing POSTs uploads…) and was used during the application framework development to validate the proposed features.</p></div></body>
+</html> \ No newline at end of file
diff --git a/doc/quick-tutorial.md b/doc/quick-tutorial.md
new file mode 100644
index 0000000..9eeebdb
--- /dev/null
+++ b/doc/quick-tutorial.md
@@ -0,0 +1,217 @@
+AGL Application Framework: A Quick Tutorial
+===========================================
+[TOC]
+
+Introduction
+------------
+This document proposes a quick tutorial to demonstrate the major functionnalities of the AGL Application Framework. For more complete information, please refer to the inline documentation available in the main git repository:
+https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-main
+https://gerrit.automotivelinux.org/gerrit/#/admin/projects/src/app-framework-binder
+
+For more information on AGL, please visit:
+https://www.automotivelinux.org/
+
+----------
+
+Sample applications
+-------------------
+4 sample applications (.wgt files) are prebuilt and available at the following address:
+https://github.com/iotbzh/afm-widget-examples
+
+You can get them by cloning this git repository on your desktop (will be useful later in this tutorial):
+
+```
+$ git clone https://github.com/iotbzh/afm-widget-examples
+```
+
+Using the CLI tool
+------------------
+
+### Setup Environment
+Connect your AGL target board to the network and copy some sample widgets on it through SSH (set BOARDIP with your board IP address) :
+```
+$ cd afm-widget-examples
+$ BOARDIP=1.2.3.4
+$ scp *.wgt root@$BOARDIP:~/
+```
+
+Connect through SSH on the target board and check for Application Framework daemons:
+
+ $ ssh root@$BOARDIP
+ root@porter:~# ps -ef|grep bin/afm
+ afm 409 1 0 13:00 ? 00:00:00 /usr/bin/afm-system-daemon
+ root 505 499 0 13:01 ? 00:00:00 /usr/bin/afm-user-daemon
+ root 596 550 0 13:22 pts/0 00:00:00 grep afm
+
+We can see that there are two daemons running:
+* **afm-system-daemon** runs with a system user 'afm' and is responsible for installing/uninstalling packages
+* **afm-user-daemon** runs as a user daemon (currently as root because it's the only real user on the target board) and is responsible for the whole lifecycle of the applications running inside the user session.
+
+The application framework has a tool running on the Command Line Interface (CLI). Using the **afm-util** command, you can install, uninstall, list, run, stop ... applications.
+
+To begin, run '**afm-util help**' to get a quick help on commands:
+
+ root@porter:~# afm-util help
+ usage: afm-util command [arg]
+
+ The commands are:
+
+ list
+ runnables list the runnable widgets installed
+
+ add wgt
+ install wgt install the wgt file
+
+ remove id
+ uninstall id remove the installed widget of id
+
+ info id
+ detail id print detail about the installed widget of id
+
+ ps
+ runners list the running instance
+
+ run id
+ start id start an instance of the widget of id
+
+ kill rid
+ terminate rid terminate the running instance rid
+
+ stop rid
+ pause rid stop the running instance rid
+
+ resume rid
+ continue rid continue the previously rid
+
+ status rid
+ state rid get status of the running instance rid
+
+### Install an application
+
+You can then install your first application:
+
+ root@porter:~# afm-util install /home/root/annex.wgt
+ { "added": "webapps-annex@0.0" }
+
+Let's install a second application:
+
+ root@porter:~# afm-util install /home/root/memory-match.wgt
+ { "added": "webapps-memory-match@1.1" }
+
+Note that usually, **afm-util** will return a **JSON result**, which is the common format for messages returned by the Application Framework daemons.
+
+### List installed applications
+You can then list all installed applications:
+
+ root@porter:~# afm-util list
+ [ { "id": "webapps-annex@0.0", "version": "0.0.10", "width": 0, "height": 0, "name": "Annex", "description": "Reversi\/Othello", "shortname": "", "author": "Todd Brandt <todd.e.brandt@intel.com>" },
+ { "id": "webapps-memory-match@1.1", "version": "1.1.7", "width": 0, "height": 0, "name": "MemoryMatch", "description": "Memory match", "shortname": "", "author": "Todd Brandt <todd.e.brandt@intel.com>" } ]
+
+Here, we can see the two previously installed applications.
+
+### Get information about an application
+Let's get some details about the first application:
+
+ root@porter:~# afm-util info webapps-annex@0.0
+ { "id": "webapps-annex@0.0", "version": "0.0.10", "width": 0, "height": 0, "name": "Annex", "description": "Reversi\/Othello", "shortname": "", "author": "Todd Brandt <todd.e.brandt@intel.com>" }
+
+Note that AGL applications are mostly handled by afm-util through their IDs. In our example, the application ID is 'webapps-annex@0.0'.
+
+### Start application
+Let's start the first application Annex:
+
+ root@porter:~# afm-util start webapps-annex@0.0
+ 1
+
+As the application is a HTML5 game, you should then get a webview running with QML on the board display.
+
+### Security Context
+The application has been started in the user session, with a dedicated security context, enforced by SMACK. To illustrate this, we can take a look at the running processes and their respective SMACK labels:
+
+ root@porter:~# ps -efZ |grep webapps-annex | grep -v grep
+ User::App::webapps-annex root 716 491 0 13:19 ? 00:00:00 /usr/bin/afb-daemon --mode=local --readyfd=8 --alias=/icons /usr/share/afm/icons --port=12348 --rootdir=/usr/share/afm/applications/webapps-annex/0.0 --token=7D6D2F16 --sessiondir=/home/root/app-data/webapps-annex/.afb-daemon
+ User::App::webapps-annex root 717 491 0 13:19 ? 00:00:00 /usr/bin/qt5/qmlscene http://localhost:12348/index.html?token=7D6D2F16 /usr/bin/web-runtime-webkit.qml
+
+In the previous result, we see that the application is composed of two processes:
+* the application binder (afb-daemon)
+* the application UI (qmlscene ...)
+
+While most system processes run with the label 'System', we see that the application runs with a specific SMACK label 'User::App::webapps-annex': this label is used to force the application to follow a Mandatory Access Control (MAC) scheme. This means that those processes run in their own security context, isolated from the rest of the system (and other applications). Global security rules can then be applied to restrict access to all other user or system resources.
+
+### Check running applications
+To check for running applications, just run:
+
+ root@porter:~# afm-util ps
+ [ { "runid": 1, "state": "running", "id": "webapps-annex@0.0" } ]
+
+The 'runid' is the application instance ID and is used as an argument for the subcommands controlling the application runtime state (kill/stop/resume/status)
+
+### Stop application
+To stop the application that was just started (the one with RUNID 1), just run the stop command:
+
+ root@porter:~# afm-util terminate 1
+ true
+
+The application is now stopped, as confirmed by a list of running apps:
+
+ root@porter:~# afm-util ps
+ [ ]
+
+
+### Uninstall application
+To uninstall an application, simply use its ID:
+
+ root@porter:~# afm-util uninstall webapps-annex@0.0
+ true
+
+Then list the installed apps to confirm the removal:
+
+ root@porter:~# afm-util list
+ [ { "id": "webapps-memory-match@1.1", "version": "1.1.7", "width": 0, "height": 0, "name": "MemoryMatch", "description": "Memory match", "shortname": "", "author": "Todd Brandt <todd.e.brandt@intel.com>" } ]
+
+afm-client: a sample HTML5 'Homescreen'
+---------------------------------------
+
+**afm-client** is a HTML5 UI that allows to install/uninstall applications as well as starting/stopping them as already demonstrated with afm-util.
+
+The HTML5 UI is accessible remotely through this URL:
+http://[board_ip]:1234/opa?token=132456789
+
+### Installing an application
+
+By clicking on the '**Upload**' button on the right, you can send an application package (WGT file) and install it. Select for example the file '**rabbit.wgt**' that was cloned initially from the git repository afm-widget-examples.
+
+Then a popup requester ask for a confirmation: 'Upload Application rabbit.wgt ?'. Click on the '**Install**' button.
+
+You should then see some changes in the toolbar: a new icon appeared, representing the freshly installed application.
+
+### Running an application
+In the toolbar, click on the button representing the Rabbit application. You'll get a popup asking to:
+* start the application
+* or get some info about it
+* or uninstall it
+
+Click on the 'start' item: the application starts and should be visible as a webview on the target board display. Note that at this point, we could also run the application remotely, that is in the same browser as the Homescreen app. By default, the application framework is configured to run applications 'locally' on the board display.
+
+### Stopping an application
+
+In the Homescreen application, click again on the Rabbit application button, then select 'stop': the application then stops.
+
+### Uninstalling an application
+
+From the same popup menu, you can select 'uninstall' to remove the application from the system. As a consequence, the application icon should disappear from the toolbar.
+
+afb-client: a template for Angular Applications
+-----------------------------------------------
+
+Another package '**afb-client**' is also available for testing.
+This is a sample HTML5 application demonstrating various basic capabilities of the Binder daemon. It can be used by developers as a template to start writing real AGL Applications.
+
+This application is not available as WGT file yet and it should be started manually without any specific security context:
+
+ root@porter:~# /usr/bin/afb-daemon --mode=remote --port=1235 --token='' --sessiondir=/home/root/.afm-daemon --rootdir=/usr/share/agl/afb-client --alias=/icons:/usr/share/afm/icons
+
+Then you can access it from a browser:
+http://[board_ip]:1235/opa/?token=132456789
+
+afb-client is a simple application to demonstrate the built-in capabilities of the binder daemon (handling sessions and security tokens, testing POSTs uploads...) and was used during the application framework development to validate the proposed features.