summaryrefslogtreecommitdiffstats
path: root/meta-agl-profile-graphical-html5/conf/layer.conf
blob: d499dd1732321a5a01de6872b44738126ff0b120 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
	${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "html5-framework"
BBFILE_PATTERN_html5-framework = "^${LAYERDIR}/"
BBFILE_PRIORITY_html5-framework = "80"

LAYERSERIES_COMPAT_html5-framework = "dunfell"
t .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
# Controller binding configuration

By default the controller searches for a config filename with the same 'middlename' as the daemon process. As an example if your process name is afb-daemon then middle name is 'daemon'. In addition, if your process name is afb-daemon-audio the middle name is also 'daemon'. Moreover the prefix is chosen when you call the [CtlConfigSearch](<#4)_Do_controller_config_parsing_at_binding_pre-init>) function, see below:

```bash
CtlConfigSearch(AFB_ApiT apiHandle, const char *dirList, const char *prefix)
```

```bash
# Middlename is taken from process middlename.
(prefix-)middlename*.json
```

You may overload the config search path with environment variables

* **CONTROL_CONFIG_PATH**: change default reserch path for configuration. You may provide multiple directories separated by ':'.
* **CONTROL_LUA_PATH**: same as CONTROL_CONFIG_PATH but for Lua script files.

Example: to load a config named '(prefix-)myconfig-test.json' do

```bash
afb-daemon --name myconfig --verbose ...'
```

The configuration is loaded dynamically during startup time. The controller scans **CONTROL_CONFIG_PATH** for a file corresponding to the pattern
"(prefix-)bindermiddlename*.json". The first file found in the path is loaded,
any other file corresponding to the same path is ignored and only generates a warning.

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, ...)
* **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.

## Config is organised in sections

* **metadata**: describes the configuration
* **plugins or resources**: defines the set of functions provided by the plugins allowing to load 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
* **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.

## Metadata

As today matadata is only used for documentation purpose.

* **uid**: mandatory
* **version**: mandatory
* **api**: mandatory
* **info**: optional
* **require**: optional
* **author**: optional
* **date**: optional

## OnLoad section

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:

* **uid**: mandatory.
* **info**: optional
* **action**: mandatory
* **args**: optionnal

## Control section

Control section defines a list of controls that are accessible.

You can define the following keys or arrays of the following keys, moreover
this section could be verb api:

* **uid**: mandatory
* **info**: optional
* **action**: the list of actions is mandatory

## Event 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, ...)
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".

* **uid**: mandatory
* **info**: optional
* **action**: the list of actions  is mandatory

## 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.

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.
* **libs**: mandatory, Plugin file or LUA scripts to load
* **lua**: optionnal, C functions that could be called from a LUA script

## Personnal sections

* **uid**: mandatory
* **info**: optionnal
* **action**: mandatory
* **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.

## Actions Categories

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).
  * `"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.
  * `"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).
  * `"action": "lua://plugin_name#function_name"`

You also can add the **privileges** property that handles AGL permission
needed to be able to call this action.

> **Note**: Lua added functions are systematically prefixed. AGL standard AppFw
functions are prefixed with AGL: (eg: AFB:notice(), AFB:success(), ...).
> User Lua functions added through the plugin and CTLP_LUA2C are prefixed with
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:

* `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:
  * 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)

* `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: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.

* `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.

* `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.

* `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', ...

> **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:
  * **MyFunction** is your function
  * **source** is the structure config
  * **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
  * **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.
  * **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".

## 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.

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:

```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.