ExecStart=-/bin/sh -c "/bin/mkdir /run/user/%i; /bin/chown %i:%i /run/user/%i; /usr/bin/chsmack -a '*' /run/user/%i"
ExecStart=-/bin/sh -c "/bin/mkdir /run/user/%i/apis; /bin/chown %i:%i /run/user/%i/apis; /usr/bin/chsmack -a '*' /run/user/%i/apis"
ExecStart=-/bin/sh -c "/bin/mkdir /run/user/%i/apis/ws; /bin/chown %i:%i /run/user/%i/apis/ws; /usr/bin/chsmack -a '*' /run/user/%i/apis/ws"
+ExecStart=-/bin/sh -c "/bin/mkdir /run/user/%i/apis/link; /bin/chown %i:%i /run/user/%i/apis/link; /usr/bin/chsmack -a '*' /run/user/%i/apis/link"
ExecStart=-/bin/sh -c "/bin/ln -sf /run/platform/display/wayland-0 /run/user/%i/wayland-0; /bin/chown %i:%i /run/user/%i/wayland-0; /usr/bin/chsmack -a '*' /run/user/%i/wayland-0"
ConditionSecurity=smack
%nl
# Automatic bound to required api
+{{#required-binding}}
+{{#value=extern}}
+BindsTo=afm-link-{{name}}@%i.service
+After=afm-link-{{name}}@%i.service
+{{/value=extern}}
+{{/required-binding}}
{{#required-api}}
{{#value=auto|ws}}
BindsTo=afm-api-{{name}}@%i.service
{{/required-api}}
{{#provided-api}}
{{#value=ws|auto}}
-Requires=afm-api-{{name}}@%i.service
-After=afm-api-{{name}}@%i.service
+Requires=afm-api-{{name}}@%i.socket
+After=afm-api-{{name}}@%i.socket
{{/value=ws|auto}}
{{/provided-api}}
%nl
{{#required-api}} \
{{#value=auto|ws}}--ws-client=unix:@afm_users_rundir@/%i/apis/ws/{{name}}{{/value=auto|ws}} \
{{#value=dbus}}--dbus-client={{name}}{{/value=dbus}} \
- {{#value=link}}--binding=@afm_users_rundir@/%i/apis/lib/{{name}}{{/value=link}} \
{{#value=cloud}}--cloud-client={{name}}{{/value=cloud}} \
{{#value=local}}--binding={{:#metadata.install-dir}}/{{name}}{{/value=local}} \
{{/required-api}} \
+ {{#required-binding}} \
+ {{#value=local}}--binding={{:#metadata.install-dir}}/{{name}}{{/value=local}} \
+ {{#value=extern}}--binding=@afm_users_rundir@/%i/apis/link/{{name}}{{/value=extern}} \
+ {{/required-binding}} \
{{#provided-api}} \
{{#value=auto|ws}}--ws-server=sd:{{name}}{{/value=auto|ws}} \
{{#value=dbus}}--dbus-server={{name}}{{/value=dbus}} \
%end systemd-unit
{{/value=ws|auto}}
{{/provided-api}}
+;-------------------------------------------------------------------------------
+;---- P R O V I D E D B I N D I N G ----
+;-------------------------------------------------------------------------------
+{{#provided-binding}}
+;-------------------------------------------------------------------------------
+;---- T H E S E R V I C E O F T H E B I N D I N G ----
+;-------------------------------------------------------------------------------
+%begin systemd-unit
+# auto generated by wgtpkg-unit for {{:id}} version {{:version}} target {{:#target}} of {{:idaver}}
+%systemd-unit system
+%systemd-unit service afm-link-{{name}}@
+[Unit]
+Description=Provides binding {{name}} for user %i
+Requires=afm-user-setup@%i.service
+After=afm-user-setup@%i.service
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/bin/ln -s {{:#metadata.install-dir}}/{{value}} @afm_users_rundir@/%i/apis/link/{{name}}
+%end systemd-unit
+{{/provided-binding}}
{{/targets}}
;---------------------------------------------------------------------------------
; End of file afm-unit.conf mode DEVEL
ConditionSecurity=smack
%nl
# Automatic bound to required api
+{{#required-binding}}
+{{#value=extern}}
+BindsTo=afm-link-{{name}}@%i.service
+After=afm-link-{{name}}@%i.service
+{{/value=extern}}
+{{/required-binding}}
{{#required-api}}
{{#value=auto|ws}}
BindsTo=afm-api-{{name}}@%i.service
{{/required-api}}
{{#provided-api}}
{{#value=ws|auto}}
-Requires=afm-api-{{name}}@%i.service
-After=afm-api-{{name}}@%i.service
+Requires=afm-api-{{name}}@%i.socket
+After=afm-api-{{name}}@%i.socket
{{/value=ws|auto}}
{{/provided-api}}
%nl
{{#required-api}} \
{{#value=auto|ws}}--ws-client=unix:@afm_users_rundir@/%i/apis/ws/{{name}}{{/value=auto|ws}} \
{{#value=dbus}}--dbus-client={{name}}{{/value=dbus}} \
- {{#value=link}}--binding=@afm_users_rundir@/%i/apis/lib/{{name}}{{/value=link}} \
{{#value=cloud}}--cloud-client={{name}}{{/value=cloud}} \
{{#value=local}}--binding={{:#metadata.install-dir}}/{{name}}{{/value=local}} \
{{/required-api}} \
+ {{#required-binding}} \
+ {{#value=local}}--binding={{:#metadata.install-dir}}/{{name}}{{/value=local}} \
+ {{#value=extern}}--binding=@afm_users_rundir@/%i/apis/link/{{name}}{{/value=extern}} \
+ {{/required-binding}} \
{{#provided-api}} \
{{#value=auto|ws}}--ws-server=sd:{{name}}{{/value=auto|ws}} \
{{#value=dbus}}--dbus-server={{name}}{{/value=dbus}} \
%end systemd-unit
{{/value=ws|auto}}
{{/provided-api}}
+;-------------------------------------------------------------------------------
+;---- P R O V I D E D B I N D I N G ----
+;-------------------------------------------------------------------------------
+{{#provided-binding}}
+;-------------------------------------------------------------------------------
+;---- T H E S E R V I C E O F T H E B I N D I N G ----
+;-------------------------------------------------------------------------------
+%begin systemd-unit
+# auto generated by wgtpkg-unit for {{:id}} version {{:version}} target {{:#target}} of {{:idaver}}
+%systemd-unit system
+%systemd-unit service afm-link-{{name}}@
+[Unit]
+Description=Provides binding {{name}} for user %i
+Requires=afm-user-setup@%i.service
+After=afm-user-setup@%i.service
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/bin/ln -s {{:#metadata.install-dir}}/{{value}} @afm_users_rundir@/%i/apis/link/{{name}}
+%end systemd-unit
+{{/provided-binding}}
{{/targets}}
;---------------------------------------------------------------------------------
; End of file afm-unit.conf mode RELEASE
MAIN = afm-unit
-FILES = $(MAIN) binder.inc provided.inc service.inc Makefile
+FILES = $(MAIN) binder.inc provided-api.inc provided-binding.inc service.inc Makefile
DIR = ..
define( `UNIT_NAME_API_BASE', `afm-api-$1')
define( `UNIT_NAME_API_SERVICE', `UNIT_NAME_API_BASE($1)@$2.service')
define( `UNIT_NAME_API_SOCKET', `UNIT_NAME_API_BASE($1)@$2.socket')
+define( `UNIT_NAME_BINDING_BASE', `afm-link-$1')
+define( `UNIT_NAME_BINDING_SERVICE', `UNIT_NAME_BINDING_BASE($1)@$2.service')
define( `APP_DATA_DIR', `/home/%i/app-data')
define( `USER_RUN_DIR', `@afm_users_rundir@/%i')
define( `DEBUGGING_DIR', `@afm_platform_rundir@/debug')
include(service.inc)
-include(provided.inc)
+include(provided-api.inc)
+
+include(provided-binding.inc)
{{/targets}}
;---------------------------------------------------------------------------------
{{#required-api}} \
ON_VALUE(auto|ws, --ws-client=unix:USER_RUN_DIR/apis/ws/{{name}}) \
ON_VALUE(dbus, --dbus-client={{name}}) \
- ON_VALUE(link, --binding=USER_RUN_DIR/apis/lib/{{name}}) \
ON_VALUE(cloud, --cloud-client={{name}}) \
ON_VALUE(local, --binding={{:#metadata.install-dir}}/{{name}}) \
{{/required-api}} \
+ {{#required-binding}} \
+ ON_VALUE(local, --binding={{:#metadata.install-dir}}/{{name}}) \
+ ON_VALUE(extern, --binding=USER_RUN_DIR/apis/link/{{name}}) \
+ {{/required-binding}} \
{{#provided-api}} \
ON_VALUE(auto|ws, --ws-server=sd:{{name}}) \
ON_VALUE(dbus, --dbus-server={{name}}) \
{{#value=ws|auto}}
ExecStart=/bin/true
{{/value=ws|auto}}
-dnl {{#value=link}}
-dnl ExecStart=/bin/ln -s {{:#metadata.install-dir}}/ USER_RUN_DIR/apis/link/{{name}}
-dnl {{/value=link}}
-
-dnl %nl
-dnl [Install]
-dnl WantedBy=afm-user-session@.target
-dnl %systemd-unit wanted-by afm-user-session@.target
%end systemd-unit
--- /dev/null
+dnl vim: set filetype=sysctl.conf.m4 syntax=sysctl.conf.m4:
+;-------------------------------------------------------------------------------
+;---- P R O V I D E D B I N D I N G ----
+;-------------------------------------------------------------------------------
+
+{{#provided-binding}}
+
+;-------------------------------------------------------------------------------
+;---- T H E S E R V I C E O F T H E B I N D I N G ----
+;-------------------------------------------------------------------------------
+%begin systemd-unit
+
+# auto generated by wgtpkg-unit for {{:id}} version {{:version}} target {{:#target}} of {{:idaver}}
+
+%systemd-unit system
+%systemd-unit service UNIT_NAME_BINDING_BASE({{name}})@
+
+[Unit]
+Description=Provides binding {{name}} for user %i
+
+Requires=afm-user-setup@%i.service
+After=afm-user-setup@%i.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/bin/ln -s {{:#metadata.install-dir}}/{{value}} USER_RUN_DIR/apis/link/{{name}}
+
+%end systemd-unit
+
+{{/provided-binding}}
+
+
%nl
# Automatic bound to required api
+{{#required-binding}}
+{{#value=extern}}
+BindsTo=UNIT_NAME_BINDING_SERVICE({{name}},%i)
+After=UNIT_NAME_BINDING_SERVICE({{name}},%i)
+{{/value=extern}}
+{{/required-binding}}
{{#required-api}}
{{#value=auto|ws}}
BindsTo=UNIT_NAME_API_SERVICE({{name}},%i)
{{/required-api}}
{{#provided-api}}
{{#value=ws|auto}}
-Requires=UNIT_NAME_API_SERVICE({{name}},%i)
-After=UNIT_NAME_API_SERVICE({{name}},%i)
+Requires=UNIT_NAME_API_SOCKET({{name}},%i)
+After=UNIT_NAME_API_SOCKET({{name}},%i)
{{/value=ws|auto}}
{{/provided-api}}
The value describes how to connect to the required api.
It is either:
-- local:
+- local: OBSOLETE, PROVIDED FOR COMPATIBILITY
The binding is a local shared object.
In that case, the name is the relative path of the
shared object to be loaded.
- dbus:
The framework connect using internal dbus
-- link:
- The framework connect in memory by dynamically linking
-
- cloud: [PROPOSAL - NOT IMPLEMENTED]
The framework connect externally using websock.
In that case, the name includes data to access the service.
Example: `<param name="log:https://oic@agl.iot.bzh/cloud/log" value="cloud" />`
+#### required-binding: param name=[name or path]
+
+The name or the path of the required BINDING.
+
+The value describes how to connect to the required binding.
+It is either:
+
+- local:
+ The binding is a local shared object.
+ In that case, the name is the relative path of the
+ shared object to be loaded.
+
+- extern:
+ The binding is external. The name is the exported binding name.
+ See provided-binding.
+
+#### provided-binding: param name=[exported name]
+
+Exports a local binding to other applications.
+
+The value must contain the path to the exported binding.
+
### required-permission: feature name="urn:AGL:widget:required-permission"
List of the permissions required by the unit.
return add_targeted_params(targets, feat, actions);
}
+/* Treats the feature "provided_binding" */
+static int add_provided_binding(struct json_object *targets, const struct wgt_desc_feature *feat)
+{
+ static struct paramaction actions[] = {
+ { .name = string_sharp_target, .action = NULL, .closure = NULL }, /* TODO: should be an error! */
+ { .name = NULL, .action = add_param_array, .closure = (void*)string_provided_binding }
+ };
+ return add_targeted_params(targets, feat, actions);
+}
+
+/* Treats the feature "required_binding" */
+static int add_required_binding(struct json_object *targets, const struct wgt_desc_feature *feat)
+{
+ static struct paramaction actions[] = {
+ { .name = string_sharp_target, .action = NULL, .closure = NULL }, /* skip #target */
+ { .name = NULL, .action = add_param_array, .closure = (void*)string_required_binding }
+ };
+ return add_targeted_params(targets, feat, actions);
+}
+
/* Treats the feature "required_permission" */
static int add_required_permission(struct json_object *targets, const struct wgt_desc_feature *feat)
{
else if (!strcmp(featname, string_provided_api)) {
rc2 = add_provided_api(targets, feat);
}
+ else if (!strcmp(featname, string_provided_binding)) {
+ rc2 = add_provided_binding(targets, feat);
+ }
else if (!strcmp(featname, string_required_api)) {
rc2 = add_required_api(targets, feat);
}
+ else if (!strcmp(featname, string_required_binding)) {
+ rc2 = add_required_binding(targets, feat);
+ }
else if (!strcmp(featname, string_required_permission)) {
rc2 = add_required_permission(targets, feat);
} else {
const char string_main[] = "main";
const char string_optional[] = "optional";
const char string_provided_api[] = "provided-api";
+const char string_provided_binding[] = "provided-binding";
const char string_provided_unit[] = "provided-unit";
const char string_required_api[] = "required-api";
+const char string_required_binding[] = "required-binding";
const char string_required_permission[] = "required-permission";
const char string_targets[] = "targets";
const char string_sharp_target[] = "#target";
extern const char string_main[];
extern const char string_optional[];
extern const char string_provided_api[];
+extern const char string_provided_binding[];
extern const char string_provided_unit[];
extern const char string_required_api[];
+extern const char string_required_binding[];
extern const char string_required_permission[];
extern const char string_sharp_target[];
extern const char string_targets[];