Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
msg_dispatcher.cc
1 #include "msg_dispatcher.h"
2 
3 #include <functional>
4 #include <unordered_map>
5 
6 #include "logging/logging.h"
7 
8 void MsgDispatcher::registerHandler(AKIpUptaneMes_PR msg_id, Handler handler) {
9  handler_map_[msg_id] = std::move(handler);
10 }
11 
12 MsgDispatcher::HandleStatusCode MsgDispatcher::handleMsg(const Asn1Message::Ptr& in_msg, Asn1Message::Ptr& out_msg) {
13  LOG_TRACE << "Got a request message from Primary: " << in_msg->toStr();
14 
15  auto find_res_it = handler_map_.find(in_msg->present());
16  if (find_res_it == handler_map_.end()) {
17  return MsgDispatcher::HandleStatusCode::kUnkownMsg;
18  }
19  LOG_TRACE << "Found a handler for the request message, processing it...";
20  auto handle_status_code = find_res_it->second(*in_msg, *out_msg);
21  LOG_TRACE << "Got a response message from a handler: " << out_msg->toStr();
22 
23  return handle_status_code;
24 }
25 
26 AktualizrSecondaryMsgDispatcher::AktualizrSecondaryMsgDispatcher(IAktualizrSecondary& secondary)
27  : secondary_{secondary} {
28  registerHandler(AKIpUptaneMes_PR_getInfoReq, std::bind(&AktualizrSecondaryMsgDispatcher::getInfoHdlr, this,
29  std::placeholders::_1, std::placeholders::_2));
30 
31  registerHandler(AKIpUptaneMes_PR_manifestReq, std::bind(&AktualizrSecondaryMsgDispatcher::getManifestHdlr, this,
32  std::placeholders::_1, std::placeholders::_2));
33 
34  registerHandler(AKIpUptaneMes_PR_putMetaReq, std::bind(&AktualizrSecondaryMsgDispatcher::putMetaHdlr, this,
35  std::placeholders::_1, std::placeholders::_2));
36 
37  registerHandler(AKIpUptaneMes_PR_sendFirmwareReq, std::bind(&AktualizrSecondaryMsgDispatcher::sendFirmwareHdlr, this,
38  std::placeholders::_1, std::placeholders::_2));
39 
40  registerHandler(AKIpUptaneMes_PR_installReq, std::bind(&AktualizrSecondaryMsgDispatcher::installHdlr, this,
41  std::placeholders::_1, std::placeholders::_2));
42 }
43 
44 MsgDispatcher::HandleStatusCode AktualizrSecondaryMsgDispatcher::getInfoHdlr(Asn1Message& in_msg,
45  Asn1Message& out_msg) {
46  (void)in_msg;
47 
48  Uptane::EcuSerial serial = Uptane::EcuSerial::Unknown();
49  Uptane::HardwareIdentifier hw_id = Uptane::HardwareIdentifier::Unknown();
50  PublicKey pub_key;
51 
52  std::tie(serial, hw_id, pub_key) = secondary_.getInfo();
53  out_msg.present(AKIpUptaneMes_PR_getInfoResp);
54 
55  auto info_resp = out_msg.getInfoResp();
56 
57  SetString(&info_resp->ecuSerial, serial.ToString());
58  SetString(&info_resp->hwId, hw_id.ToString());
59  info_resp->keyType = static_cast<AKIpUptaneKeyType_t>(pub_key.Type());
60  SetString(&info_resp->key, pub_key.Value());
61 
62  return HandleStatusCode::kOk;
63 }
64 
65 MsgDispatcher::HandleStatusCode AktualizrSecondaryMsgDispatcher::getManifestHdlr(Asn1Message& in_msg,
66  Asn1Message& out_msg) {
67  (void)in_msg;
68 
69  std::string manifest = Utils::jsonToStr(secondary_.getManifest());
70  out_msg.present(AKIpUptaneMes_PR_manifestResp);
71  auto manifest_resp = out_msg.manifestResp();
72  manifest_resp->manifest.present = manifest_PR_json;
73  SetString(&manifest_resp->manifest.choice.json, manifest); // NOLINT
74 
75  LOG_TRACE << "Manifest : \n" << manifest;
76  return HandleStatusCode::kOk;
77 }
78 
79 MsgDispatcher::HandleStatusCode AktualizrSecondaryMsgDispatcher::putMetaHdlr(Asn1Message& in_msg,
80  Asn1Message& out_msg) {
81  auto md = in_msg.putMetaReq();
82  Uptane::RawMetaPack meta_pack;
83 
84  if (md->director.present == director_PR_json) {
85  meta_pack.director_root = ToString(md->director.choice.json.root); // NOLINT
86  meta_pack.director_targets = ToString(md->director.choice.json.targets); // NOLINT
87  LOG_DEBUG << "Received Director repo Root metadata:\n" << meta_pack.director_root;
88  LOG_DEBUG << "Received Director repo Targets metadata:\n" << meta_pack.director_targets;
89  } else {
90  LOG_WARNING << "Director metadata in unknown format:" << md->director.present;
91  }
92 
93  if (md->image.present == image_PR_json) {
94  meta_pack.image_root = ToString(md->image.choice.json.root); // NOLINT
95  meta_pack.image_timestamp = ToString(md->image.choice.json.timestamp); // NOLINT
96  meta_pack.image_snapshot = ToString(md->image.choice.json.snapshot); // NOLINT
97  meta_pack.image_targets = ToString(md->image.choice.json.targets); // NOLINT
98  LOG_DEBUG << "Received Image repo Root metadata:\n" << meta_pack.image_root;
99  LOG_DEBUG << "Received Image repo Timestamp metadata:\n" << meta_pack.image_timestamp;
100  LOG_DEBUG << "Received Image repo Snapshot metadata:\n" << meta_pack.image_snapshot;
101  LOG_DEBUG << "Received Image repo Targets metadata:\n" << meta_pack.image_targets;
102  } else {
103  LOG_WARNING << "Image repo metadata in unknown format:" << md->image.present;
104  }
105  bool ok = secondary_.putMetadata(meta_pack);
106 
107  out_msg.present(AKIpUptaneMes_PR_putMetaResp).putMetaResp()->result =
108  ok ? AKInstallationResult_success : AKInstallationResult_failure;
109 
110  return HandleStatusCode::kOk;
111 }
112 
113 MsgDispatcher::HandleStatusCode AktualizrSecondaryMsgDispatcher::sendFirmwareHdlr(Asn1Message& in_msg,
114  Asn1Message& out_msg) {
115  auto fw = in_msg.sendFirmwareReq();
116  auto send_firmware_result = secondary_.sendFirmware(ToString(in_msg.sendFirmwareReq()->firmware));
117 
118  out_msg.present(AKIpUptaneMes_PR_sendFirmwareResp).sendFirmwareResp()->result =
119  send_firmware_result ? AKInstallationResult_success : AKInstallationResult_failure;
120  ;
121 
122  return HandleStatusCode::kOk;
123 }
124 
125 MsgDispatcher::HandleStatusCode AktualizrSecondaryMsgDispatcher::installHdlr(Asn1Message& in_msg,
126  Asn1Message& out_msg) {
127  auto install_result = secondary_.install(ToString(in_msg.installReq()->hash));
128  out_msg.present(AKIpUptaneMes_PR_installResp).installResp()->result =
129  static_cast<AKInstallationResultCode_t>(install_result);
130 
131  if (data::ResultCode::Numeric::kNeedCompletion == install_result) {
132  return HandleStatusCode::kRebootRequired;
133  }
134 
135  return HandleStatusCode::kOk;
136 }
Reference counted holder for the top-level ASN1 message structure.
Definition: asn1_message.h:34