Skip to content

Commit

Permalink
Added alarm state change signal functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Ómar Högni Guðmarsson committed Jun 27, 2024
1 parent debb1e4 commit 902be6d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
2 changes: 1 addition & 1 deletion docs/design/snitch.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The alarm system is exposed through the `com.skaginn3x.Alarm` interface.
TryReset(i: alarm_id) # Transmits a signal to the alarm to reset itself
TryResetAll() # Transmits a signal to all alarms to reset themselfs
### Signals
AlarmActivationChanged(i: alarm_id, n: level, n: state)
AlarmChanged(i: alarm_id, n: state)
TryReset(i: alarm_id)
TryResetAll()
### Properties
Expand Down
14 changes: 11 additions & 3 deletions exes/themis/inc/alarm_database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,20 @@ ON Alarms.sha1sum = AlarmTranslations.sha1sum;
db_ << "COMMIT;";
return activation_id;
}
auto reset_alarm(snitch::api::alarm_id_t activation_id, std::optional<tfc::snitch::api::time_point> tp = {}) -> void {
/**
* @brief Reset an alarm in the database
* @param activation_id the activation_id of the alarm to reset
* @param tp an optional timepoint
* @return true if the alarm was reset
*/
auto reset_alarm(snitch::api::alarm_id_t activation_id, std::optional<tfc::snitch::api::time_point> tp = {}) -> bool {
if (!is_activation_high(activation_id)) {
throw dbus_error("Cannot reset an inactive activation");
return false;
}
db_ << fmt::format("UPDATE AlarmActivations SET activation_level = {}, reset_time = {} WHERE activation_id = {};",
std::to_underlying(tfc::snitch::api::state_e::inactive), milliseconds_since_epoch(tp), activation_id);
std::to_underlying(tfc::snitch::api::state_e::inactive), milliseconds_since_epoch(tp),
activation_id);
return true;
}
auto set_activation_status(snitch::api::alarm_id_t activation_id, tfc::snitch::api::state_e activation) -> void {
if (!is_activation_high(activation_id)) {
Expand Down
38 changes: 29 additions & 9 deletions exes/themis/inc/dbus_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ using namespace tfc::snitch::api::dbus;
using std::string_view_literals::operator""sv;
using dbus_error = tfc::dbus::exception::runtime;

using tfc::snitch::api::state_e;
using tfc::snitch::api::alarm_id_t;
using tfc::snitch::level_e;

class interface {
public:
explicit interface(std::shared_ptr<sdbusplus::asio::connection> connection, tfc::themis::alarm_database& database)
: database_(database) {
connection_ = connection;
: connection_(std::move(connection)), database_(database) {
// Initialize the object server and request the service name
object_server_ = std::make_unique<sdbusplus::asio::object_server>(connection_);
connection_->request_name(service_name.data());
interface_ = object_server_->add_unique_interface(object_path.data(), interface_name.data());
Expand All @@ -48,16 +52,26 @@ class interface {
auto alarm_id = database.register_alarm_en(tfc_id, description, details, latching,
static_cast<tfc::snitch::level_e>(alarm_level));
dbus_ids_to_monitor_[sender].push_back(alarm_id);
notify_alarm_state(alarm_id, state_e::inactive);
return alarm_id;
});

interface_->register_method(
std::string(methods::set_alarm),
[&](snitch::api::alarm_id_t alarm_id, const std::unordered_map<std::string, std::string>& args) -> std::uint64_t {
return database.set_alarm(alarm_id, args);
auto activation_id = database.set_alarm(alarm_id, args);
notify_alarm_state(alarm_id, state_e::active);
return activation_id;
});
interface_->register_method(std::string(methods::reset_alarm),
[&](snitch::api::alarm_id_t alarm_id) -> void { database.reset_alarm(alarm_id); });
interface_->register_method(std::string(methods::reset_alarm), [&](snitch::api::alarm_id_t alarm_id) -> void {
if (!database.reset_alarm(alarm_id)) {
throw dbus_error("Cannot reset an inactive activation");
} else {
// Notify the change in alarm status of this alarm
notify_alarm_state(alarm_id, state_e::inactive);
}
});

interface_->register_method(std::string(methods::try_reset), [&](snitch::api::alarm_id_t alarm_id) -> void {
if (database.is_alarm_active(alarm_id)) {
auto message = interface_->new_signal(signals::try_reset.data());
Expand All @@ -67,6 +81,7 @@ class interface {
throw dbus_error("Alarm is not active");
}
});

interface_->register_method(std::string(methods::try_reset_all), [&]() -> void {
if (database.is_some_alarm_active()) {
auto message = interface_->new_signal(signals::try_reset_all.data());
Expand All @@ -75,8 +90,7 @@ class interface {
throw dbus_error("No alarm is active");
}
});
using tfc::snitch::level_e;
using tfc::snitch::api::state_e;

interface_->register_method(std::string(methods::list_activations),
[&](const std::string& locale, std::uint64_t start_count, std::uint64_t count,
std::underlying_type_t<level_e> alarm_level, std::underlying_type_t<state_e> active,
Expand All @@ -93,8 +107,7 @@ class interface {
});

// Signal alarm_id, current_activation, ack_status
interface_->register_signal<std::tuple<tfc::snitch::api::alarm_id_t, std::underlying_type_t<tfc::snitch::level_e>,
std::underlying_type_t<tfc::snitch::api::state_e>>>(
interface_->register_signal<std::tuple<tfc::snitch::api::alarm_id_t, std::underlying_type_t<tfc::snitch::api::state_e>>>(
std::string(signals::alarm_activation_changed));
interface_->register_signal<std::uint64_t>(std::string(signals::try_reset));
interface_->register_signal<void>(std::string(signals::try_reset_all));
Expand All @@ -110,6 +123,12 @@ class interface {
static constexpr std::string_view name_owner_changed_ = "NameOwnerChanged"sv;
static constexpr std::string_view match_rule_ = tfc::dbus::match::rules::
make_match_rule<dbus_name_, dbus_interface_, dbus_path_, name_owner_changed_, tfc::dbus::match::rules::type::signal>();

auto notify_alarm_state (alarm_id_t alarm_id, state_e state) -> void {
sdbusplus::message_t alarm_change_message = interface_->new_signal(signals::alarm_activation_changed.data());
alarm_change_message.append(std::tuple(alarm_id, std::to_underlying(state)));
alarm_change_message.signal_send();
}
auto match_callback(sdbusplus::message_t& msg) -> void {
std::tuple<std::string, std::string, std::string> container;
sdbusplus::utility::read_into_tuple(container, msg);
Expand All @@ -124,6 +143,7 @@ class interface {
auto activation = database_.get_activation_id_for_active_alarm(alarm_id);
if (activation.has_value()) {
database_.set_activation_status(activation.value(), tfc::snitch::api::state_e::unknown);
notify_alarm_state(alarm_id, state_e::unknown);
}
}
}
Expand Down

0 comments on commit 902be6d

Please sign in to comment.