diff --git a/3P/CMakeLists.txt b/3P/CMakeLists.txt
index 7c1b8521..d24aaa19 100644
--- a/3P/CMakeLists.txt
+++ b/3P/CMakeLists.txt
@@ -11,4 +11,4 @@ add_subdirectory (ubus/libubus/builders/cmake)
add_subdirectory (ubus/ubus/builders/cmake)
add_subdirectory (ubus/ubusd/builders/cmake)
add_subdirectory (civetweb/builders/cmake)
-#add_subdirectory (wiringPi/)
+add_subdirectory (wiringPi/)
diff --git a/Docs/Schemas/Domo_box.fzz b/Docs/Schemas/Domo_box.fzz
new file mode 100644
index 00000000..a64a3728
Binary files /dev/null and b/Docs/Schemas/Domo_box.fzz differ
diff --git a/firmware/board/raspberrypi/buildroot-toolchain.cfg b/firmware/board/raspberrypi/buildroot-toolchain.cfg
index fcbe1dfd..c562764e 100644
--- a/firmware/board/raspberrypi/buildroot-toolchain.cfg
+++ b/firmware/board/raspberrypi/buildroot-toolchain.cfg
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Buildroot 2016.02-rc2-g0498544-dirty Configuration
+# Buildroot 2016.02-g1dabafe-dirty Configuration
#
BR2_HAVE_DOT_CONFIG=y
BR2_HOST_GCC_AT_LEAST_4_7=y
@@ -588,7 +588,7 @@ BR2_PACKAGE_CMAKE_ARCH_SUPPORTS=y
#
#
-# efl needs lua
+# efl needs lua 5.1
#
# BR2_PACKAGE_FBDUMP is not set
# BR2_PACKAGE_FBGRAB is not set
@@ -1817,6 +1817,12 @@ BR2_TARGET_ROOTFS_EXT2_NONE=y
# Bootloaders
#
# BR2_TARGET_BAREBOX is not set
+# BR2_TARGET_BAREBOX_LATEST_VERSION is not set
+# BR2_TARGET_BAREBOX_CUSTOM_VERSION is not set
+# BR2_TARGET_BAREBOX_CUSTOM_TARBALL is not set
+# BR2_TARGET_BAREBOX_CUSTOM_GIT is not set
+# BR2_TARGET_BAREBOX_USE_DEFCONFIG is not set
+# BR2_TARGET_BAREBOX_USE_CUSTOM_CONFIG is not set
# BR2_TARGET_MXS_BOOTLETS is not set
# BR2_TARGET_UBOOT is not set
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2451ceb8..de36759a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,9 +3,8 @@
# to the root binary directory of the project as ${HELLO_BINARY_DIR}.
cmake_minimum_required (VERSION 2.8.11)
-#add_subdirectory (alarmd/builders/cmake)
add_subdirectory (domod/builders/cmake)
-#add_subdirectory (chacond/builders/cmake)
+add_subdirectory (chacond/builders/cmake)
add_subdirectory (sprinklersd/builders/cmake)
#add_subdirectory (rf_listenerd/builders/cmake)
#add_subdirectory (restd/builders/cmake)
diff --git a/src/restd/builders/cmake/CMakeLists.txt b/src/restd/builders/cmake/CMakeLists.txt
new file mode 100644
index 00000000..ba7c9b4c
--- /dev/null
+++ b/src/restd/builders/cmake/CMakeLists.txt
@@ -0,0 +1,46 @@
+cmake_minimum_required(VERSION 2.8.11)
+
+project(restd)
+
+include (libcivetweb)
+include (libjsoncpp)
+include (libubus)
+include (libubox)
+include (libubuscpp)
+
+include_directories(../../src)
+
+set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -pedantic -Werror=strict-aliasing")
+
+file (
+ GLOB_RECURSE
+ source_files
+ ../../src/main.cpp
+ ../../src/authorize.cpp
+ ../../src/session.cpp
+ ../../src/message.cpp
+ ../../src/routes/ExitHandler.cpp
+ ../../src/routes/UbusHandler.cpp
+)
+
+add_executable (
+ restd
+ ${source_files}
+)
+
+target_link_libraries (restd
+ LINK_PUBLIC
+ civetweb
+ ubus
+ ubuscpp
+ dl
+ crypt
+ jsoncpp
+)
+
+
+add_custom_command(
+ TARGET restd
+ POST_BUILD
+ COMMAND cp ${CMAKE_SOURCE_DIR}/certificate/ssl_cert.pem ${CMAKE_SOURCE_DIR}/build/
+ )
diff --git a/src/restd/doc.md b/src/restd/doc.md
new file mode 100644
index 00000000..9742c448
--- /dev/null
+++ b/src/restd/doc.md
@@ -0,0 +1,43 @@
+### Doc of the API ###
+
+### examples
+http://dev.enchant.com/api/v1
+http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#useful-post-responses
+
+## Get Capabilities ###
+
+curl -v http://localhost:8081/v1/capabilities/
+
+* Trying 127.0.0.1...
+* Connected to localhost (127.0.0.1) port 8081 (#0)
+> GET /v1/capabilities HTTP/1.1
+> User-Agent: curl/7.35.0
+> Host: localhost:8081
+> Accept: */*
+>
+< HTTP/1.1 200 OK
+< Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
+< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
+< Access-Control-Allow-Origin: *
+< Cache-Control: no-store, no-cache, must-revalidate, max-age=0
+< Connection: close
+< Content-Type: application/json; charset=utf-8
+< Pragma: no-cache
+<
+{
+ "capabilities" : [ "Light", "Shutter", "Sprinkler" ],
+ "id" : "/v1/capabilities",
+ "response_code" : 200,
+ "status" : "OK"
+}
+
+## Get Capabilities ###
+
+curl -v http://localhost:8081/v1/capabilities/Lights/
+
+## Set Capabilities Light ###
+
+curl -v -X POST http://localhost:8081/v1/capabilities/Lights -d "{\"id\": 1, \"state\":true}"
+
+
+curl -v -X POST http://localhost:8081/v1/capabilities/Lights/1 -d "{"state"=true}"
\ No newline at end of file
diff --git a/src/restd/doc/Makefile b/src/restd/doc/Makefile
new file mode 100644
index 00000000..2fb3599e
--- /dev/null
+++ b/src/restd/doc/Makefile
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make ' where is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ST2-WRemoteless.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ST2-WRemoteless.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/ST2-WRemoteless"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ST2-WRemoteless"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/src/restd/doc/source/about-the-api.rst b/src/restd/doc/source/about-the-api.rst
new file mode 100644
index 00000000..9385a176
--- /dev/null
+++ b/src/restd/doc/source/about-the-api.rst
@@ -0,0 +1,10 @@
+What is a REST API and why does it matter ?
+===========================================
+
+To enable external devices to pair the AwoX Audio Device with other wireless access points, a web API has been designed
+for the control part. Aside from enabling devices to interact with the pairing capabilities of the device, this API is a
+logical interface to every possible stateless interactions with it.
+
+This document is referencing the complete API exposed by the Awox Audio Striim Device.
+A REST (Representational state transfer) service is based on an architectural style consisting of a coordinated set of
+architectural constraints applied to components, connectors, and data elements, within a distributed hypermedia system.
diff --git a/src/restd/doc/source/alarm-api.rst b/src/restd/doc/source/alarm-api.rst
new file mode 100644
index 00000000..44057ad6
--- /dev/null
+++ b/src/restd/doc/source/alarm-api.rst
@@ -0,0 +1,374 @@
+=============================
+Alarm programming interface
+=============================
+
+A description of the available programming interfaces used to interact with alarm components.
+
+.. _Alarm-Summary:
+
+Summary
+~~~~~~~
+
+========================================== ========================================= ================
+Chapter URL JSON HTTP Method
+========================================== ========================================= ================
+:ref:`Alarm/Count` /Alarm/Count.json GET
+:ref:`Alarm/Configuration/Get` /Alarm/Configuration.json GET
+:ref:`Alarm/Configuration/Post` /Alarm/Configuration.json POST
+:ref:`Alarm/Configuration/Put` /Alarm/Configuration.json PUT
+:ref:`Alarm/Preset/Info` /Alarm/Preset/Info.json GET
+========================================== ========================================= ================
+
+
+.. _Alarm/Count:
+
+Count
+~~~~~
+
+Get the available Alarm Number
+------------------------------
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /Alarm/Count.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+Description
+^^^^^^^^^^^
+
+Returns the available alarm number.
+
+Parameters
+^^^^^^^^^^
+
+None.
+
+Request example
+^^^^^^^^^^^^^^^
+::
+
+ http://[x.x.x.x]:34000/Alarm/Count.json
+
+Expected response
+^^^^^^^^^^^^^^^^^
+
++---------------+---------------------+----------------------+-------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+=====================+======================+=====================================+
+| 200 | ``passed`` | Integer | The request succeeded. |
++---------------+---------------------+----------------------+-------------------------------------+
+
+Response example
+^^^^^^^^^^^^^^^^
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "count": "1",
+ "id": "/Alarm/Count.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+|
+|
+|
+
+.. _Alarm/Configuration/Get:
+
+Configuration
+~~~~~~~~~~~~~
+
+Get the Alarm Configuration
+---------------------------
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /Alarm/Configuration.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+Description
+^^^^^^^^^^^
+
+Returns the ``AlarmConfigContainer`` object.
+
+Parameters
+^^^^^^^^^^
+
+None.
+
+Request example
+^^^^^^^^^^^^^^^
+::
+
+ http://[x.x.x.x]:34000//Alarm/Configuration.json
+
+Expected response
+^^^^^^^^^^^^^^^^^
+
++---------------+---------------------+----------------------------+-------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+=====================+============================+=====================================+
+| 200 | ``passed`` | ``AlarmConfigContainer`` | The request succeeded. |
++---------------+---------------------+----------------------------+-------------------------------------+
+
+Response example
+^^^^^^^^^^^^^^^^
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "alarms": [{
+ "id": 0,
+ "state": "on",
+ "source_type": "preset",
+ "source": "1",
+ "frequency": [1, 2, 4, 8, 16],
+ "volume_mode": "specific",
+ "volume": 50,
+ "time": "06:45"
+ }],
+ "id": "/Alarm/Configuration.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+|
+|
+|
+
+.. _Alarm/Configuration/Post:
+
+Set an Alarm Configuration (POST)
+---------------------------------
+
+======================== =========================
+Key Value JSon
+======================== =========================
+Resource URL /Alarm/Configuration.json
+HTTP Method POST
+Response format ``application/json``
+======================== =========================
+
+Description
+^^^^^^^^^^^
+
+This method allow to change parameters of an alarm.
+
+Keys
+^^^^
+
++-----+--------------------+-------------+-------------+-------------------+
+| # | Name | Mandatory | Data type | Type of parameter |
++=====+====================+=============+=============+===================+
+| 1 | alarm_config | Yes | ``alarms`` | POST |
++-----+--------------------+-------------+-------------+-------------------+
+
+alarm_config: Alarm configuration parameters in json format
+
+Example request
+^^^^^^^^^^^^^^^
+::
+
+ http://[x.x.x.x]:34000/Alarm/Configuration.json
+
+ alarm_config={"id":0,"volume":50,"source":1,"source_type":"default_tone","state":"on","volume_mode":"specific","time":"12:12","frequency":[1, 64]}
+
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "id": "/Alarm/Configuration.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+|
+|
+|
+
+
+.. _Alarm/Configuration/Put:
+
+Set an Alarm Configuration (PUT)
+--------------------------------
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /Alarm/Configuration.json
+HTTP Method PUT
+Response format ``application/json``
+======================== ==============================
+
+
+Description
+^^^^^^^^^^^
+
+This method allow to change parameters of an alarm.
+
+Parameters
+^^^^^^^^^^
+
+Parameters can be sent in the same time.
+The alarm id parameter is mandatory for each request.
+
++-----+--------------------+-------------+-----------+-------------------+
+| # | Name | Mandatory | Data type | Type of parameter |
++=====+====================+=============+===========+===================+
+| 1 | id | Yes | Integer | PUT |
++-----+--------------------+-------------+-----------+-------------------+
+| 2 | state | No | String | PUT |
++-----+--------------------+-------------+-----------+-------------------+
+| 3 | source_type | No | String | PUT |
++-----+--------------------+-------------+-----------+-------------------+
+| 4 | source | No | String | PUT |
++-----+--------------------+-------------+-----------+-------------------+
+| 5 | frequency | No | String | PUT |
++-----+--------------------+-------------+-----------+-------------------+
+| 6 | volume_mode | No | String | PUT |
++-----+--------------------+-------------+-----------+-------------------+
+| 7 | volume | No | Integer | PUT |
++-----+--------------------+-------------+-----------+-------------------+
+| 9 | time | No | String | PUT |
++-----+--------------------+-------------+-----------+-------------------+
+
+:id: Alarm id value starting at index '0'
+
+:state: Alarm state can be ''on'' or ''off''
+
+:source_type: Alarm source_type can be ''default_tone'' or ''preset''
+
+:source: Alarm source can be a preset number (starting at index 1) if source_type = preset
+
+:frequency: Alarm frequency list separated by ',' character.
+ Can be ''0'' (once), ''1'' (monday), ''2'' (tuesday), ''4'' (wednesday), , ''8'' (thursday), ''16'' (friday), ''32'' (saturday), ''64'' (sunday)
+
+:volume_mode: Alarm volume_mode can be ''specific'' or ''incremental''
+
+:volume: Alarm specific volume value or the maximum incremental volume value
+
+:time: Alarm time value in the form "HH:MM"
+
+Example request
+^^^^^^^^^^^^^^^
+
+::
+
+ http://[x.x.x.x]:34000/Alarm/Configuration.json?id=0&state=true
+ http://[x.x.x.x]:34000/Alarm/Configuration.json?id=0&source_type=preset
+ http://[x.x.x.x]:34000/Alarm/Configuration.json?id=0&source=1
+ http://[x.x.x.x]:34000/Alarm/Configuration.json?id=0&frequency=0
+ http://[x.x.x.x]:34000/Alarm/Configuration.json?id=0&volume_mode=spec
+ http://[x.x.x.x]:34000/Alarm/Configuration.json?id=0&volume=30
+ http://[x.x.x.x]:34000/Alarm/Configuration.json?id=0&time=15:45
+
+ http://[x.x.x.x]:34000/Alarm/Configuration.json?id=0&state=true&source_type=preset&source=1&frequency=1,2,4&volume_mode=spec&volume=10&time=17:26
+
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "id": "/Alarm/Configuration.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+.. _Alarm/Preset/Info:
+
+Preset
+~~~~~~
+
+Get the Alarm Preset
+--------------------
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /Alarm/Preset/Info.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+Description
+^^^^^^^^^^^
+
+Returns the ``AlarmPresetContainer`` object.
+
+Parameters
+^^^^^^^^^^
+
+None.
+
+Request example
+^^^^^^^^^^^^^^^
+::
+
+ http://[x.x.x.x]:34000//Alarm/Preset/Info.json
+
+Expected response
+^^^^^^^^^^^^^^^^^
+
++---------------+---------------------+----------------------------+-------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+=====================+============================+=====================================+
+| 200 | ``passed`` | ``AlarmPresetContainer`` | The request succeeded. |
++---------------+---------------------+----------------------------+-------------------------------------+
+
+Response example
+^^^^^^^^^^^^^^^^
+
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "alarm_presets": [{
+ "id": 1,
+ "title": "CHERIE FM 99.1 Live",
+ "selected": false
+ }, {
+ "id": 2,
+ "title": "Europe 1 104.2 FM Live",
+ "selected": true
+ }, {
+ "id": 3,
+ "title": "Jazz Radio 97.3 FM Live",
+ "selected": false
+ }, {
+ "id": 4,
+ "title": "MFM 102.7",
+ "selected": false
+ }, {
+ "id": 5,
+ "title": "RMC Info Live",
+ "selected": false
+ }],
+ "id": "/Alarm/Preset/Info.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+|
+|
+|
diff --git a/src/restd/doc/source/api-models.rst b/src/restd/doc/source/api-models.rst
new file mode 100644
index 00000000..d71a7d9e
--- /dev/null
+++ b/src/restd/doc/source/api-models.rst
@@ -0,0 +1,735 @@
+Models & data types
+===================
+
+
+Introduction
+~~~~~~~~~~~~
+
+The ``WAPI`` takes requests as inputs and ouputs back an appropriate reponse to the client. As you may have seen, these response are formatted under the form of objects serialized in JSON. As it is sometimes hard to make all the response uniform, we wanted to keep a well stated logic in our way of responding to your requests by outputting well-documented objects for each type of responses.
+
+This page will list every objects that we are using for responding to your requests. Every responses we are sending back extends a ``BasicResponseContainer`` object.
+
+When reading about the layout of each type of responses, keep in mind that the layout depends on the object attributes. If an object's attribute can vary, we will only document its type, otherwise, we will document the exact value this attribute must take.
+
+
+Models
+~~~~~~
+
+BasicResponseContainer
+----------------------
+
+Description:
+^^^^^^^^^^^^
+
+This is the object every other JSON object will be extending. This object basically contains every attributes a response needs to be correctly handled by the client.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++---------------+------------+
+| Field name | Data type |
++===============+============+
+| id | String |
++---------------+------------+
+| status | String |
++---------------+------------+
+| response_code | Integer |
++---------------+------------+
+
+
+|
+|
+|
+
+
+RequestSucceededContainer *extends BasicResponseContainer*
+----------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+This response is sent back when the request went well. This is a generic container stating that everything is OK.
+
+Object layout:
+^^^^^^^^^^^^^^
+
+.. code-block:: json
+
+ {
+ "id": "/xxx/yy.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+
+LocaleContainer *extends RequestSucceededContainer*
+---------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+
+Holds informations about the device available locales, as well as the currently active locale.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++------------------+------------+
+| Field name | Data type |
++==================+============+
+| current_locale | object |
++------------------+------------+
+| available_locale | Array |
++------------------+------------+
+
+The ``available_locale`` attribute is an array of ``Locale`` objects. The layout of a ``Locale`` object is described as follow :
+
++------------------+------------+
+| Field name | Data type |
++==================+============+
+| iso3_language | String |
++------------------+------------+
+| iso3_country | String |
++------------------+------------+
+| display_name | String |
++------------------+------------+
+| display_language | String |
++------------------+------------+
+| country | String |
++------------------+------------+
+
+
+|
+|
+|
+
+
+AlarmConfigContainer
+--------------------
+
+Description:
+^^^^^^^^^^^^
+
+Holds informations about the device alarm configuration.
+
+Object layout:
+^^^^^^^^^^^^^^
+
+The ``AlarmConfigContainer`` is an array of ``alarms`` objects. The layout of a ``alarms`` object is described as follow :
+
++-----+--------------------+-------------+-----------+
+| # | Field Name | Mandatory | Data type |
++=====+====================+=============+===========+
+| 1 | id | Yes | Integer |
++-----+--------------------+-------------+-----------+
+| 2 | state | No | String |
++-----+--------------------+-------------+-----------+
+| 3 | source_type | No | String |
++-----+--------------------+-------------+-----------+
+| 4 | source | No | String |
++-----+--------------------+-------------+-----------+
+| 5 | frequency | No | Array |
++-----+--------------------+-------------+-----------+
+| 6 | volume_mode | No | String |
++-----+--------------------+-------------+-----------+
+| 7 | volume | No | Integer |
++-----+--------------------+-------------+-----------+
+| 9 | time | No | String |
++-----+--------------------+-------------+-----------+
+
+
+The ``alarms`` object contains the following attributes :
+
+:id: Alarm id value starting at index ''0''
+
+:state: Alarm state can be ''on'' or ''off''
+
+:source_type: Alarm source_type can be ''default_tone'' or ''preset''
+
+:source: Alarm source can be a preset number (starting at index 1) if source_type = preset
+
+:frequency: Alarm frequency can be ''0'' (once), ''1'' (monday), ''2'' (tuesday), ''4'' (wednesday), , ''8'' (thursday), ''16'' (friday), ''32'' (saturday), ''64'' (sunday)
+
+:volume_mode: Alarm volume_mode can be ''specific'' or ''incremental''
+
+:volume: Alarm specific volume value or the maximum incremental volume value
+
+:time: Alarm time value in the form "HH:MM"
+
+
+|
+|
+|
+
+
+AlarmPresetContainer
+--------------------
+
+Description:
+^^^^^^^^^^^^
+
+Holds informations about the available device alarm presets.
+
+Object layout:
+^^^^^^^^^^^^^^
+
+The ``AlarmPresetContainer`` is an array of ``alarm_presets`` objects. The layout of a ``alarm_presets`` object is described as follow :
+
++-----+--------------------+-------------+-----------+
+| # | Field Name | Mandatory | Data type |
++=====+====================+=============+===========+
+| 1 | id | No | Integer |
++-----+--------------------+-------------+-----------+
+| 2 | title | No | String |
++-----+--------------------+-------------+-----------+
+| 3 | selected | No | boolean |
++-----+--------------------+-------------+-----------+
+
+The ``alarm_presets`` object contains the following attributes :
+
+:id: Preset id value starting at index ''1''
+
+:title: Preset title
+
+:selected: Flag set to true if the preset id is selected as an alarm source
+
+
+|
+|
+|
+
+NetworkInfoContainer *extends RequestSucceededContainer*
+--------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Contains informations about the network state of the AwoX Audio Device.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++---------------+------------+
+| Field name | Data type |
++===============+============+
+| network | object |
++---------------+------------+
+| stats | object |
++---------------+------------+
+
+
+The ``network`` object contains the following attributes :
+
+:network_type: the type of the interface
+
+:ip_mode: Mode of Ip Acquisition
+
+:mac_address: The MAC address of the current interface
+
+:ip_address: The current IP address of the device. Can be ``0.0.0.0`` if the device isn't bound to any network
+
+:ip_netmask: The current IP netmask of the device. Can be ``0.0.0.0`` if the device isn't bound to any network
+
+:ip_gateway: The current IP gateway of the device.
+
+:ip_dns1: The main DNS Server used by the device. It could be empty.
+
+:ip_dns2: The second DNS Server used by the device. It could be empty.
+
+:connected_ssid: If the network_type is Wi-Fi, the field is returned. The SSID of the access point the device is currently bound to
+
+:link_speed: If the network_type is Wi-Fi, the field is returned. The current WiFi link speed between the stick and the remote AP
+
+The ``stats`` object contains the following attributes :
+
+:total_tx_bytes: The amount of bytes sent by the device since it was started
+
+:total_rx_bytes: The amount of bytes received by the device since it was started
+
+
+|
+|
+|
+
+
+AccessPointContainer *extends RequestSucceededContainer*
+--------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Wraps a list of AccessPoint.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++---------------+------------+
+| Field name | Data type |
++===============+============+
+| ap_list | Array |
++---------------+------------+
+
+
+The sole purpose of this object is to embed a list of ``AccessPoint`` within the ap_list field, and to advertise the user that the retrieval of the access point list went well.
+
+
+|
+|
+|
+
+
+AccessPoint
+-----------
+
+Description:
+^^^^^^^^^^^^
+Holds the characteristics of an access point.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++--------------------------+------------+
+| Field name | Data type |
++==========================+============+
+| bssid | String |
++--------------------------+------------+
+| channel | Integer |
++--------------------------+------------+
+| raw_level | Integer |
++--------------------------+------------+
+| scaled_signal_level | Integer |
++--------------------------+------------+
+| capabilities_stringified | String |
++--------------------------+------------+
+| capabilities | Array |
++--------------------------+------------+
+| ssid | String |
++--------------------------+------------+
+| is_bound | Boolean |
++--------------------------+------------+
+| favorite | Integer |
++--------------------------+------------+
+
+
+
+This object contains the following attributes :
+
+ :bssid: the MAC address of the access point
+ :channel: the channel of the access point
+ :raw_level: the signal quality of the Wi-Fi Link. between 0-100.
+ :scaled_signal_level: the radio level scaled on a scale of 5. Every results expressed in absolute dbm are converted on a 5-based scale. Very handy if you'd like to show to the user the level of the signal in a user-friendly way.
+ :capabilities_stringified: A string holding the informations about the authentication capabilities of the access point.
+ :capabilities: A clean list of the authentication capabilities this access point supports. This a list of strings which can take the following values : WPA-PSK, WPA2-PSK, WEP, EAP, WPS, OPEN.
+ :ssid: the SSID of the access point
+ :is_bound: whether the device is connected or is in the process of being connected to this access point
+ :favorite: integer value (0 or 1) to know if the Access point is in the favorite of the device.
+
+We only support a connection based on one of the following authentication methods : WPA-PSK, WPA2-PSK, WEP and OPEN.
+
+
+|
+|
+|
+
+
+
+CpuInfoContainer *extends RequestSucceededContainer*
+-----------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Contains informations about the CPU of the Device.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++---------------+------------+
+| Field name | Data type |
++===============+============+
+| load | Integer |
++---------------+------------+
+
+
+Field details:
+^^^^^^^^^^^^^^
+
+:load: CPU load of the CPU
+
+
+|
+|
+|
+
+MemoryInfoContainer *extends RequestSucceededContainer*
+-------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Holds informations about the device memory metrics.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++----------------+------------+
+| Field name | Data type |
++================+============+
+| memory_info | object |
++----------------+------------+
+
+The ``memory_info`` object layout is described as follow :
+
++------------------+-----------+
+| Field name | Data type |
++==================+===========+
+| total_memory | Long |
++------------------+-----------+
+| available_memory | Long |
++------------------+-----------+
+| used_memory | Long |
++------------------+-----------+
+| cached | Long |
++------------------+-----------+
+
+
+Field details:
+^^^^^^^^^^^^^^
+
+:total_memory: The total memory available on the device in bytes.
+
+:available_memory: The free memory available on the device in bytes.
+
+:used_memory: The used memory on the device in bytes.
+
+:cached: The cached memory available on the device in bytes.
+
+|
+|
+|
+
+DeviceInfoContainer *extends RequestSucceededContainer*
+-------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Holds informations about the device informations.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++----------------+------------+
+| Field name | Data type |
++================+============+
+| device_info | object |
++----------------+------------+
+
+The ``device_info`` object layout is described as follow :
+
++-----+--------------------+-----------+
+| # | Name | Data type |
++=====+====================+===========+
+| 1 | Manufacturer | String |
++-----+--------------------+-----------+
+| 2 | ProductName | String |
++-----+--------------------+-----------+
+| 3 | CompanyName | String |
++-----+--------------------+-----------+
+| 4 | HardwareVersion | String |
++-----+--------------------+-----------+
+| 5 | SoftwareVersion | String |
++-----+--------------------+-----------+
+| 6 | build_date | String |
++-----+--------------------+-----------+
+| 7 | build_revision | String |
++-----+--------------------+-----------+
+| 8 | uuid | String |
++-----+--------------------+-----------+
+| 9 | uptime | Integer |
++-----+--------------------+-----------+
+
+Field details:
+^^^^^^^^^^^^^^
+
+:Manufacturer: The Name of the Manufacturer should be ''AwoX''
+
+:ProductName: Correspond to the Product Name could be ''SLCW13''
+
+:CompanyName: Correspond to the CompanyName should be ''AwoX''
+
+:HardwareVersion: Correspond to the Hardware Version could be ''1.0''
+
+:SoftwareVersion: Correspond to the Software Version
+
+:build_date: Correspond to the build date of the system.
+
+:build_revision: Correspond to the revision attached to the firmware.
+
+:uuid: Correspond to the unique UUID of the Device . could be ''xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx''
+
+:uptime: Correspond to the uptime of the Device.
+
+|
+|
+|
+
+PlayerStateContainer *extends RequestSucceededContainer*
+--------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Holds informations about the player.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++----------------+------------+
+| Field name | Data type |
++================+============+
+| player | object |
++----------------+------------+
+
+The ``player`` object layout is described as follow :
+
++-----+--------------------+-----------+
+| # | Name | Data type |
++=====+====================+===========+
+| 1 | state | String |
++-----+--------------------+-----------+
+
+Field details:
+^^^^^^^^^^^^^^
+
+:state: contains the state of the player could be ''stopped'', ''playing'' or ''paused''
+
+
+|
+|
+|
+
+LightCapabilitiesContainer *extends RequestSucceededContainer*
+--------------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Wraps a list of Light Capabilities.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++----------------+------------+
+| Field name | Data type |
++================+============+
+| capabilities | Array |
++----------------+------------+
+
+The ``capabilities`` array contain the list as string of the light capabilities.
+it could be:
+
+* SwitchPower
+* Dimming
+* WhiteLight
+* ColorLight
+
+|
+|
+|
+
+LightSwitchPowerContainer *extends RequestSucceededContainer*
+-------------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Wrap the Sate of the Light state is equal to ''true'' is the light is turn ''on'', ''false'' otherwise.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++---------------+------------+
+| Field name | Data type |
++===============+============+
+| state | Boolean |
++---------------+------------+
+
+|
+|
+|
+
+LightDimmingContainer *extends RequestSucceededContainer*
+---------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+return the level of dimming.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++---------------+------------+-----------------------+-----------------------+
+| Field name | Data type | Minimum allowed value | Maximum allowed value |
++===============+============+=======================+=======================+
+| level | Integer | 0 | 100 |
++---------------+------------+-----------------------+-----------------------+
+
+|
+|
+|
+
+
+WhiteLightContainer *extends RequestSucceededContainer*
+-------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Return the informations about the White Light. the temperature and the brightness.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++---------------+------------+-----------------------+-----------------------+
+| Field name | Data type | Minimum allowed value | Maximum allowed value |
++===============+============+=======================+=======================+
+| brightness | Integer | 0 | 100 |
++---------------+------------+-----------------------+-----------------------+
+| temperature | Integer | 0 | 100 |
++---------------+------------+-----------------------+-----------------------+
+
+|
+|
+|
+
+ColorLightRGBContainer *extends RequestSucceededContainer*
+----------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+
+Wrap the the current color of the light and returned as an rgb color object.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++---------------+------------+
+| Field name | Data type |
++===============+============+
+| rgbcolor | Object |
++---------------+------------+
+
+The ``rgbcolor`` object contains the following attributes :
+
+:red: red composant of the color
+
+:green: green composant of the color
+
+:blue: blue composant of the color
+
+|
+|
+|
+
+ColorLightHSVContainer *extends RequestSucceededContainer*
+----------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+
+Wrap the the current color of the light and returned as an hsv color object.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++---------------+------------+
+| Field name | Data type |
++===============+============+
+| hsvcolor | Object |
++---------------+------------+
+
+The ``hsvcolor`` object contains the following attributes :
+
++---------------+------------+-----------------------+-----------------------+
+| Field name | Data type | Minimum allowed value | Maximum allowed value |
++===============+============+=======================+=======================+
+| hue | Integer | 0 | 359 |
++---------------+------------+-----------------------+-----------------------+
+| saturation | Integer | 0 | 255 |
++---------------+------------+-----------------------+-----------------------+
+| value | Integer | 0 | 255 |
++---------------+------------+-----------------------+-----------------------+
+
+|
+|
+|
+
+
+SourceSelectionContainer *extends RequestSucceededContainer*
+------------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+
+The source selection container contains a list of sources available into the device.
+
+Object layout:
+^^^^^^^^^^^^^^
+
+The ``SourceSelectionContainer`` is an array of ``available_source`` objects. The layout of a ``available_source`` object is described as follow :
+
++---------------+------------+
+| Field name | Data type |
++===============+============+
+| id | Integer |
++---------------+------------+
+| name | String |
++---------------+------------+
+
+The ``SourceSelectionContainer`` contains a ''current_source'' object too. This object is always present into the object.
+This object contains a shortcut to the current object of the available source.
+
+|
+|
+|
+
+SongQueueContentListContainer *extends RequestSucceededContainer*
+-----------------------------------------------------------------
+
+Description:
+^^^^^^^^^^^^
+Contains informations about the song queue of the AwoX Audio Device.
+
+Object layout:
+^^^^^^^^^^^^^^
+
++------------------------+------------+
+| Field name | Data type |
++========================+============+
+| song_queue | Array |
++------------------------+------------+
+| repeat_mode | String |
++------------------------+------------+
+| shuffle_mode | Boolean |
++------------------------+------------+
+| song_selected_position | Integer |
++------------------------+------------+
+| active_state | Boolean |
++------------------------+------------+
+
+The ``song_queue`` attribute is an array of ``Song`` objects. The layout of a ``Song`` object is described as follow :
+
++------------------+------------+
+| Field name | Data type |
++==================+============+
+| uri | String |
++------------------+------------+
+| info | Object |
++------------------+------------+
+
+:repeat_mode: The pair value can be ''repeat_none'', ''repeat_one'' or ''repeat_all''
+
+:shuffle_mode: The pair value is equal to ''true'' if the shuffle is turn on, ''false'' otherwise
+
+:song_selected_position: The pair value is a number indicating the current song selected position. -1 is returned if no position has been set or if the song queue is empty
+
+:active_state: The pair value is equal to ''true'' if the song queue is active, ''false'' otherwise
+
+|
+|
+|
diff --git a/src/restd/doc/source/api-reference.rst b/src/restd/doc/source/api-reference.rst
new file mode 100644
index 00000000..6093815d
--- /dev/null
+++ b/src/restd/doc/source/api-reference.rst
@@ -0,0 +1,22 @@
+API Reference
+=============
+
+This page contains the links pointing to the various API related documents that are relevant for developers.
+
+
+.. toctree::
+ :maxdepth: 3
+
+ history
+ about-the-api
+ understanding-the-api
+ device-discovery
+ api-models
+ network-api
+ system-api
+ hardware-api
+ alarm-api
+ mixer-api
+ player-api
+ songqueue-api
+ light-api
diff --git a/src/restd/doc/source/conf.py b/src/restd/doc/source/conf.py
new file mode 100644
index 00000000..e78f2d9f
--- /dev/null
+++ b/src/restd/doc/source/conf.py
@@ -0,0 +1,246 @@
+# -*- coding: utf-8 -*-
+#
+# Awox Audio Striim Documentation build configuration file, created by
+# sphinx-quickstart on Wed Apr 2 09:55:54 2014.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'hidden_code_block']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['sphinx_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'AwoX Audio Striim'
+copyright = u'2015, AwoX'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.6'
+# The full version, including alpha/beta/rc tags.
+release = '1.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'sphinx_rtd_theme'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = ["sphinx_templates", ]
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# " v documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['sphinx_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+html_show_sourcelink = False
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+html_show_sphinx = False
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'AwoxAudioStriim-doc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'AwowAudioStriim-Documentation.tex', u'Awox Audio Striim Documentation',
+ u'Awox', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'AwowAudioStriim-Documentation', u'Awox Audio Striim Documentation',
+ [u'AwoX'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'AwowAudioStriim-Documentation', u'Awox Audio Striim Documentation',
+ u'Awox', 'AwowAudioStriim-Documentation', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'http://docs.python.org/': None}
diff --git a/src/restd/doc/source/device-discovery.rst b/src/restd/doc/source/device-discovery.rst
new file mode 100644
index 00000000..71b5daa2
--- /dev/null
+++ b/src/restd/doc/source/device-discovery.rst
@@ -0,0 +1,45 @@
+How to identify the device on the network
+=========================================
+
+When you start a remote app on a third party device, and want to communicate with an AwoX Striim's API, you want to know whether it is present on your network or not. Get the IP address and the Port of API. To do so, several solutions are possible :
+
+- Searching for the device on ``UPnP``
+ - Searching for the device during 2x 10 seconds seems reasonable (searching for 5 seconds, and if the device has not been found issue another request. This is sometimes helpful because the discovery process is based on UDP, which is unreliable interms of data transmission). With the ''UPnP'' stack, you can get the IP addess of the Device. the API port is always 34000.
+
+- Direct connect on the Access Point of the Device.
+ - If a the Striim device is not connected to any devive an Access Point is exposed.
+ - Connect a Device to the AP Verifying the name of the access point
+ - Verifying the underlying subnetwork an IP address you are using
+ - Verifying if the device is reachable on the ``192.168.0.1`` address (this is the predefined address used to mount the access point).
+
+- Searching for the device on ``mDNS``
+ - The device broadcasts the “_awox-api._tcp.” service.
+ - On iOS devices, you can use a NSNetServiceBrowser.
+ - On Android devices, you can use Network Service Discovery or JmDNS.
+ - On the TXT record you can obtain the following information:
+ - api_version: The current API version on the
+ - Dashboard: Contains the URI of th dashboard of the Device (Web App)
+
+
+
+Building the API request URL
+----------------------------
+
+Once you’ve discovered a Device on the local network you can access the API at the following URL:
+
+http://[device_ip]:[api_port]/[api_url]
+
+Example:
+::
+
+ http://192.168.0.1:34000/System/DeviceInfo.json
+
+
+Dashboard
+---------
+The Device contains a Web App do access to all the settings and the information of the device.
+This Web App is a View of the API exposed by the Device.
+
+::
+
+ http://[x.x.x.x]:34000/dashboard/
diff --git a/src/restd/doc/source/hardware-api.rst b/src/restd/doc/source/hardware-api.rst
new file mode 100644
index 00000000..43ec142a
--- /dev/null
+++ b/src/restd/doc/source/hardware-api.rst
@@ -0,0 +1,129 @@
+Hardware programming interface
+==============================
+
+A description of the available programming interfaces used to interact with hardware components.
+
+.. _Hardware-Summary:
+
+Summary
+~~~~~~~
+
+============================ ========================== ===========
+Chapter JSon URL HTTP Method
+============================ ========================== ===========
+:ref:`Hardware/Cpu/Info` /Hardware/Cpu/Info.json GET
+:ref:`Hardware/Memory/Info` /Hardware/Memory/Info.json GET
+============================ ========================== ===========
+
+
+.. _Hardware/Cpu/Info:
+
+Retrieving metrics about the CPU
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Description
+^^^^^^^^^^^
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /Hardware/Cpu/Info.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+
+This route returns metrics about the device's current CPU state.
+
+Parameters
+^^^^^^^^^^
+
+None.
+
+
+Expected responses
+^^^^^^^^^^^^^^^^^^
+
++---------------+--------------------------+-------------------------------+--------------------------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+==========================+===============================+========================================================+
+| 200 | ``Passed`` | ``CpuInfoContainer`` | The CPU metrics have been successfully returned. |
++---------------+--------------------------+-------------------------------+--------------------------------------------------------+
+
+Response example
+^^^^^^^^^^^^^^^^
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "load": 10,
+ "id": "/Hardware/Cpu/Info.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+.. _Hardware/Memory/Info:
+
+Retrieving metrics about memory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Description
+^^^^^^^^^^^
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /Hardware/Memory/Info.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+
+This route returns metrics about the device's current memory state.
+
+Parameters
+^^^^^^^^^^
+
+None.
+
+
+Expected responses
+^^^^^^^^^^^^^^^^^^
+
++---------------+--------------------------+-------------------------------+--------------------------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+==========================+===============================+========================================================+
+| 200 | ``Passed`` | ``MemoryInfoContainer`` | The memory metrics have been successfully returned. |
++---------------+--------------------------+-------------------------------+--------------------------------------------------------+
+
+Response example
+^^^^^^^^^^^^^^^^
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "memory_info": {
+ "total_memory": 61412,
+ "available_memory": 9592,
+ "used_memory": 51820,
+ "cached": 32572
+ },
+ "id": "/Hardware/Memory/Info.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
diff --git a/src/restd/doc/source/hidden_code_block.py b/src/restd/doc/source/hidden_code_block.py
new file mode 100644
index 00000000..bddb4b44
--- /dev/null
+++ b/src/restd/doc/source/hidden_code_block.py
@@ -0,0 +1,128 @@
+"""Simple, inelegant Sphinx extension which adds a directive for a
+highlighted code-block that may be toggled hidden and shown in HTML.
+This is possibly useful for teaching courses.
+
+The directive, like the standard code-block directive, takes
+a language argument and an optional linenos parameter. The
+hidden-code-block adds starthidden and label as optional
+parameters.
+
+Examples:
+
+.. hidden-code-block:: python
+ :starthidden: False
+
+ a = 10
+ b = a + 5
+
+.. hidden-code-block:: python
+ :label: --- SHOW/HIDE ---
+
+ x = 10
+ y = x + 5
+
+Thanks to http://www.javascriptkit.com/javatutors/dom3.shtml for
+inspiration on the javascript.
+
+Thanks to Milad 'animal' Fatenejad for suggesting this extension
+in the first place.
+
+Written by Anthony 'el Scopz' Scopatz, January 2012.
+
+Released under the WTFPL (http://sam.zoy.org/wtfpl/).
+"""
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from sphinx.directives.code import CodeBlock
+from sphinx.util.compat import make_admonition
+
+HCB_COUNTER = 0
+
+js_showhide = """\
+
+"""
+
+def nice_bool(arg):
+ tvalues = ('true', 't', 'yes', 'y')
+ fvalues = ('false', 'f', 'no', 'n')
+ arg = directives.choice(arg, tvalues + fvalues)
+ return arg in tvalues
+
+
+class hidden_code_block(nodes.General, nodes.FixedTextElement):
+ pass
+
+
+class HiddenCodeBlock(CodeBlock):
+ """Hidden code block is Hidden"""
+
+ option_spec = dict(starthidden=nice_bool,
+ label=str,
+ **CodeBlock.option_spec)
+
+ def run(self):
+ # Body of the method is more or less copied from CodeBlock
+ code = u'\n'.join(self.content)
+ hcb = hidden_code_block(code, code)
+ hcb['language'] = self.arguments[0]
+ hcb['linenos'] = 'linenos' in self.options
+ hcb['starthidden'] = self.options.get('starthidden', True)
+ hcb['label'] = self.options.get('label', '+ show/hide code')
+ hcb.line = self.lineno
+ return [hcb]
+
+
+def visit_hcb_html(self, node):
+ """Visit hidden code block"""
+ global HCB_COUNTER
+ HCB_COUNTER += 1
+
+ # We want to use the original highlighter so that we don't
+ # have to reimplement it. However it raises a SkipNode
+ # error at the end of the function call. Thus we intercept
+ # it and raise it again later.
+ try:
+ self.visit_literal_block(node)
+ except nodes.SkipNode:
+ pass
+
+ # The last element of the body should be the literal code
+ # block that was just made.
+ code_block = self.body[-1]
+
+ fill_header = {'divname': 'hiddencodeblock{0}'.format(HCB_COUNTER),
+ 'startdisplay': 'none' if node['starthidden'] else 'block',
+ 'label': node.get('label'),
+ }
+
+ divheader = (""""""
+ """{label} """
+ '''
+{%- endblock %}
+
+
+
diff --git a/src/restd/doc/source/sphinx_templates/sphinx_rtd_theme/search.html b/src/restd/doc/source/sphinx_templates/sphinx_rtd_theme/search.html
new file mode 100644
index 00000000..e3aa9b5c
--- /dev/null
+++ b/src/restd/doc/source/sphinx_templates/sphinx_rtd_theme/search.html
@@ -0,0 +1,50 @@
+{#
+ basic/search.html
+ ~~~~~~~~~~~~~~~~~
+
+ Template for the search page.
+
+ :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{%- extends "layout.html" %}
+{% set title = _('Search') %}
+{% set script_files = script_files + ['_static/searchtools.js'] %}
+{% block footer %}
+
+ {# this is used when loading the search index using $.ajax fails,
+ such as on Chrome for documents on localhost #}
+
+ {{ super() }}
+{% endblock %}
+{% block body %}
+
+
+ {% if search_performed %}
+
{{ _('Search Results') }}
+ {% if not search_results %}
+
{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}
+ {% endif %}
+ {% endif %}
+
+ {% if search_results %}
+
+ {% for href, caption, context in search_results %}
+
+
+ Free document hosting provided by Read the Docs.
+
+
+
+{% endif %}
+
diff --git a/src/restd/doc/source/system-api.rst b/src/restd/doc/source/system-api.rst
new file mode 100644
index 00000000..8021bc6b
--- /dev/null
+++ b/src/restd/doc/source/system-api.rst
@@ -0,0 +1,817 @@
+System programming interface
+============================
+
+A description of the available programming interfaces used to interact with system components.
+
+.. _System-Summary:
+
+Summary
+~~~~~~~
+
+=================================== ============================== ===========
+Chapter JSon URL HTTP Method
+=================================== ============================== ===========
+:ref:`System/Reset/Put` /System/Reset.json PUT/POST
+:ref:`System/Reboot/Put` /System/Reboot.json PUT/POST
+:ref:`System/Locale/Get` /System/Locale.json GET
+:ref:`System/Locale/Put` /System/Locale.json PUT/POST
+:ref:`System/Timezone/Get` /System/Timezone.json GET
+:ref:`System/Timezone/Put` /System/Timezone.json PUT/POST
+:ref:`System/RangeExtender/Get` /System/RangeExtender.json GET
+:ref:`System/RangeExtender/Put` /System/RangeExtender.json PUT/POST
+:ref:`System/FriendlyName/Get` /System/FriendlyName.json GET
+:ref:`System/FriendlyName/Put` /System/FriendlyName.json PUT/POST
+:ref:`System/SoundNotification/Get` /System/SoundNotification.json GET
+:ref:`System/SoundNotification/Put` /System/SoundNotification.json PUT/POST
+:ref:`System/DeviceInfo/Get` /System/DeviceInfo.json GET
+=================================== ============================== ===========
+
+
+.. _System/Reset/Put:
+
+Performing a factory reset
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/Reset.json
+HTTP Method POST | PUT
+Response format ``application/json``
+======================== ==============================
+
+Description
+-----------
+
+Used to restore the default factory parameters of the device. This will cause the device to reboot and will erase all the user settings.
+
+
+Parameters
+----------
+
+None.
+
+Example request
+---------------
+::
+
+ http://[x.x.x.x]:34000/System/Reset.json
+
+Expected responses
+------------------
+
++---------------+--------------------------+-------------------------------+---------------------------------------------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+==========================+===============================+===========================================================================+
+| 200 | ``Passed`` | ``RequestSucceededContainer`` | The device will reboot shortly and the user settings will be erased. |
++---------------+--------------------------+-------------------------------+---------------------------------------------------------------------------+
+
+Response example
+----------------
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "id": "/System/Reset.json",
+ "status": "passed",
+ "return_code": 200
+ }
+
+
+|
+|
+|
+
+
+.. _System/Reboot/Put:
+
+Rebooting the device
+~~~~~~~~~~~~~~~~~~~~
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/Reboot.json
+HTTP Method POST | PUT
+Response format ``application/json``
+======================== ==============================
+
+Description
+-----------
+
+Used to reboot the device.
+
+
+Parameters
+----------
+
+None.
+
+Example request
+---------------
+::
+
+ http://[x.x.x.x]:34000/System/Reboot.json
+
+Expected responses
+------------------
+
++---------------+--------------------------+-------------------------------+-------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+==========================+===============================+=====================================+
+| 200 | ``Passed`` | ``RequestSucceededContainer`` | The device will reboot shortly. |
++---------------+--------------------------+-------------------------------+-------------------------------------+
+
+Response example
+----------------
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "id": "/System/Reboot.json",
+ "status": "passed",
+ "return_code": 200
+ }
+
+
+|
+|
+|
+
+.. _System/Locale/Get:
+
+Retrieving the device locales
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/Locale.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+Description
+-----------
+
+Returns all the available locales as well as the locale that is currently active.
+
+
+Parameters
+----------
+
+None.
+
+Example request
+---------------
+::
+
+ http://[x.x.x.x]:34000/System/Locale.json
+
+Expected responses
+------------------
+
++---------------+--------------------------+----------------------+-------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+==========================+======================+=====================================+
+| 200 | ``Passed`` | ``LocaleContainer`` | The request succeeded. |
++---------------+--------------------------+----------------------+-------------------------------------+
+
+Response example
+----------------
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "available_locale": [{
+ "iso3_language": "fra",
+ "iso3_country": "FRA",
+ "display_name": "français (France)",
+ "display_language": "français",
+ "country": "FR"
+ }],
+ "current_locale": {
+ "iso3_language": "fra",
+ "iso3_country": "FRA",
+ "display_name": "français (France)",
+ "display_language": "français",
+ "country": "FR"
+ },
+ "id": "/System/Locale.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+
+.. _System/Locale/Put:
+
+Updating the device locale
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/Locale.json
+HTTP Method POST | PUT
+Response format ``application/json``
+======================== ==============================
+
+Description
+-----------
+
+Used to change the currently active locale.
+
+
+Parameters
+----------
+
++-----+---------------+-------------+-----------+-------------------+-------------------------------------+
+| # | Name | Mandatory | Data type | Type of parameter | Description |
++=====+===============+=============+===========+===================+=====================================+
+| 1 | language | Yes | String | POST | PUT | The new locale's language ISO3 code |
++-----+---------------+-------------+-----------+-------------------+-------------------------------------+
+
+Example request
+---------------
+::
+
+ http://[x.x.x.x]:34000/System/Locale.json?language=fra
+
+
+Expected responses
+------------------
+
++---------------+--------------------------+-------------------------------+-------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+==========================+===============================+=====================================+
+| 200 | ``Passed`` | ``RequestSuceededContainer`` | The locale was successfully updated |
++---------------+--------------------------+-------------------------------+-------------------------------------+
+
+Response example
+----------------
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "id": "/System/Locale.json",
+ "status": "passed",
+ "return_code": 200
+ }
+
+
+|
+|
+|
+
+.. _System/Timezone/Get:
+
+Retrieving the device timezones
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/Timezone.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+Description
+-----------
+
+Returns all the available device timezones as well as the timezone that is currently active.
+
+
+Parameters
+----------
+
+None.
+
+
+Example request
+---------------
+::
+
+ http://[x.x.x.x]:34000/System/Timezone.json
+
+Expected responses
+------------------
+
++---------------+--------------------------+------------------------+-------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+==========================+========================+=====================================+
+| 200 | ``Passed`` | ``TimezoneContainer`` | The request succeeded. |
++---------------+--------------------------+------------------------+-------------------------------------+
+
+Response example
+----------------
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "available_timezones": [{
+ "id": 1,
+ "offset": " MHT-12",
+ "zone": "Kwajalein",
+ "display_name": "(GMT-12:00) International Date Line West"
+ }, {
+ "..." : "..."
+ }],
+ "current_timezone": {
+ "id": 30,
+ "offset": "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00",
+ "zone": "CET",
+ "display_name": "(GMT+01:00) Brussels, Copenhagen, Madrid, Paris"
+ },
+ "id": "/System/Timezone.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+.. _System/Timezone/Put:
+
+Updating the device timezone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/Timezone.json
+HTTP Method POST | PUT
+Response format ``application/json``
+======================== ==============================
+
+Description
+-----------
+
+Used to change the currently active timezone.
+
+Example request
+---------------
+::
+
+ http://[x.x.x.x]:34000/System/Timezone.json?id=30
+
+Parameters
+----------
+
++-----+---------------+-------------+-----------+-------------------+-------------------------------------+
+| # | Name | Mandatory | Data type | Type of parameter | Description |
++=====+===============+=============+===========+===================+=====================================+
+| 1 | id | Yes | Integer | POST | PUT | The new timezone's id |
++-----+---------------+-------------+-----------+-------------------+-------------------------------------+
+
+
+
+Expected responses
+------------------
+
++---------------+--------------------------+-------------------------------+---------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+==========================+===============================+=======================================+
+| 200 | ``Passed`` | ``RequestSuceededContainer`` | The timezone was successfully updated |
++---------------+--------------------------+-------------------------------+---------------------------------------+
+
+Response example
+----------------
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "id": "/System/Timezone.json",
+ "status": "passed",
+ "return_code": 200
+ }
+
+
+|
+|
+|
+
+.. _System/RangeExtender/Get:
+
+Range Extender
+~~~~~~~~~~~~~~
+
+Get Range Extender State
+------------------------
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/RangeExtender.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+Description
+^^^^^^^^^^^
+
+This function retrieves the current range extender state of the device (ON or OFF). This is a blocking command
+with a timeout duration set to 3 seconds.
+
+Parameters
+^^^^^^^^^^
+
+None
+
+Example request
+^^^^^^^^^^^^^^^
+::
+
+ http://[x.x.x.x]:34000/System/RangeExtenderState.json
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "RangeExtenderState": "off",
+ "id": "/System/RangeExtender.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+.. _System/RangeExtender/Put:
+
+Set Range Extender State
+------------------------
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/RangeExtender.json
+HTTP Method PUT | POST
+Response format ``application/json``
+======================== ==============================
+
+Description
+^^^^^^^^^^^
+
+This function modifies the range extender state (ON or OFF) of devices that use the range extender on demand
+functionality. Once this command has been executed, the Striim device reboots to take into account the new range
+extender state. So, the device will not be reachable during 90 seconds (approximately).
+
+Parameters
+^^^^^^^^^^
+
++-----+--------------------+-------------+-----------+-------------------+
+| # | Name | Mandatory | Data type | Type of parameter |
++=====+====================+=============+===========+===================+
+| 1 | state | Yes | Boolean | PUT / POST |
++-----+--------------------+-------------+-----------+-------------------+
+
+Field details
+"""""""""""""
+
+:state: state could be ''on'' or ''off''
+
+Example request
+^^^^^^^^^^^^^^^
+::
+
+ http://[x.x.x.x]:34000/System/RangeExtender.json?State=[on]
+ http://[x.x.x.x]:34000/System/RangeExtender.json?State=[off]
+
+Response example
+^^^^^^^^^^^^^^^^
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "id": "/System/RangeExtender.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+
+.. _System/FriendlyName/Get:
+
+Get Device FriendlyName
+-----------------------
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/FriendlyName.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+Description
+^^^^^^^^^^^
+
+This function retrieves the current device friendly Name of the Device exposed on the network.
+
+Parameters
+^^^^^^^^^^
+
+None
+
+Example request
+^^^^^^^^^^^^^^^
+::
+
+ http://[x.x.x.x]:34000/System/FriendlyName.json
+
+Response example
+^^^^^^^^^^^^^^^^
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+
+ {
+ "friendly_name": "StriimSOUND-XX-XX",
+ "id": "/System/FriendlyName.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+
+.. _System/FriendlyName/Put:
+
+Device FriendlyName
+~~~~~~~~~~~~~~~~~~~
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/FriendlyName.json
+HTTP Method PUT | POST
+Response format ``application/json``
+======================== ==============================
+
+Description
+-----------
+
+This function modifies the friendly name of the following applications: DMR, DMS and Castafiore (Slave player
+and Light management service).
+Once this command has been executed, the corresponding applications are restarted to take into account the new
+friendly name.
+
+
+Parameters
+----------
+
++-----+--------------------+-------------+-----------+-------------------+
+| # | Name | Mandatory | Data type | Type of parameter |
++=====+====================+=============+===========+===================+
+| 1 | FriendlyName | Yes | String | PUT / POST |
++-----+--------------------+-------------+-----------+-------------------+
+
+
+Field details
+^^^^^^^^^^^^^
+
+:FriendlyName: a New Device FriendlyName for the DMR and the DMS
+
+
+Example request
+---------------
+::
+
+ http://[x.x.x.x]:34000/System/FriendlyName.json?FriendlyName=[A Device Friendly Name]
+
+Response example
+----------------
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "id": "/System/FriendlyName.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+
+.. _System/SoundNotification/Get:
+
+Get Sound Notification State.
+-----------------------------
+
+======================== ===============================
+ Key Value JSon
+======================== ===============================
+Resource URL /System/SoundNotification.json
+HTTP Method GET
+Response format ``application/json``
+======================== ===============================
+
+Description
+^^^^^^^^^^^
+
+This function retrieves the Sound Notification state of the device (ON or OFF).
+
+Parameters
+^^^^^^^^^^
+
+None.
+
+Example request
+^^^^^^^^^^^^^^^
+::
+
+ http://[x.x.x.x]:34000/System/SoundNotification.json
+
+
+Response example
+^^^^^^^^^^^^^^^^
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "SoundNotification": "on",
+ "id": "/System/SoundNotification.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+
+.. _System/SoundNotification/Put:
+
+Sound Notification
+~~~~~~~~~~~~~~~~~~
+
+Change Sound Notification State
+-------------------------------
+
+======================== ===============================
+ Key Value JSon
+======================== ===============================
+Resource URL /System/SoundNotification.json
+HTTP Method PUT | POST
+Response format ``application/json``
+======================== ===============================
+
+Description
+^^^^^^^^^^^
+
+This function modifies the Sound Notification state (ON or OFF) of the device. Note that only network notifications
+(connection in progress, connection passed, connection failed) will be affected by this configuration parameter.
+Factory reset and firmware upgrade notifications will always be activated even if the Sound Notification state
+is set to OFF.
+
+Parameters
+^^^^^^^^^^
+
++-----+--------------------+-------------+-----------+-------------------+
+| # | Name | Mandatory | Data type | Type of parameter |
++=====+====================+=============+===========+===================+
+| 1 | state | Yes | Boolean | GET |
++-----+--------------------+-------------+-----------+-------------------+
+
+Field details
+"""""""""""""
+
+:state: state could be ''on'' or ''off''
+
+Example request
+^^^^^^^^^^^^^^^
+::
+
+ http://[x.x.x.x]:34000/System/SoundNotification.json?State=[on]
+ http://[x.x.x.x]:34000/System/SoundNotification.json?State=[off]
+
+Response example
+^^^^^^^^^^^^^^^^
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "id": "/System/SoundNotification.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
+
+
+.. _System/DeviceInfo/Get:
+
+Device Information
+~~~~~~~~~~~~~~~~~~
+
+======================== ==============================
+ Key Value JSon
+======================== ==============================
+Resource URL /System/DeviceInfo.json
+HTTP Method GET
+Response format ``application/json``
+======================== ==============================
+
+Description
+-----------
+
+This function return the information about the Device like the Firmware and Hardware Version.
+
+Parameters
+----------
+
+None.
+
+
+Expected responses
+------------------
+
++---------------+--------------------------+-------------------------------+--------------------------------------------------------+
+| HTTP code | Status | Object type | Description |
++===============+==========================+===============================+========================================================+
+| 200 | ``Passed`` | ``DeviceInfoContainer`` | The Device information have been successfully returned.|
++---------------+--------------------------+-------------------------------+--------------------------------------------------------+
+
+
+Example request
+---------------
+
+::
+
+ http://[x.x.x.x]:34000/System/DeviceInfo.json
+
+Response example
+----------------
+
+.. hidden-code-block:: json
+ :linenos:
+ :label: JSON Response Example (Open/Close)
+
+ {
+ "device_info": {
+ "Manufacturer": "AwoX",
+ "ProductName": "ProductName",
+ "CompanyName": "Awox",
+ "HardwareVersion": "1.0",
+ "SoftwareVersion": "1.1.0",
+ "build_date": "2014-06-25 15h28",
+ "build_revision": "123456",
+ "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ "uptime": 73030,
+ },
+ "id": "/System/DeviceInfo.json",
+ "status": "passed",
+ "response_code": 200
+ }
+
+
+|
+|
+|
diff --git a/src/restd/doc/source/understanding-the-api.rst b/src/restd/doc/source/understanding-the-api.rst
new file mode 100644
index 00000000..406c272e
--- /dev/null
+++ b/src/restd/doc/source/understanding-the-api.rst
@@ -0,0 +1,106 @@
+Understanding the API
+=====================
+
+How does it work ?
+~~~~~~~~~~~~~~~~~~
+
+In an effort to provide the end-user with the ability to efficiently control and customize his device, a *RESTful* HTTP based
+API has been developped on the AwoX Audio Striim Device. It is hosted by a webserver which runs on the port ``34000`` and
+accepts HTTP connections.
+
+Our web service is built to address two important roles : first, he is binding a set of URLs to the right API routes responsible of
+handling an action, such as a Wi-Fi connection request. Next, we use it as a static page provider in order to let the user access a
+full HTML/CSS configuration website.
+The configuration website is an independant application running on the user browser and acts as a client of the WAPI. This allows us
+to both develop and test our API on one side, while integrating our web app on the other side. This also allows us to decouple the
+development of both of them which dramatically speeds up the development/testing part.
+
+Talking to the API
+~~~~~~~~~~~~~~~~~~
+
+Handling CORS request
+^^^^^^^^^^^^^^^^^^^^^
+
+Interacting with an HTTP-based API from a native program or a smartphone app is usally not a big deal. However, interacting
+with it through AJAX Javascript calls can rapidly become a painful experience because of Cross-domain policies. To address
+this kind of issues, the server uses cross-domain resource sharing through the use of specific HTTP headers we are joining to
+the response part :
+
+.. code-block:: http
+
+ Access-Control-Allow-Origin: *
+ Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
+ Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
+
+
+Response objects layout
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The Rest Daemon could responde in XML or in JSon. the two kind of object is provided by the Rest Server.
+
+Every response sent by the WAPI is serialized into an object similarly in XML or in JSon.
+
+Each object that is returned has a specific layout associated to a specific type. Each returned object extends a base
+object which contains three attributes that are sent with every response. This base object has the following representation:
+
+For JSon
+
+.. code-block:: json
+
+ {
+ "id": string,
+ "status": string,
+ "response_code": number
+ }
+
+For Xml
+
+.. code-block:: xml
+
+
+
+
+
+ ...
+
+
+
+The ``id`` field correspond to the request ID we want to do.
+
+The ``Status`` field could be ``passed`` or ``failed`` and correspond of the status of the request.
+
+The ``response_code`` integer is also a representation of the response. In most cases, this code will be equal to the HTTP
+response code sent with the response at HTTP level.
+
+As said before, these fields are embedded in every responses sent by the API. One or more field can be added to the response
+depending on the accessed route.
+A list of all the existing JSON objects is documented in the :doc:`Models` page. You can bind these models to your
+actual class hierarchy in your code when deserializing the JSON/XML response.
+
+Also note that the documentation about each routes will inform you about the potential object types that are expected in the
+response.
+
+Expected Response Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When issuing a request and receiving a response back, you should pay attention to two things : the HTTP response code, which
+is always meaningful, and the JSON object sent in the response. The documentation related to each route provides a detailed
+set of responses that should be expected by the client to receive. Nevertheless, you should not always expect the expectable
+and be sure that your error handlers are correctly handling the following cases for every API call :
+
+ - A ``404`` Object you try to access is not available.
+ - A ``405`` Method Not Allowed response will be issued if the HTTP method is wrong.
+ - A ``412`` Expectation Failed response will be issued if the parameters that are expected with the request are missing or considered invalid.
+ - A ``500`` Internal Server Error response will be issued if a severe error happened server-side. A meaningful textual message can be available within the message attribute of the object to state what did happen.
+
+ - You should be using a timeout on each of your request to advertise a user that something bad happened and that you cannot reach the remote device anymore if a timeout is triggered. A reasonnable value is expected on a LAN.
+
+
+Properly encoding the request
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We expect the characters you send us to be encoded in UTF-8. This should be pretty straightforward if you work on Android
+or iOS. We also need your parameters to be properly percent-encoded (also referred as URL encoding).
+
+The strings wrapped in the response we will send you back will also be UTF-8 encoded and percent-encoded.
+
diff --git a/src/restd/src/authorize.cpp b/src/restd/src/authorize.cpp
new file mode 100644
index 00000000..996123df
--- /dev/null
+++ b/src/restd/src/authorize.cpp
@@ -0,0 +1,266 @@
+/*!
+ * authorize.cpp
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 04/03/2015
+ *
+ */
+
+/*-------------------------------- INCLUDES ---------------------------------*/
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include "restd.h"
+
+#include "authorize.h"
+#include "session.h"
+#include "message.h"
+
+
+/*-------------------------------- GLOBALE ---------------------------------*/
+
+static const char *gAuthorize_Url = "/authorize";
+static const char *gLogin_Url = "/login.html";
+
+/*--------------------------- LOCAL FUNCTIONS -------------------------------*/
+
+static void redirect_to_ssl (struct mg_connection *aConn,
+ const struct mg_request_info *aRequest_info);
+static void redirect_to_login (struct mg_connection *aConn,
+ const struct mg_request_info *aRequest_info);
+static int is_authorized (const struct mg_connection *aConn,
+ const struct mg_request_info *aRequest_info);
+static void authorize (struct mg_connection *aConn,
+ const struct mg_request_info *aRequest_info);
+int check_password (const char *aUser, const char *aPassword);
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn my_strlcpy
+ *
+ * @brief TODO
+ */
+static void my_strlcpy (char *dst, const char *src, size_t len)
+{
+ strncpy(dst, src, len);
+ dst[len - 1] = '\0';
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn begin_request_handler
+ *
+ * @brief TODO.
+ */
+int begin_request_handler (struct mg_connection *aConn)
+{
+ const struct mg_request_info *theRequest_Info = mg_get_request_info (aConn);
+ int theProcessed = 1;
+
+ printf ("begin_request_handler: request_info->uri%s\n", theRequest_Info->uri);
+
+ if (!theRequest_Info->is_ssl) {
+
+ printf ("clear request => redirect to ssl.\n");
+ redirect_to_ssl (aConn, theRequest_Info);
+ }
+ else if (!is_authorized (aConn, theRequest_Info)) {
+
+ printf ("Redirect to the login page.\n");
+ redirect_to_login (aConn, theRequest_Info);
+ }
+ else if (strcmp (theRequest_Info->uri, gAuthorize_Url) == 0) {
+
+ printf ("Redirect to authorize.\n");
+ authorize (aConn, theRequest_Info);
+ }
+ else {
+ // No suitable handler found, mark as not processed. Civetweb will
+ // try to serve the request.
+ theProcessed = 0;
+ }
+
+ return theProcessed;
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn redirect_to_ssl
+ *
+ * @brief This method force the reconnection to the https port, if we try to
+ access with an http request.
+ */
+static void redirect_to_ssl (struct mg_connection *aConn,
+ const struct mg_request_info *aRequest_info)
+{
+ const char *aP, *anHost = mg_get_header (aConn, "Host");
+
+ if (anHost != NULL && (aP = strchr (anHost, ':')) != NULL) {
+
+ mg_printf (aConn, "HTTP/1.1 302 Found\r\n"
+ "Location: https://%.*s:8082/%s:8082\r\n\r\n",
+ (int) (aP - anHost), anHost, aRequest_info->uri);
+ }
+ else {
+
+ mg_printf (aConn, "%s", "HTTP/1.1 500 Error\r\n\r\nHost: header is not set");
+ }
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn redirect_to_login
+ *
+ * @brief Redirect user to the login form. In the cookie, store the original URL
+ * we came from, so that after the authorization we could redirect back.
+ */
+static void redirect_to_login (struct mg_connection *aConn,
+ const struct mg_request_info *aRequest_info)
+{
+ mg_printf (aConn, "HTTP/1.1 302 Found\r\n"
+ "Set-Cookie: original_url=%s\r\n"
+ "Location: %s\r\n\r\n",
+ aRequest_info->uri, gLogin_Url);
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn is_authorized
+ *
+ * @brief Return 1 if request is authorized, 0 otherwise.
+ */
+static int is_authorized (const struct mg_connection *aConn,
+ const struct mg_request_info *aRequest_info)
+{
+ struct session *session;
+ char valid_id[33];
+ int authorized = 0;
+
+ // Always authorize accesses to login page and to authorize URI
+ if (!strcmp (aRequest_info->uri, gLogin_Url) ||
+ !strcmp (aRequest_info->uri, gAuthorize_Url)) {
+ return 1;
+ }
+
+ pthread_rwlock_rdlock (&gRwlock);
+ if ((session = get_session (aConn)) != NULL) {
+ generate_session_id (valid_id, session->random, session->user);
+ if (strcmp (valid_id, session->session_id) == 0) {
+ session->expire = time(0) + SESSION_TTL;
+ authorized = 1;
+ }
+ }
+ pthread_rwlock_unlock (&gRwlock);
+
+ return authorized;
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn authorize
+ *
+ * @brief A handler for the /authorize endpoint.
+ * Login page form sends user name and password to this endpoint.
+ */
+static void authorize (struct mg_connection *aConn,
+ const struct mg_request_info *aRequest_info)
+{
+ char user[MAX_USER_LEN], password[MAX_USER_LEN];
+ struct session *session;
+
+ // Fetch user name and password.
+ get_qsvar (aRequest_info, "user", user, sizeof (user));
+ get_qsvar (aRequest_info, "password", password, sizeof (password));
+
+ if (check_password (user, password) && (session = new_session()) != NULL) {
+
+ /* Authentication success:
+ * 1. create new session
+ * 2. set session ID token in the cookie
+ * 3. remove original_url from the cookie - not needed anymore
+ * 4. redirect client back to the original URL
+ *
+ * The most secure way is to stay HTTPS all the time. However, just to
+ * show the technique, we redirect to HTTP after the successful
+ * authentication. The danger of doing this is that session cookie can
+ * be stolen and an attacker may impersonate the user.
+ * Secure application must use HTTPS all the time.
+ */
+ my_strlcpy (session->user, user, sizeof (session->user));
+ snprintf (session->random, sizeof (session->random), "%d", rand());
+ generate_session_id (session->session_id, session->random, session->user);
+ send_server_message ("<%s> joined", session->user);
+ mg_printf (aConn, "HTTP/1.1 302 Found\r\n"
+ "Set-Cookie: session=%s; max-age=3600; http-only\r\n" // Session ID
+ "Set-Cookie: user=%s\r\n" // Set user, needed by Javascript code
+ "Set-Cookie: original_url=/; max-age=0\r\n" // Delete original_url
+ "Location: /\r\n\r\n",
+ session->session_id, session->user);
+ } else {
+ // Authentication failure, redirect to login.
+ redirect_to_login (aConn, aRequest_info);
+ }
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn check_password
+ *
+ * @brief TODO.
+ */
+int check_password (const char *aUser, const char *aPassword)
+{
+ int theResult;
+ Json::Value theRoot;
+ Json::Value theUsers;
+ Json::Reader theReader;
+ std::ifstream thePassFile ("./rsc/users.json");
+
+ if (!theReader.parse (thePassFile, theRoot)) {
+
+ fprintf (stderr, "Failed to parse the User File.\n");
+ return 0;
+ }
+
+ for (const Json::Value& theUser : theRoot["users"]) {
+
+ if (theUser["login"].asString() == aUser) {
+
+ char *theCrypted;
+ theCrypted = crypt (aPassword, theUser["password"].asString().c_str());
+
+ printf ("compare: <%s> AND <%s> \n", theCrypted, theUser["password"].asString().c_str());
+
+ theResult = strcmp (theCrypted, theUser["password"].asString().c_str()) == 0;
+ printf ("resultat : %d\n", theResult);
+ }
+ }
+
+ printf ("check_password - done\n");
+
+ return theResult;
+}
diff --git a/src/restd/src/authorize.h b/src/restd/src/authorize.h
new file mode 100644
index 00000000..c30f982b
--- /dev/null
+++ b/src/restd/src/authorize.h
@@ -0,0 +1,38 @@
+/*!
+ * authorize.h
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 11/03/2015
+ *
+ */
+
+#ifndef _AUTHORIZE_H
+#define _AUTHORIZE_H
+
+/*------------------------------- INCLUDES ----------------------------------*/
+
+
+/*--------------------------------- Define ----------------------------------*/
+
+
+int begin_request_handler (struct mg_connection *conn);
+
+
+#endif /* _AUTHORIZE_H */
diff --git a/src/restd/src/main.cpp b/src/restd/src/main.cpp
new file mode 100644
index 00000000..0b237f2e
--- /dev/null
+++ b/src/restd/src/main.cpp
@@ -0,0 +1,329 @@
+/*!
+ * main.cpp
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 04/03/2015
+ *
+ */
+
+/*-------------------------------- INCLUDES ---------------------------------*/
+
+#include
+#include
+#include
+
+#include "routes/UbusHandler.h"
+#include "routes/ExitHandler.h"
+
+#include "authorize.h"
+#include "restd.h"
+
+/*-------------------------------- GLOBALE ---------------------------------*/
+
+bool gExitNow = false;
+
+pthread_rwlock_t gRwlock = PTHREAD_RWLOCK_INITIALIZER;
+
+#define kDocument_root "html"
+#define PORT "8081"
+#define EXAMPLE_URI "/example"
+#define EXIT_URI "/exit"
+
+/*! ----------------------------------------------------------------------------
+ * @fn main
+ *
+ * @brief Main function of Rest Daemon.
+ */
+int main (void)
+{
+ const char *theOptions[] = {
+ "document_root", "html",
+ "listening_ports", "8081",
+ 0};
+
+ CivetServer theServer (theOptions);
+
+ printf("Browse files at http://localhost:%s/\n", PORT);
+ printf("Run example at http://localhost:%s%s\n", PORT, EXAMPLE_URI);
+ printf("Exit at http://localhost:%s%s\n", PORT, EXIT_URI);
+
+ /* Capabilities. */
+ theServer.addHandler ("/v1/capabilities",
+ new UBusHandler ("domo.capabilities"));
+
+ /* Lights */
+ theServer.addHandler ("/v1/capabilities/lights",
+ new UBusHandler ("domo.capabilities.lights"));
+
+ /* Shutter */
+ theServer.addHandler ("/v1/capabilities/shutter",
+ new UBusHandler ("domo.capabilities.shutter"));
+
+ /* sprinklers */
+ theServer.addHandler ("/v1/capabilities/sprinklers",
+ new UBusHandler ("domo.capabilities.sprinklers"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/open",
+ new UBusHandler ("domo.capabilities.sprinklers", "open"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/close",
+ new UBusHandler ("domo.capabilities.sprinklers", "close"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/up",
+ new UBusHandler ("domo.capabilities.sprinklers", "up"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/down",
+ new UBusHandler ("domo.capabilities.sprinklers", "down"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/position",
+ new UBusHandler ("domo.capabilities.sprinklers", "position"));
+
+ /* Speach Command. */
+ theServer.addHandler ("/v1/speach",
+ new UBusHandler ("domo.speach.command"));
+
+ printf ("Rest Daemon started on ports %s...\n",
+ mg_get_option (theServer.getContext(), "listening_ports"));
+
+ while (!gExitNow) {
+ sleep(1);
+ }
+
+ printf("Bye!\n");
+
+ return 0;
+
+
+}
+
+
+int main_ssl (void)
+{
+ struct mg_callbacks theCallbacks;
+
+ const char *theOptions[] = {
+ "document_root", "html",
+ "put_delete_auth_file", "/tmp/passfile",
+ "listening_ports", "8081,8082s",
+ "ssl_certificate", "ssl_cert.pem",
+ "num_threads", "5",
+ NULL
+ };
+
+ // Initialize random number generator. It will be used later on for
+ // the session identifier creation.
+ srand ((unsigned) time(0));
+
+ memset (&theCallbacks, 0, sizeof (theCallbacks));
+#ifndef DEBUG_SECURIRY
+ theCallbacks.begin_request = begin_request_handler;
+#endif
+
+ CivetServer theServer (theOptions, &theCallbacks);
+
+#ifdef DEBUG_SECURIRY
+ theServer.addHandler ("/Exit", new ExitHandler());
+#endif
+
+ /* Capabilities. */
+ theServer.addHandler ("/v1/capabilities",
+ new UBusHandler ("domo.capabilities"));
+
+ /* Lights */
+ theServer.addHandler ("/v1/capabilities/lights",
+ new UBusHandler ("domo.capabilities.lights"));
+
+ /* Shutter */
+ theServer.addHandler ("/v1/capabilities/shutter",
+ new UBusHandler ("domo.capabilities.shutter"));
+
+ /* sprinklers */
+ theServer.addHandler ("/v1/capabilities/sprinklers",
+ new UBusHandler ("domo.capabilities.sprinklers"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/open",
+ new UBusHandler ("domo.capabilities.sprinklers", "open"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/close",
+ new UBusHandler ("domo.capabilities.sprinklers", "close"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/up",
+ new UBusHandler ("domo.capabilities.sprinklers", "up"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/down",
+ new UBusHandler ("domo.capabilities.sprinklers", "down"));
+
+ theServer.addHandler ("/v1/capabilities/sprinklers/position",
+ new UBusHandler ("domo.capabilities.sprinklers", "position"));
+
+ /* Speach Command. */
+ theServer.addHandler ("/v1/speach",
+ new UBusHandler ("domo.speach.command"));
+
+ printf ("Rest Daemon started on ports %s...\n",
+ mg_get_option (theServer.getContext(), "listening_ports"));
+
+
+ /* Infinite loop. */
+ while (!gExitNow) {
+
+ sleep (1);
+ }
+
+ printf("Bye!\n");
+
+ return 0;
+}
+
+
+#if 0
+
+/ Simple example program on how to use Embedded C++ interface.
+
+#include "CivetServer.h"
+
+#ifdef _WIN32
+#include
+#else
+#include
+#endif
+
+#define DOCUMENT_ROOT "."
+#define PORT "8081"
+#define EXAMPLE_URI "/example"
+#define EXIT_URI "/exit"
+bool exitNow = false;
+
+class ExampleHandler: public CivetHandler
+{
+public:
+ bool handleGet(CivetServer *server, struct mg_connection *conn) {
+ mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n");
+ mg_printf(conn, "\r\n");
+ mg_printf(conn, "
",
+ req_info->request_method, req_info->uri, req_info->http_version);
+ mg_printf(conn, "\n");
+ return true;
+ }
+};
+
+
+int main(int argc, char *argv[])
+{
+
+ const char * options[] = { "document_root", DOCUMENT_ROOT,
+ "listening_ports", PORT, 0
+ };
+
+ CivetServer server(options);
+
+ server.addHandler(EXAMPLE_URI, new ExampleHandler());
+ server.addHandler(EXIT_URI, new ExitHandler());
+ server.addHandler("/a", new AHandler());
+ server.addHandler("/a/b", new ABHandler());
+ server.addHandler("**.foo$", new FooHandler());
+
+ printf("Browse files at http://localhost:%s/\n", PORT);
+ printf("Run example at http://localhost:%s%s\n", PORT, EXAMPLE_URI);
+ printf("Exit at http://localhost:%s%s\n", PORT, EXIT_URI);
+
+ while (!exitNow) {
+#ifdef _WIN32
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+ }
+
+ printf("Bye!\n");
+
+ return 0;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/restd/src/message.cpp b/src/restd/src/message.cpp
new file mode 100644
index 00000000..dbda9730
--- /dev/null
+++ b/src/restd/src/message.cpp
@@ -0,0 +1,74 @@
+/*!
+ * message.cpp
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 19/03/2015
+ *
+ */
+
+
+/*-------------------------------- INCLUDES ---------------------------------*/
+
+#include
+
+#include "message.h"
+
+/*-------------------------------- GLOBALE ---------------------------------*/
+
+static struct message_t gMessages[MAX_MESSAGES]; // Ringbuffer for messages
+static long gLast_message_id;
+
+static struct message_t *new_message (void);
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn send_server_message
+ *
+ * @brief TODO
+ */
+void send_server_message (const char *fmt, ...)
+{
+ va_list ap;
+ struct message_t *message;
+
+ pthread_rwlock_wrlock (&gRwlock);
+ message = new_message ();
+ message->user[0] = '\0'; // Empty user indicates server message
+ va_start (ap, fmt);
+ vsnprintf(message->text, sizeof (message->text), fmt, ap);
+ va_end (ap);
+
+ pthread_rwlock_unlock (&gRwlock);
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn new_message
+ *
+ * @brief Allocate new message. Caller must hold the lock.
+ */
+static struct message_t *new_message (void)
+{
+ static int size = sizeof (gMessages) / sizeof (gMessages[0]);
+ struct message_t *message = &gMessages[gLast_message_id % size];
+ message->id = gLast_message_id++;
+ message->timestamp = time(0);
+ return message;
+}
diff --git a/src/restd/src/message.h b/src/restd/src/message.h
new file mode 100644
index 00000000..938985c4
--- /dev/null
+++ b/src/restd/src/message.h
@@ -0,0 +1,52 @@
+/*!
+ * message.h
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 19/03/2015
+ *
+ */
+
+#ifndef _MESSAGE_H
+#define _MESSAGE_H
+
+/*------------------------------- INCLUDES ----------------------------------*/
+
+#include "restd.h"
+
+/*--------------------------------- Define ----------------------------------*/
+
+#define MAX_MESSAGES 5
+#define MAX_MESSAGE_LEN 100
+
+// Describes single message sent to a chat. If user is empty (0 length),
+// the message is then originated from the server itself.
+struct message_t {
+ long id; // Message ID
+ char user[MAX_USER_LEN]; // User that have sent the message
+ char text[MAX_MESSAGE_LEN]; // Message text
+ time_t timestamp; // Message timestamp, UTC
+};
+
+
+
+void send_server_message (const char *fmt, ...);
+
+
+#endif /* _MESSAGE_H */
diff --git a/src/restd/src/restd.h b/src/restd/src/restd.h
new file mode 100644
index 00000000..a554f439
--- /dev/null
+++ b/src/restd/src/restd.h
@@ -0,0 +1,49 @@
+/*!
+ * session.h
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 19/03/2015
+ *
+ */
+
+#ifndef _RESTD_H
+#define _RESTD_H
+
+/*------------------------------- INCLUDES ----------------------------------*/
+
+#include
+
+#include
+
+/*--------------------------------- Define ----------------------------------*/
+
+#define DEBUG_SECURIRY 1
+
+#define MAX_USER_LEN 20
+
+#ifndef UNUSED_PARAMETER
+#define UNUSED_PARAMETER(x) (void)(x)
+#endif
+
+
+extern pthread_rwlock_t gRwlock;
+extern bool gExitNow;
+
+#endif /* _RESTD_H */
diff --git a/src/restd/src/routes/ExitHandler.cpp b/src/restd/src/routes/ExitHandler.cpp
new file mode 100644
index 00000000..48f64db0
--- /dev/null
+++ b/src/restd/src/routes/ExitHandler.cpp
@@ -0,0 +1,45 @@
+/*!
+ * ExitHandler.cpp
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 21/03/2015
+ *
+ */
+
+
+/*-------------------------------- INCLUDES ---------------------------------*/
+
+#include "ExitHandler.h"
+#include "restd.h"
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn handleGet
+ *
+ * @brief Get Method for the Exit route.
+ */
+bool ExitHandler::handleGet (CivetServer *aServer, struct mg_connection *aConn)
+{
+ UNUSED_PARAMETER (aServer);
+ mg_printf (aConn, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n");
+ mg_printf (aConn, "Bye!\n");
+ gExitNow = true;
+ return true;
+}
diff --git a/src/restd/src/routes/ExitHandler.h b/src/restd/src/routes/ExitHandler.h
new file mode 100644
index 00000000..86dac14a
--- /dev/null
+++ b/src/restd/src/routes/ExitHandler.h
@@ -0,0 +1,41 @@
+/*!
+ * ExitHandler.h
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 21/03/2015
+ *
+ */
+
+#ifndef _EXIT_HANDLER_H
+#define _EXIT_HANDLER_H
+
+/*-------------------------------- INCLUDES ---------------------------------*/
+
+#include
+
+/*---------------------------------- CLASS ----------------------------------*/
+
+class ExitHandler: public CivetHandler
+{
+public:
+ bool handleGet (CivetServer *aServer, struct mg_connection *aConn);
+};
+
+#endif /* _EXIT_HANDLER_H */
diff --git a/src/restd/src/routes/UbusHandler.cpp b/src/restd/src/routes/UbusHandler.cpp
new file mode 100644
index 00000000..c6ba1f5d
--- /dev/null
+++ b/src/restd/src/routes/UbusHandler.cpp
@@ -0,0 +1,213 @@
+/*!
+ * UbusHandler.cpp
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 21/03/2015
+ *
+ */
+
+/*-------------------------------- INCLUDES ---------------------------------*/
+
+#include
+
+#include
+
+#include
+
+#include "UbusHandler.h"
+
+
+#include "restd.h"
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn UBusHandler
+ *
+ * @brief Constructor of the UBus Handler.
+ */
+UBusHandler::UBusHandler (std::string aRoute, std::string aPostCmd):
+mRoute (aRoute),
+mPostCmd (aPostCmd)
+{
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn handleGet
+ *
+ * @brief Get Method for the Exit route.
+ */
+bool UBusHandler::handleGet (CivetServer *aServer, struct mg_connection *aConn)
+{
+ return Exec ("get", "", aServer, aConn);
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn handleGet
+ *
+ * @brief Get Method for the Exit route.
+ */
+bool UBusHandler::handlePost (CivetServer *aServer, struct mg_connection *aConn)
+{
+ int thePostDataLen;
+ char thePostData[1024];
+ //const struct mg_request_info *theReqInfo = mg_get_request_info (aConn);
+
+ UNUSED_PARAMETER (aServer);
+ printf ("Handle Post....\n");
+
+ thePostDataLen = mg_read (aConn, thePostData, sizeof(thePostData));
+
+ printf ("Data: <%s>%d\n", thePostData, thePostDataLen);
+
+ return Exec (mPostCmd, thePostData, aServer, aConn);
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn handleGet
+ *
+ * @brief Get Method for the Exit route.
+ */
+bool UBusHandler::handlePut (CivetServer *aServer, struct mg_connection *conn)
+{
+ printf ("Handle Put....\n");
+ UNUSED_PARAMETER (aServer);
+ UNUSED_PARAMETER (conn);
+// Updates
+ return true;
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn handleGet
+ *
+ * @brief Get Method for the Exit route.
+ */
+bool UBusHandler::handleDelete (CivetServer *aServer, struct mg_connection *conn)
+{
+ printf ("Handle Delete....\n");
+ UNUSED_PARAMETER (aServer);
+ UNUSED_PARAMETER (conn);
+// Delete
+ return true;
+}
+
+/*! ----------------------------------------------------------------------------
+ * @fn Exec
+ *
+ * @brief Get Method for the Exit route.
+ */
+bool UBusHandler::Exec (const std::string &aCommand, const std::string &aParam,
+ CivetServer *aServer, struct mg_connection *aConn)
+{
+ std::string theOutputData;
+ UBusCall theCall;
+ Json::Value theDocument;
+ Json::Reader theReader;
+ Json::StyledWriter theWriter;
+ int theResult;
+ int theResultCode;
+
+ UNUSED_PARAMETER (aServer);
+ std::string theCallResult;
+
+ theResult = theCall.Exec (mRoute, aCommand.c_str(), aParam.c_str(), theCallResult);
+ theResultCode = GetResultCode (theResult);
+
+ if (theResult == 0) {
+
+ if (!theReader.parse (theCallResult, theDocument)) {
+ /* Impossible to parse the result of the command. */
+ fprintf (stderr, "The Data Returned by the command is not a valid JSon.\n");
+ fprintf (stderr, "<%s>\n", theCallResult.c_str());
+ theResult = 406;
+ }
+ else {
+
+ struct mg_request_info *theInfo;
+ theInfo = (struct mg_request_info *)mg_get_request_info (aConn);
+
+ theDocument["id"] = theInfo->uri;
+ theDocument["status"] = mg_get_response_code_text (theResultCode, aConn);
+ theDocument["response_code"] = theResultCode;
+ theOutputData = theWriter.write (theDocument);
+ }
+ }
+
+ /* Add HTTP Headers. for the Responde. */
+ mg_printf (aConn, "HTTP/1.1 %d %s\r\n",
+ theResultCode, mg_get_response_code_text (theResultCode, aConn));
+ mg_printf (aConn, "Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept\r\n");
+ mg_printf (aConn, "Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS\r\n");
+ mg_printf (aConn, "Access-Control-Allow-Origin: *\r\n");
+ mg_printf (aConn, "Cache-Control: no-store, no-cache, must-revalidate, max-age=0\r\n");
+ mg_printf (aConn, "Connection: close\r\n");
+ mg_printf (aConn, "Content-Type: application/json; charset=utf-8\r\n");
+ mg_printf (aConn, "Pragma: no-cache\r\n\r\n");
+
+ /* Add Information into the response JSon. */
+
+ mg_printf (aConn, "%s\n", theOutputData.c_str());
+
+ return true;
+}
+
+
+/*! -----------------------------------------------------------------------
+ * @fn GetResultCode
+ *
+ * @brief TODO.
+ *
+ */
+int UBusHandler::GetResultCode (int anExecResult)
+{
+ int theResultCode;
+
+ switch (anExecResult) {
+ case 0:
+ theResultCode = 200; /* OK */
+ break;
+ case -1:
+ theResultCode = 404; /* HTTP_NOT_FOUND */
+ break;
+ case -2:
+ theResultCode = 507; /* HTTP_INSUFFICIENT_STORAGE */
+ break;
+ case UBUS_STATUS_METHOD_NOT_FOUND:
+ theResultCode = 405; /* HTTP_METHOD_NOT_ALLOWED */
+ break;
+ case -3:
+ theResultCode = 500; /* HTTP_INTERNAL_SERVER_ERROR */
+ break;
+ case -4: // NotImplemented
+ theResultCode = 501; /* HTTP_NOT_IMPLEMENTED */
+ break;
+ case UBUS_STATUS_INVALID_ARGUMENT:
+ theResultCode = 412; /* HTTP_PRECONDITION_FAILED */
+ break;
+ default:
+ theResultCode = 500; // HTTP_INTERNAL_SERVER_ERROR
+ break;
+ }
+
+ return theResultCode;
+}
diff --git a/src/restd/src/routes/UbusHandler.h b/src/restd/src/routes/UbusHandler.h
new file mode 100644
index 00000000..a2a769f2
--- /dev/null
+++ b/src/restd/src/routes/UbusHandler.h
@@ -0,0 +1,58 @@
+/*!
+ * UbusHandler.h
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 21/03/2015
+ *
+ */
+
+#ifndef _UBUS_HANDLER_H
+#define _UBUS_HANDLER_H
+
+/*-------------------------------- INCLUDES ---------------------------------*/
+
+#include
+#include
+
+#include
+
+/*---------------------------------- CLASS ----------------------------------*/
+
+class UBusHandler: public CivetHandler
+{
+public:
+ UBusHandler (std::string aRoute, std::string aPostCmd="post");
+ bool handleGet (CivetServer *aServer, struct mg_connection *aConn);
+ bool handlePost (CivetServer *server, struct mg_connection *conn);
+ bool handlePut (CivetServer *server, struct mg_connection *conn);
+ bool handleDelete (CivetServer *server, struct mg_connection *conn);
+
+private:
+ bool Exec (const std::string &aCommand, const std::string &aParam,
+ CivetServer *aServer, struct mg_connection *aConn);
+ int GetResultCode (int anExecResult);
+
+private:
+ std::string mRoute;
+ std::string mPostCmd;
+};
+
+
+#endif /* _UBUS_HANDLER_H */
diff --git a/src/restd/src/session.cpp b/src/restd/src/session.cpp
new file mode 100644
index 00000000..10dc044b
--- /dev/null
+++ b/src/restd/src/session.cpp
@@ -0,0 +1,107 @@
+/*!
+ * session.cpp
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 19/03/2015
+ *
+ */
+
+/*-------------------------------- INCLUDES ---------------------------------*/
+
+#include
+
+#include "session.h"
+
+/*-------------------------------- GLOBALE ---------------------------------*/
+
+static struct session gSessions [MAX_SESSIONS]; // Current sessions
+
+/*! ----------------------------------------------------------------------------
+ * @fn new_session
+ *
+ * @brief Allocate new session object
+ */
+struct session *new_session (void)
+{
+ int i;
+ time_t now = time(NULL);
+ pthread_rwlock_wrlock (&gRwlock);
+ for (i = 0; i < MAX_SESSIONS; i++) {
+ if (gSessions[i].expire == 0 || gSessions[i].expire < now) {
+ gSessions[i].expire = time(0) + SESSION_TTL;
+ break;
+ }
+ }
+ pthread_rwlock_unlock (&gRwlock);
+ return i == MAX_SESSIONS ? NULL : &gSessions[i];
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn get_session
+ *
+ * @brief Get session object for the connection. Caller must hold the lock.
+ */
+struct session *get_session (const struct mg_connection *aConn)
+{
+ int i;
+ const char *cookie = mg_get_header (aConn, "Cookie");
+ char session_id[33];
+ time_t now = time (NULL);
+
+ mg_get_cookie (cookie, "session", session_id, sizeof(session_id));
+
+ for (i = 0; i < MAX_SESSIONS; i++) {
+
+ if (gSessions[i].expire != 0 &&
+ gSessions[i].expire > now &&
+ strcmp (gSessions[i].session_id, session_id) == 0) {
+ break;
+ }
+ }
+ return i == MAX_SESSIONS ? NULL : &gSessions[i];
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn generate_session_id
+ *
+ * @brief Generate session ID. buf must be 33 bytes in size.
+ * Note that it is easy to steal session cookies by sniffing traffic.
+ * This is why all communication must be SSL-ed.
+ */
+void generate_session_id (char *aBuf, const char *aRandom,
+ const char *anUser)
+{
+ mg_md5 (aBuf, aRandom, anUser, NULL);
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn get_qsvar
+ *
+ * @brief TODO.
+ */
+void get_qsvar (const struct mg_request_info *aRequest_info,
+ const char *aName, char *aDst, size_t aDst_len)
+{
+ const char *qs = aRequest_info->query_string;
+ mg_get_var (qs, strlen(qs == NULL ? "" : qs), aName, aDst, aDst_len);
+}
diff --git a/src/restd/src/session.h b/src/restd/src/session.h
new file mode 100644
index 00000000..3c5eb92f
--- /dev/null
+++ b/src/restd/src/session.h
@@ -0,0 +1,54 @@
+/*!
+ * session.h
+ *
+ * Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * @Author: NADAL Jean-Baptiste
+ * @Date: 19/03/2015
+ *
+ */
+
+#ifndef _SESSION_H
+#define _SESSION_H
+
+/*------------------------------- INCLUDES ----------------------------------*/
+
+#include "restd.h"
+
+/*--------------------------------- Define ----------------------------------*/
+
+#define MAX_SESSIONS 2
+#define SESSION_TTL 120
+
+
+// Describes web session.
+struct session {
+ char session_id[33]; // Session ID, must be unique
+ char random[20]; // Random data used for extra user validation
+ char user[MAX_USER_LEN]; // Authenticated user
+ time_t expire; // Expiration timestamp, UTC
+};
+
+struct session *new_session (void);
+struct session *get_session (const struct mg_connection *aConn);
+void generate_session_id (char *aBuf, const char *aRandom,
+ const char *anUser);
+void get_qsvar (const struct mg_request_info *aRequest_info,
+ const char *aName, char *aDst, size_t aDst_len);
+
+#endif /* _SESSION_H */
diff --git a/src/rf_listener_arduino/rf_listener_arduino.ino b/src/rf_listener_arduino/rf_listener_arduino.ino
new file mode 100644
index 00000000..4c238b8e
--- /dev/null
+++ b/src/rf_listener_arduino/rf_listener_arduino.ino
@@ -0,0 +1,218 @@
+/*
+ * rf_listener_arduino.
+ *
+ */
+
+#include
+
+#define kSlave_Address 0x12
+
+int gGetAddr = 0;
+
+int gRxPin = 3;
+
+unsigned int gTemperatureCelsius;
+unsigned int gRainfallMillimeters;
+
+#define kWeatherInovalley_Frame_LengthBytes 5
+#define kWeatherInovalley_Frame_LengthBytes_WithoutCRC 4
+
+#define kWeatherInovalley_Lock_Min 7500
+#define kWeatherInovalley_Lock_Max 8500
+
+#define kWeatherInovalley_Bit1_Min 3500
+#define kWeatherInovalley_Bit1_Max 4500
+
+#define kWeatherInovalley_Bit0_Min 1500
+#define kWeatherInovalley_Bit0_Max 2500
+
+#define kWeatherInovalley_ReadBit_MaxTimeout kWeatherInovalley_Bit1_Max
+
+#define kWeatherInovalley_Frame_LengthBits (8+4+12+8+5) //8bits=>StationID 4bits=>Unknown 12bits=>Temperature 8bits=>Rainfall 5bits=>CRC
+
+#define kWeatherInovalley_CRC_LengthBits 5
+
+/*! ----------------------------------------------------------------------------
+ * @fn setup
+ *
+ * @brief This function setup the MCU.
+ */
+void setup (void)
+{
+ Serial.begin (9600);
+
+ // Setup I2C
+ Wire.begin (kSlave_Address);
+ Wire.onReceive (receiveData);
+ Wire.onRequest (sendData);
+
+ // Setup
+ pinMode (gRxPin, INPUT);
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn loop
+ *
+ * @brief Main Loop.
+ */
+void loop (void)
+{
+ unsigned char theBuffer[kWeatherInovalley_Frame_LengthBytes];
+ unsigned long thePulse = 0;
+ unsigned int theBitRead = 0;
+ int theRet;
+
+ /* Wait Lock */
+ while ((thePulse < kWeatherInovalley_Lock_Min || thePulse > kWeatherInovalley_Lock_Max)) {
+
+ thePulse = pulseIn (gRxPin, LOW, 1000000);
+ }
+
+ /* Read NEC */
+ theBitRead = readNEC (theBuffer, kWeatherInovalley_Frame_LengthBits);
+ if (theBitRead != kWeatherInovalley_Frame_LengthBits) {
+
+ //Serial.println ("Unable to properly read NEC");
+ //Serial.println(theBitRead);
+ return;
+ }
+
+ /* Verify CRC */
+ theRet = checkCRC (theBuffer, kWeatherInovalley_Frame_LengthBits);
+ if (theRet != 0) {
+
+ //Serial.println ("CRC Failed.");
+ return;
+ }
+
+ /* Extract Data. */
+ gTemperatureCelsius = theBuffer[1] << 8 | theBuffer[2];
+ gRainfallMillimeters = theBuffer[3];
+
+ Serial.print("Temperature: ");
+ Serial.println(gTemperatureCelsius);
+
+ Serial.print("Rainfall: ");
+ Serial.println(gRainfallMillimeters);
+
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn receiveData
+ *
+ * @brief IIC receive data function.
+ */
+void receiveData (int byteCount)
+{
+ while (Wire.available ()) {
+
+ gGetAddr = Wire.read ();
+ Serial.print ("Get Addr: ");
+ Serial.println (gGetAddr);
+ }
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn sendData
+ *
+ * @brief IIC send data function.
+ */
+void sendData (void)
+{
+ if (gGetAddr == 0) {
+
+ Wire.write(gTemperatureCelsius);
+ }
+
+ if (gGetAddr == 1) {
+
+ Wire.write(gRainfallMillimeters);
+ }
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn readNEC
+ *
+ * @brief Read the NEC Protocol.
+ */
+unsigned int readNEC (unsigned char *aBuffer, unsigned int aDataLengthBits)
+{
+ unsigned long thePulseTimeMicro = 0;
+ // unsigned long theStartFunctionTimeMs = mDigitalOutput->nowMicroseconds()/1000;
+ unsigned long theBitRead = 0;
+
+ for (unsigned int i=0; i<(aDataLengthBits/8)+1; i++)
+ aBuffer[i] = 0x00;
+
+ for (theBitRead=0; theBitRead kWeatherInovalley_Bit1_Min && thePulseTimeMicro < kWeatherInovalley_Bit1_Max)
+ {
+ //Bit 1
+ aBuffer[theBitRead/8] |= (1 << (7 - (theBitRead%8)));
+ }
+ else if (thePulseTimeMicro > kWeatherInovalley_Bit0_Min && thePulseTimeMicro < kWeatherInovalley_Bit0_Max)
+ {
+ //Bit 0
+ aBuffer[theBitRead/8] |= (0 << (7 - (theBitRead%8)));
+ }
+ else
+ {
+ break; //Invalid read
+ }
+ }
+
+ return theBitRead;
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn checkCRC
+ *
+ * @brief Read the NEC Protocol.
+ */
+int checkCRC (unsigned char *aBuffer, unsigned int aDataLengthBits)
+{
+ unsigned char theCRCFrame = *(aBuffer + kWeatherInovalley_Frame_LengthBytes_WithoutCRC);
+ theCRCFrame >>= 8 - kWeatherInovalley_CRC_LengthBits;
+
+ unsigned char theCRCComputed = CRC (aBuffer, (aDataLengthBits - kWeatherInovalley_CRC_LengthBits) / 8, theCRCFrame >> 4 & 0x01);
+
+ if (theCRCComputed != theCRCFrame)
+ return -1;
+
+ return 0;
+}
+
+
+/*! ----------------------------------------------------------------------------
+ * @fn CRC
+ *
+ * @brief Compute the CRC.
+ */
+unsigned char CRC (unsigned char *aBuffer, unsigned int aBufferLength, unsigned char aXorOut)
+{
+ unsigned char theCRC = 0x00;
+ unsigned char theWidth = 5;
+ unsigned char thePoly = 0x10;
+
+ theCRC <<= 8 - theWidth;
+ for (unsigned int i=0; i>= 8 - theWidth;
+
+ theCRC = theCRC ^ aXorOut;
+
+ return theCRC;
+}
+
diff --git a/src/sprinklersd/Readme.md b/src/sprinklersd/Readme.md
index 4c077dbd..70dc3b97 100644
--- a/src/sprinklersd/Readme.md
+++ b/src/sprinklersd/Readme.md
@@ -9,3 +9,12 @@ Bonne appli on peut s'en inspirer
https://opensprinkler.com/forums/topic/sprinklers_pi-an-alternative-sprinkler-control-program/
https://github.com/rszimm/sprinklers_pi/
+
+
+## Command used to activate or not a Sprinkler.
+
+>
+>./bin/ucli call sprinkers set "{ \"station\": 7,\"state\": true}"
+>
+>./bin/ucli call sprinkers set "{ \"station\": 7,\"state\": false}"
+>
\ No newline at end of file
diff --git a/src/sprinklersd/src/UbusSprinklerModel.cpp b/src/sprinklersd/src/UbusSprinklerModel.cpp
index c18fb9b0..a6b00a81 100644
--- a/src/sprinklersd/src/UbusSprinklerModel.cpp
+++ b/src/sprinklersd/src/UbusSprinklerModel.cpp
@@ -1,5 +1,5 @@
/*!
- * UBusModel.c
+ * UBusSprinkerModel.cpp
*
* Copyright (c) 2015, NADAL Jean-Baptiste. All rights reserved.
*