aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/controller.md36
-rw-r--r--docs/controllerConfig.md225
2 files changed, 163 insertions, 98 deletions
diff --git a/docs/controller.md b/docs/controller.md
index bf0a3c2..24abcea 100644
--- a/docs/controller.md
+++ b/docs/controller.md
@@ -1,31 +1,43 @@
# Controller
-* Object: Generic Controller to handle Policy,Small Business Logic, Glue in between components, ...
+* Object: Generic Controller to handle Policy, Small Business Logic, Glue in
+ between components, ...
* Status: Release Candidate
* Author: Fulup Ar Foll fulup@iot.bzh
* Date : May-2018
## Features
-* Create a controller application from a JSON config file
* Create a controller application from a JSON config file.
* A controller could be considered as a collection of actions that could be
mapped to a dynamically created verb or when receiving an event from any other
API.
* Actions can either be:
- * Invocation of an other binding API, either internal or external (eg: a policy service, Alsa UCM, ...)
- * C routines from a user provided plugin (eg: policy routine, proprietary code, ...)
- * Lua script function. Lua provides access to every AGL appfw functionality and can be extended by plugins written in C.
+ * Invocation of an other binding API, either internal or external (eg: a
+ policy service, Alsa UCM, ...)
+ * C routines from a user provided plugin (eg: policy routine, proprietary code
+ , ...)
+ * Lua script function. Lua provides access to every AGL appfw functionality
+ and can be extended by plugins written in C.
## Installation
-* Controller can easily be included as a git submodule in any AGL service or application binder.
-* Dependencies: the only dependencies are AGL application framework (https://gerrit.automotivelinux.org/gerrit/p/src/app-framework-binder.git) and app-afb-helpers-submodule (https://gerrit.automotivelinux.org/gerrit/p/apps/app-afb-helpers-submodule.git).
-* Controller relies on Lua-5.3, when not needed Lua might be removed at compilation time.
+* Controller can easily be included as a git submodule in any AGL service or
+ application binder.
+* Dependencies: the only dependencies are [AGL application framework](https://gerrit.automotivelinux.org/gerrit/p/src/app-framework-binder.git)
+ and [app-afb-helpers-submodule](https://gerrit.automotivelinux.org/gerrit/p/apps/app-afb-helpers-submodule.git).
+* Controller relies on Lua-5.3, when not needed Lua might be removed at
+ compilation time.
## Monitoring
-* The default test HTML page expect the monitoring HTML page to be accessible under /monitoring with the --monitoring option.
-* The monitoring HTML pages are installed with the app framework binder in a subdirectory called monitoring.
-* You can add other HTML pages with the alias options e.g. afb-daemon --port=1234 --monitoring --alias=/path1/to/htmlpages:/path2/to/htmlpages --ldpaths=. --workdir=. --roothttp=../htdocs
-* The monitoring is accessible at http://localhost:1234/monitoring. \ No newline at end of file
+* The default test HTML page expect the monitoring HTML page to be accessible
+ under /monitoring with the --monitoring option.
+* The monitoring HTML pages are installed with the app framework binder in a
+ subdirectory called monitoring.
+* The monitoring is accessible at `http://localhost:1234/monitoring`.
+* You can add other HTML pages with the alias options i.e:
+
+```bash
+afb-daemon --name afb-my-binding --port=1234 --monitoring --alias=/path1/to/htmlpages:/path2/to/htmlpages --ldpaths=. --workdir=. --roothttp=../htdocs
+```
diff --git a/docs/controllerConfig.md b/docs/controllerConfig.md
index cf3c007..d260db7 100644
--- a/docs/controllerConfig.md
+++ b/docs/controllerConfig.md
@@ -28,40 +28,46 @@ any other file corresponding to the same path is ignored and only generates a wa
Each block in the configuration file is defined with
-* **uid**: mandatory, it is used either for debugging or as input for the action (eg: signal name, control name, ...)
+* **uid**: mandatory, it is used either for debugging or as input for the action
+ (eg: signal name, control name, ...)
* **info**: optional, it is used for documentation purpose only
-> **Note**: by default the controller config search path is defined at compilation time, but the path might be overloaded with the **CONTROL_CONFIG_PATH**
-> environment variable.
+> **Note**: by default the controller config search path is defined at
+> compilation time, but the path might be overloaded with the
+> **CONTROL_CONFIG_PATH** environment variable.
-## Config is organised in sections
+## Configuration is organised in sections
* **metadata**: describes the configuration
* **plugins or resources**: defines the plugins to be loaded as additionnal
resources (compiled C or lua).
* **onload**: a collection of actions meant to be executed at startup time
-* **control**: sets the controls with a collection of actions, in dynamic api it could also specify the verbs of the api
-* **event**: a collection of actions meant to be executed when receiving a given signal
+* **control**: sets the controls with a collection of actions, in dynamic api it
+ could also specify the verbs of the api
+* **event**: a collection of actions meant to be executed when receiving a given
+ signal
* **personnal sections**: personnal section
-Callbacks to parse sections are documented in [Declare your controller config section in your binding](<#3_Declare_your_controller_config_section_in_your_binding>) section. You can use the callback defined in controller or define your own callback.
+Callbacks to parse sections are documented in [Declare your controller config section in your binding](<#3_Declare_your_controller_config_section_in_your_binding>)
+section. You can use the callback defined in controller or define your own
+callback.
## Metadata
-As today matadata is only used for documentation purpose.
+As today metadata is only used for documentation purpose.
* **uid**: mandatory
* **version**: mandatory
-* **api**: mandatory
+* **api**: mandatory, string which named the API to be created
* **info**: optional
-* **require**: optional
+* **require**: optional, string or array of strings of dependants API's names.
* **author**: optional
* **date**: optional
## OnLoad section
-Onload section defines startup time configuration. Onload may provide multiple initialisation
-profiles, each with a different uid.
+Onload section defines startup time configuration. Onload may provide multiple
+initialisation profiles, each with a different uid.
You can define the following keys or arrays of the following keys:
@@ -84,14 +90,15 @@ this section could be verb api:
explained in the later [Action Elements](<#Action Elements>) chapter.
* **args**: optionnal, action's arguments.
-## Event section
+## Events section
-Event section defines a list of actions to be executed on event reception. Event can do
-anything a controller can (change state, send back signal, ...)
+Events section defines a list of actions to be executed on event reception.
+Event can do anything a controller can (change state, send back signal, ...)
eg: if a controller subscribes to vehicle speed, then speed-event may adjust
master-volume to speed.
-You can define the following keys or arrays of the following keys, moreover you can define an event from an another API with the following syntax "API/event".
+You can define the following keys or arrays of the following keys, moreover you
+can define an event from an another API with the following syntax "API/event".
* **uid**: mandatory must match an event name with format **api/event_name**,
i.e: **low-can/messages.engine.speed**
@@ -102,15 +109,17 @@ You can define the following keys or arrays of the following keys, moreover you
## Plugin section
-Plugin section defines plugins used with this controller. A plugin is a C/C++ program meant to
-execute some tasks after an event or on demand. This easily extends intrinsec
-binding logic for ad-hoc needs.
+Plugin section defines plugins used with this controller. A plugin is a C/C++
+program meant to execute some tasks after an event or on demand. This easily
+extends intrinsec binding logic for ad-hoc needs.
You can define the following keys or arrays of the following keys:
* **uid**: mandatory
* **info**: optionnal
-* **spath**: optionnal, semicolon separated paths where to find the plugin. This could be a compiled shared library or LUA scripts. Could be specified using CONTROL_PLUGIN_PATH environment variable also.
+* **spath**: optionnal, semicolon separated paths where to find the plugin. This
+ could be a compiled shared library or LUA scripts. Could be specified using
+ **CONTROL_PLUGIN_PATH** environment variable also.
* **libs**: mandatory, Plugin file or LUA scripts to load
* **lua**: optionnal, a JSON object listing C functions that could be called
from a LUA script and could prefixed.
@@ -126,20 +135,30 @@ You can define the following keys or arrays of the following keys:
* **args**: optionnal, action's arguments.
* **any keys wanted**: optionnal
-You can define your own sections and add your own callbacks into the
-CtlSectionT structure, see
-[Declare your controller config section in your binding](<#3_Declare_your_controller_config_section_in_your_binding>) section.
+You can define your own sections and add your own callbacks into the CtlSectionT
+structure, see [Declare your controller config section in your binding](<#3_Declare_your_controller_config_section_in_your_binding>)
+section.
-## Actions Categories
+## Action Elements
Controller supports three categories of actions. Each action returns a status
where 0=success and 1=failure.
-* **AppFw API** provides a generic model to request other bindings. Requested bindings can be local (eg: ALSA/UCM) or external (eg: vehicle signalling).
+* **AppFw API** provides a generic model to request other bindings. Requested
+ bindings can be local (eg: ALSA/UCM) or external (eg: vehicle signalling).
* `"action": "api://API_NAME#verb_name"`
-* C-API, when defined in the onload section, the plugin may provide C native API with `CTLP-CAPI(apiname, uid, args, query, context)`. Plugin may also create Lua command with `CTLP-LUA2C(LuaFuncName, uid, args, query, context)`. Where `args`+`query` are JSON-C object and context is the returned value from `CTLP_ONLOAD` function. Any missing value is set to NULL.
+* C-API, when defined in the onload section, the plugin may provide C native API
+ with `CTLP-CAPI(apiname, uid, args, query, context)`. Plugin may also create
+ Lua command with `CTLP-LUA2C(LuaFuncName, uid, args, query, context)`. Where
+ `args`+`query` are JSON-C object and context is the returned value from
+ `CTLP_ONLOAD` function. Any missing value is set to NULL.
* `"action": "plugin://plugin_name#function_name"`
-* Lua-API, when compiled with Lua option, the controller supports action defined directly in Lua script. During "*onload*" phase, the controller searches in `CONTROL_LUA_PATH` file with pattern "(prefix-)bindermiddlename*.lua". Any file corresponding to this pattern is automatically loaded. Any function defined in those Lua scripts can be called through a controller action. Lua functions receive three parameters (uid, args, query).
+* Lua-API, when compiled with Lua option, the controller supports action defined
+ directly in Lua script. During "*onload*" phase, the controller searches in
+ `CONTROL_LUA_PATH` file with pattern "(prefix-)bindermiddlename*.lua". Any file
+ corresponding to this pattern is automatically loaded. Any function defined in
+ those Lua scripts can be called through a controller action. Lua functions
+ receive three parameters (uid, args, query).
* `"action": "lua://plugin_name#function_name"`
You also can add the **privileges** property that handles AGL permission
@@ -152,102 +171,136 @@ the plugin uid or the one you defined in your config (eg: MyPlug:HelloWorld1).
## Available Application Framework Commands
-Each Lua AppFw commands should be prefixed by AFB:
+Each LUA AppFw commands should be prefixed by AFB:
-* `AFB:notice ("format", arg1,... argn)` directly printed LUA tables as json string with '%s'.
- `AFB:error`, `AFB:warning`, `AFB:info`, `AFB:debug` work on the same model. Printed messages are limited to 512 characters.
+* `AFB:notice ("format", arg1,... argn)` directly printed LUA tables as json
+ string with '%s'. `AFB:error`, `AFB:warning`, `AFB:info`, `AFB:debug` work on
+ the same model. Printed messages are limited to 512 characters.
-* `AFB:service ('API', 'VERB', {query}, "Lua_Callback_Name", {context})` is an asynchronous call to another binding. When empty, query/context should be set to '{}'
- and not to 'nil'. When 'nil', Lua does not send 'NULL' value but removes arguments to calling stack. WARNING:"Callback"
- is the name of the callback as a string and not a pointer to the callback. (If someone as a solution to fix this, please
- let me known). Callback is call as LUA "function Alsa_Get_Hal_CB (error, result, context)" where:
+* `AFB:service ('API', 'VERB', {query}, "Lua_Callback_Name", {context})` is an
+ asynchronous call to another binding. When empty, query/context should be set
+ to '{}' and not to 'nil'. When 'nil', Lua does not send 'NULL' value but
+ removes arguments to calling stack. WARNING:"Callback" is the name of the
+ callback as a string and not a pointer to the callback. (If someone as a
+ solution to fix this, please let me known). Callback is call as LUA
+ "function Alsa_Get_Hal_CB (error, result, context)" where:
* error is a Boolean
* result is the full answer from AppFw (do not forget to extract the response)
- * context is a copy of the Lua table pass as an argument (warning it's a copy not a pointer to original table)
+ * context is a copy of the Lua table pass as an argument (warning it's a copy
+ not a pointer to original table)
-* `error,result=AFB:servsync('API', 'VERB', {query})` is saved as previous but for synchronous call. Note that Lua accepts multiple
- returns. AFB:servsync returns both the error message and the response as a Lua table. Like for AFB:service, the user should not
- forget to extract response from result.
+* `error,result=AFB:servsync('API', 'VERB', {query})` is saved as previous but
+ for synchronous call. Note that Lua accepts multiple returns. AFB:servsync
+ returns both the error message and the response as a Lua table. Like for
+ AFB:service, the user should not forget to extract response from result.
-* `AFB:success(request, response)` is the success request. request is the opaque handle passes when Lua is called from (api="control", verb="docall").
- Response is a Lua table that will be returned to the client.
+* `AFB:success(request, response)` is the success request. request is the opaque
+ handle passes when Lua is called from (api="control", verb="docall"). Response
+ is a Lua table that will be returned to the client.
-* `AFB:fail(request, response)` is the same as for success. Note that LUA generates automatically the error code from Lua function name.
- The response is transformed into a json string before being returned to the client.
+* `AFB:fail(request, response)` is the same as for success. Note that LUA
+ generates automatically the error code from Lua function name. The response
+ is transformed into a json string before being returned to the client.
-* `EventHandle=AFB:evtmake("MyEventName")` creates an event and returns the handle as an opaque handle. Note that due to a limitation
- of json_object, this opaque handle cannot be passed as an argument in a callback context.
+* `EventHandle=AFB:evtmake("MyEventName")` creates an event and returns the
+ handle as an opaque handle. Note that due to a limitation of json_object, this
+ opaque handle cannot be passed as an argument in a callback context.
-* `AFB:subscribe(request, MyEventHandle)` subscribes a given client to a previously created event.
+* `AFB:subscribe(request, MyEventHandle)` subscribes a given client to a
+ previously created event.
-* `AFB:evtpush (MyEventHandle, MyEventData)` pushes an event to every subscribed client. MyEventData is a Lua table that will be
- sent as a json object to the corresponding clients.
+* `AFB:evtpush (MyEventHandle, MyEventData)` pushes an event to every subscribed
+ client. MyEventData is a Lua table that will be sent as a json object to the
+ corresponding clients.
-* `timerHandle=AFB:timerset (MyTimer, "Timer_Test_CB", context)` initialises a timer from MyTimer Lua table. This table should contains 3 elements:
- MyTimer={[l"abel"]="MyTimerName", ["delay"]=timeoutInMs, ["count"]=nBOfCycles}. Note that if count==0 then timer is cycled
- infinitely. Context is a standard Lua table. This function returns an opaque handle to be used to further control the timer.
+* `timerHandle=AFB:timerset (MyTimer, "Timer_Test_CB", context)` initialises a
+ timer from MyTimer Lua table. This table should contains 3 elements:
+ MyTimer={[l"abel"]="MyTimerName", ["delay"]=timeoutInMs, ["count"]=nBOfCycles}
+ Note that if count==0 then timer is cycled infinitely. Context is a standard
+ Lua table. This function returns an opaque handle to be used to further
+ control the timer.
-* `AFB:timerclear(timerHandle)` kills an existing timer. Returns an error when timer does not exit.
+* `AFB:timerclear(timerHandle)` kills an existing timer. Returns an error when
+ timer does not exit.
-* `MyTimer=AFB:timerget(timerHandle)` returns uid, delay and count of an active timer. Returns an error when timerHandle does not
- point on an active timer.
+* `MyTimer=AFB:timerget(timerHandle)` returns uid, delay and count of an active
+ timer. Returns an error when timerHandle does not point on an active timer.
* `AFB:GetEventLoop()` retrieves the common systemd's event loop of AFB.
-* `AFB:RootDirGetFD()` gets the root directory file descriptor. This file descriptor can be used with functions 'openat', 'fstatat', ...
+* `AFB:RootDirGetFD()` gets the root directory file descriptor. This file
+ descriptor can be used with functions 'openat', 'fstatat', ...
-> **Note**: Except for functions call during binding initialisation period. Lua calls are protected and should returned clean messages
-> even when they are improperly used. If you find bug please report.
+> **Note**: Except for functions call during binding initialisation period. Lua
+> calls are protected and should returned clean messages even when they are
+> improperly used. If you find bug please report.
## Adding Lua command from User Plugin
-User Plugin is optional and may provide either native C-action accessible directly from controller actions as defined in
-JSON config file, or alternatively may provide a set of Lua commands usable inside any script (onload, control,event). A simple
-plugin that provides both notice C API and Lua commands is provided as example (see ctl-plugin-sample.c). Technically a
-plugin is a simple sharelibrary and any code fitting in sharelib might be used as a plugin. Developer should nevertheless
-not forget that except when no-concurrency flag was at binding construction time, any binding should to be thread safe.
-
-A plugin must be declared with `CTLP_REGISTER("MyCtlSamplePlugin")`. This entry point defines a special structure that is checked
-at plugin load time by the controller. Then you have an optional init routine declare with `CTLP_ONLOAD(plugin, handle)`.
- The init routine may create
-a plugin context that is later presented to every plugin API, this for both LUA and native C ones. Then each:
-
-* C API declare with `CTLP_CAPI(MyCFunction, source, argsJ, queryJ) {your code}`. Where:
+User Plugin is optional and may provide either native C-action accessible
+directly from controller actions as defined in JSON config file, or
+alternatively may provide a set of Lua commands usable inside any script (onload
+, control,event). A simple plugin that provides both notice C API and Lua
+commands is provided as example (see ctl-plugin-sample.c). Technically a plugin
+is a simple sharelibrary and any code fitting in sharelib might be used as a
+plugin. Developer should nevertheless forget that except when no-concurrency
+flag was at binding construction time, any binding should to be thread safe.
+
+A plugin must be declared with `CTLP_REGISTER("MyCtlSamplePlugin")`. This
+entry point defines a special structure that is checked at plugin load time by
+the controller. Then you have an optional init routine declare with
+`CTLP_ONLOAD(plugin, handle)`. The init routine may create a plugin context that
+is later presented to every plugin API, this for both LUA and native C ones.
+Then each:
+
+* C API declare with `CTLP_CAPI(MyCFunction, source, argsJ, queryJ) {your code}`.
+ Where:
* **MyFunction** is your function
* **source** is the structure config
- * **argsJ** a json_object containing the argument attaches to this control in JSON config file
+ * **argsJ** a json_object containing the argument attaches to this control in
+ JSON config file
* **queryJ** a json_object
-* Lua API declare with `CTLP_LUA2C(MyLuaCFunction, source, argsJ, responseJ) {your code}`. Where
+* Lua API declare with `CTLP_LUA2C(MyLuaCFunction, source, argsJ, responseJ) {your code}`.
+ Where:
* **MyLuaCFunction** is both the name of your C function and Lua command
* **source** is the structure config
- * **argsJ** the arguments passed this time from Lua script and not from Json config file.
+ * **argsJ** the arguments passed this time from Lua script and not from JSON
+ config file.
* **responseJ** if success the argument is passed into the request.
-> **Warning**: Lua samples use with controller enforce strict mode. As a result every variable should be declared either as
-> local or as global. Unfortunately "luac" is not smart enough to handle strict mode at build time and errors only appear
-> at run time. Because of this strict mode every global variables (which include functions) should be prefixed by '_'.
-> Note that LUA requires an initialisation value for every variables and declaring something like "local myvar" will not
-> allocate "myvar".
+> **Warning**: Lua samples use with controller enforce strict mode. As a result
+> every variable should be declared either as local or as global. Unfortunately
+> "luac" is not smart enough to handle strict mode at build time and errors only
+> appear at run time. Because of this strict mode every global variables (which
+> include functions) should be prefixed by '_'. Note that LUA requires an
+> initialisation value for every variables and declaring something like
+> "local myvar" will not allocate "myvar".
## Debugging Facilities
-Controller Lua scripts are checked for syntax from CMAKE template with Luac. When needed to go further, a developer API should be allowed to
-execute directly Lua commands within the controller context from Rest/Ws (api=control, verb=lua_doscript). DoScript API takes two
-other optional arguments func=xxxx where xxxx is the function to execute within Lua script and args, a JSON object to provide
-input parameters. When funcname is not given by default, the controller tries to execute middle filename doscript-xxxx-????.lua.
+Controller Lua scripts are checked for syntax from CMAKE template with Luac.
+When needed to go further, a developer API should be allowed to execute directly
+Lua commands within the controller context from Rest/Ws (api=control,
+verb=lua_doscript). DoScript API takes two other optional arguments func=xxxx
+where xxxx is the function to execute within Lua script and args, a JSON object
+to provide input parameters. When funcname is not given by default, the
+controller tries to execute middle filename doscript-xxxx-????.lua.
-When executed from the controller, Lua script may use any AppFw Apis as well as any L2C user defines commands in plugin.
+When executed from the controller, Lua script may use any AppFw Apis as well as
+any L2C user defines commands in plugin.
## Running as Standalone Controller
-The controller is a standard binding. It can be started with the following command:
+The controller is a standard binding. It can be started with the following
+command:
```bash
afb-daemon --name=yourname --port=1234 --workdir=. --roothttp=./htdocs --tracereq=common --token= --verbose --binding=pathtoyourbinding.so --monitoring
```
-Afb-Daemon only loads controller bindings without searching for the other
-binding. In this case, the controller binding will search for a configuration file
-name '(prefix-)bindermiddlename*.json'. This model can be used to implement for testing
-purpose or simply to act as the glue between a UI and other binder/services.
+afb-daemon only loads controller bindings without searching for the other
+binding. In this case, the controller binding will search for a configuration
+file name '(prefix-)bindermiddlename*.json'. This model can be used to implement
+for testing purpose or simply to act as the glue between a UI and other
+binder/services.