blob: 6d999b2952859378785ad69e71d074a80dac00ab [file] [log] [blame]
Tomáš Peckacb7a5f82021-01-20 15:12:00 +01001/*
2 * Copyright (C) 2021 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Tomáš Pecka <tomas.pecka@cesnet.cz>
5 *
6 */
7
Tomáš Pecka594a6762021-01-29 11:06:08 +01008#include "Firmware.h"
Tomáš Peckacb7a5f82021-01-20 15:12:00 +01009#include "utils/log.h"
10#include "utils/sysrepo.h"
11
12using namespace std::literals;
13
14namespace {
15
16const auto CZECHLIGHT_SYSTEM_MODULE_NAME = "czechlight-system"s;
17const auto CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX = "/"s + CZECHLIGHT_SYSTEM_MODULE_NAME + ":firmware/"s;
18
19}
20
21namespace velia::system {
22
Tomáš Pecka594a6762021-01-29 11:06:08 +010023Firmware::Firmware(std::shared_ptr<::sysrepo::Connection> srConn, sdbus::IConnection& dbusConnection)
Tomáš Peckacb7a5f82021-01-20 15:12:00 +010024 : m_srConn(std::move(srConn))
25 , m_srSession(std::make_shared<::sysrepo::Session>(m_srConn))
26 , m_srSubscribe(std::make_shared<::sysrepo::Subscribe>(m_srSession))
27 , m_rauc(std::make_shared<RAUC>(
28 dbusConnection,
29 [this](const std::string& operation) {
30 if (operation == "installing") {
31 std::map<std::string, std::string> data {
32 {CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/status", "in-progress"},
33 };
34
35 utils::valuesPush(data, std::make_shared<::sysrepo::Session>(m_srConn, SR_DS_OPERATIONAL));
36 }
37 },
Tomáš Pecka9a6e15b2021-01-25 18:57:48 +010038 [this](int32_t perc, const std::string& msg) {
39 std::map<std::string, std::string> data = {
40 {CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/update/message", msg},
41 {CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/update/progress", std::to_string(perc)},
42 };
43
44 libyang::S_Data_Node dataNode;
45 auto session = std::make_shared<::sysrepo::Session>(m_srConn);
46
47 utils::valuesToYang(data, session, dataNode);
48 session->event_notif_send(dataNode);
49 },
Tomáš Peckacb7a5f82021-01-20 15:12:00 +010050 [this](int32_t retVal, const std::string& lastError) {
51 std::map<std::string, std::string> data {
52 {CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/message", lastError},
53 {CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/status", retVal == 0 ? "succeeded" : "failed"},
54 };
55
56 utils::valuesPush(data, std::make_shared<::sysrepo::Session>(m_srConn, SR_DS_OPERATIONAL));
57 }))
58 , m_log(spdlog::get("system"))
59{
60 {
61 auto raucOperation = m_rauc->operation();
62 auto raucLastError = m_rauc->lastError();
63 std::map<std::string, std::string> data {
64 {CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/message", raucLastError},
65 };
66
67 if (raucOperation == "installing") {
68 data[CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/status"] = "in-progress";
69 } else if (!raucLastError.empty()) {
70 data[CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/status"] = "failed";
71 } else {
72 data[CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/status"] = "none";
73 }
74
75 utils::valuesPush(data, m_srSession, SR_DS_OPERATIONAL);
76 }
77
78 m_srSubscribe->rpc_subscribe(
79 (CZECHLIGHT_SYSTEM_FIRMWARE_MODULE_PREFIX + "installation/install").c_str(),
80 [this](::sysrepo::S_Session session, [[maybe_unused]] const char* op_path, const ::sysrepo::S_Vals input, [[maybe_unused]] sr_event_t event, [[maybe_unused]] uint32_t request_id, [[maybe_unused]] ::sysrepo::S_Vals_Holder output) {
81 try {
82 std::string source = input->val(0)->val_to_string();
83 m_rauc->install(source);
84 } catch (sdbus::Error& e) {
85 m_log->warn("RAUC install error: '{}'", e.what());
86 session->set_error(e.getMessage().c_str(), nullptr);
87 return SR_ERR_OPERATION_FAILED;
88 }
89 return SR_ERR_OK;
90 },
91 0,
92 SR_SUBSCR_CTX_REUSE);
93}
94}