# This variable is parsed by Autoconf
EXTRA_actd_SOURCES = \
src/action/service_restart.c \
- src/action/unit_start.c
+ src/action/unit_start.c \
+ src/action/forward_signal.c
actd_CFLAGS = $(AM_CFLAGS)
actd_LDFLAGS = -ldl -pie
modules_LTLIBRARIES = \
service_restart_action.la \
unit_start_action.la \
+ forward_signal_action.la \
vconf_key_changed_event.la \
dbus_signal_event.la \
unit_control_event.la \
service_restart_action_la_SOURCES = src/action/service_restart.c
unit_start_action_la_SOURCES = src/action/unit_start.c
+forward_signal_action_la_SOURCES = src/action/forward_signal.c
vconf_key_changed_event_la_SOURCES = src/event_types/vconf_key_changed_event.c
dbus_signal_event_la_SOURCES = src/event_types/dbus_signal_event.c
unit_control_event_la_SOURCES = src/event_types/unit_control_event.c
#define EPC_ACTION_REBOOT_ID "org.tizen.epc.action.REBOOT"
#define EPC_ACTION_RECOVERY_REBOOT_ID "org.tizen.epc.action.RECOVERY_REBOOT"
#define EPC_ACTION_UNIT_START_ID "org.tizen.epc.action.UNIT_START"
+#define EPC_ACTION_DBUS_SIGNAL_FORWARD_ID "org.tizen.epc.action.DBUS_SIGNAL_FORWARD"
#define EPC_DEFAULT_ACTION_IMPL "default"
#define EPC_AD_CLEANUP_UNIT "RecoveryUnit"
#define EPC_AD_UNIT_NAME "UnitName"
#define EPC_AD_UNIT_ACTION "UnitAction"
+#define EPC_AD_SIGNAL_ACTION "SignalAction"
+#define EPC_AD_SIGNAL_DEST "SignalDestination"
+#define EPC_AD_SIGNAL_PATH "SignalPath"
+#define EPC_AD_SIGNAL_INTERFACE "SignalInterface"
+#define EPC_AD_SIGNAL_MEMBER "SignalMember"
+#define EPC_AD_SIGNAL_PARAMS "SignalParams"
int epc_fill_for_srv_restart(struct epc_object *obj, const char *service_path);
int epc_fill_for_unit_start(struct epc_object *obj, const char *unit_path);
int epc_fill_for_unit_action(struct epc_object *obj, const char *action);
+int epc_fill_for_signal_forward(struct epc_object *obj, const char *dest,
+ const char *objpath, const char *interface,
+ const char *member, struct epc_object *params);
+
#define epc_fill_for_reboot(o) \
epc_object_fill_empty(o)
},
{"event":"dbus_signal", "id":"test_bn", "action":"StopUnit", "target":"activationd-acceptance-test-b-n.service", "match":
{"arg1":false, "arg2":true}
- }
-
-
+ },
+ {"event":"dbus_signal", "id":"test_unicast_signal_001", "action":"ForwardDBusSignal", "target":"org.tizen.activationd.testsuite.UnicastSignalReceiver001" },
+ {"event":"dbus_signal", "id":"test_unicast_signal_002", "action":"ForwardDBusSignal", "target":"org.tizen.activationd.testsuite.UnicastSignalReceiver002" }
]
}
{"id":"test_dp", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestDP", "path_namespace":"/org/freedesktop"},
{"id":"test_dn", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestDN", "path_namespace":"/org/freedesktop"},
{"id":"test_bp", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestBP", "path_namespace":"/org/freedesktop"},
- {"id":"test_bn", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestBN", "path_namespace":"/org/freedesktop"}
+ {"id":"test_bn", "interface":"org.freedesktop.ActivationdTestInterface", "member":"AcceptanceTestBN", "path_namespace":"/org/freedesktop"},
+
+ {"id":"test_unicast_signal_001", "interface":"org.tizen.activationd.eventtest", "member":"Test001", "path_namespace":"/"},
+ {"id":"test_unicast_signal_002", "interface":"org.tizen.activationd.eventtest", "member":"Test002", "path_namespace":"/"}
]
}
%install_module service_restart_action extra
%install_module unit_start_action extra
+%install_module forward_signal_action extra
%install_module vconf_key_changed_event vconf
%install_module vconf_listener vconf
%install_module dbus_signal_event dbus
--- /dev/null
+/*
+ * This file is part of activationd.
+ *
+ * Copyright © 2019 Samsung Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "action.h"
+#include "action_executor.h"
+#include "decision_made_event.h"
+#include "unit_control_event.h"
+#include "log.h"
+#include "systemd_dbus.h"
+#include "common.h"
+
+#include <libsyscommon/dbus-system.h>
+
+static int forward_signal(struct epc_action *action,
+ struct action_executed_event *exe_info)
+{
+ struct epc_event *ev = pop_epc_event(&action->execution_queue);
+ struct decision_made_event *dm_ev = to_decision_made_event(ev);
+ char *signal_action = NULL;
+ char *signal_dest = NULL;
+ char *signal_path = NULL;
+ char *signal_interface = NULL;
+ char *signal_member = NULL;
+ //FIXME: we need to pass both signature or original signal and their parameters
+ // while passing GVariant* directly seems ok, we already have serialized
+ // form in module that generates the event, so might try to pass it here
+ // as epc_object (look for ->params in decision_makers/activation_dm)
+ //FIXME: signal_params = NULL;
+
+ epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_ACTION, &signal_action);
+ epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_DEST, &signal_dest);
+ epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_PATH, &signal_path);
+ epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_INTERFACE, &signal_interface);
+ epc_object_get_string(dm_ev->action_data, EPC_AD_SIGNAL_MEMBER, &signal_member);
+ log_debug("forward_signal: action %s, dest %s, path %s, interface %s, member %s",
+ signal_action, signal_dest, signal_path, signal_interface, signal_member);
+ //FIXME: epc_object_get_object(dm_ev->action_data, EPC_AD_SIGNAL_PARAMS, &signal_params);
+ if (!signal_dest || !signal_path || !signal_interface || !signal_member)
+ goto err;
+
+ dbus_handle_broadcast_dbus_signal(signal_dest, signal_path, signal_interface, signal_member, NULL);
+
+
+ //FIXME: shortly after this function exits actd gets segfault. I assume something
+ // more needs to be done in terms of cleanup here. Unfortunatelly, I have
+ // no idea what.
+ exe_info->result = 0;
+ return 0;
+
+err:
+ epc_object_append_string(exe_info->action_log, "error", "Invalid parameters given for forward_signal");
+ exe_info->result = -EINVAL;
+ log_error("Invalid parameters given for forward_signal");
+
+ return 0;
+}
+
+static struct epc_action forward_signal_action = {
+ .action_id = EPC_ACTION_DBUS_SIGNAL_FORWARD_ID,
+ .impl_name = EPC_DEFAULT_ACTION_IMPL,
+ .execute = forward_signal,
+ .node = LIST_HEAD_INIT(forward_signal_action.node),
+};
+
+EPC_ACTION_REGISTER_SIMPLE(forward_signal_action);
return 0;
}
+
+int epc_fill_for_signal_forward(struct epc_object *obj, const char *dest,
+ const char *path, const char *interface,
+ const char *member, struct epc_object *params)
+{
+ assert(dest);
+ assert(path);
+ assert(interface);
+ assert(member);
+
+ int ret;
+
+ ret = epc_object_append_string(obj, EPC_AD_SIGNAL_DEST, dest);
+ ret += epc_object_append_string(obj, EPC_AD_SIGNAL_PATH, path);
+ ret += epc_object_append_string(obj, EPC_AD_SIGNAL_INTERFACE, interface);
+ ret += epc_object_append_string(obj, EPC_AD_SIGNAL_MEMBER, member);
+ if (params)
+ ret += epc_object_append_object(obj, EPC_AD_SIGNAL_PARAMS, params);
+
+ if (ret != 0) {
+ log_error("Unable to append parameters for forward_signal");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
return 1;
}
+static int execute_rule_uc(struct rule *r, struct epc_event *ev, struct dm_event_data *ev_data)
+{
+ ev_data->action = EPC_ACTION_UNIT_START_ID;
+
+ if (epc_fill_for_unit_start(ev_data->action_data, r->target)) {
+ log_error("Unable to create event data");
+ return -1;
+ }
+ epc_fill_for_unit_action(ev_data->action_data, r->action);
+
+ return 0;
+}
+
+static int execute_rule_signal(struct rule *r, struct epc_event *ev, struct dm_event_data *ev_data)
+{
+ struct dbus_signal_event *dev = to_dbus_signal_event(ev);
+
+ ev_data->action = EPC_ACTION_DBUS_SIGNAL_FORWARD_ID;
+
+ if (epc_fill_for_signal_forward(ev_data->action_data, r->target,
+ dev->path, dev->interface, dev->member,
+ NULL /* FIXME not supported yet (dev->params) */)) {
+ // FIXME note that dev->params already has parameters that need to be passed as epc_object
+ log_error("Unable to create event data");
+ return -1;
+ }
+
+ return 0;
+}
static int execute_rule(struct rule *r, struct epc_event *ev)
{
struct epc_event *new_ev;
int ret;
- ev_data.action = EPC_ACTION_UNIT_START_ID;
ret = epc_object_new(&ev_data.action_data);
if (ret < 0) {
log_error("Could not create data object for action");
goto out;
}
- ret = epc_fill_for_unit_start(ev_data.action_data, r->target);
- if (ret) {
- log_error("Unable to create event data");
+ bool is_uc = !strcmp(r->action, "StartUnit") ||
+ !strcmp(r->action, "StopUnit") ||
+ !strcmp(r->action, "RestartUnit");
+ bool is_sig = !strcmp(r->action, "ForwardDBusSignal");
+
+ ret = is_uc ? execute_rule_uc(r, ev, &ev_data) :
+ (is_sig ? execute_rule_signal(r, ev, &ev_data) : -1);
+ if (ret < 0) {
+ log_debug("Unsupported action");
goto out;
}
- epc_fill_for_unit_action(ev_data.action_data, r->action);
ret = epc_event_create(DECISION_MADE_EVENT_ID, &ev_data, &new_ev);
if (ret) {