2 #include <netinet/tcp.h>
4 #include "asn1/asn1_message.h"
5 #include "der_encoder.h"
6 #include "ipuptanesecondary.h"
7 #include "logging/logging.h"
13 Uptane::SecondaryInterface::Ptr IpUptaneSecondary::connectAndCreate(
const std::string& address,
unsigned short port) {
14 LOG_INFO <<
"Connecting to and getting info about IP Secondary: " << address <<
":" << port <<
"...";
18 if (con_sock.connect() != 0) {
19 LOG_ERROR <<
"Failed to connect to a secondary: " << std::strerror(errno);
20 return std::shared_ptr<Uptane::SecondaryInterface>();
23 LOG_INFO <<
"Connected to IP Secondary: "
24 <<
"(" << address <<
":" << port <<
")";
26 return create(address, port, *con_sock);
29 Uptane::SecondaryInterface::Ptr IpUptaneSecondary::create(
const std::string& address,
unsigned short port,
int con_fd) {
31 req->present(AKIpUptaneMes_PR_getInfoReq);
33 auto m = req->getInfoReq();
35 auto resp = Asn1Rpc(req, con_fd);
37 if (resp->present() != AKIpUptaneMes_PR_getInfoResp) {
38 LOG_ERROR <<
"Failed to get info response message from secondary";
39 throw std::runtime_error(
"Failed to obtain information about a secondary: " + address + std::to_string(port));
41 auto r = resp->getInfoResp();
43 EcuSerial serial = EcuSerial(ToString(r->ecuSerial));
44 HardwareIdentifier hw_id = HardwareIdentifier(ToString(r->hwId));
45 std::string key = ToString(r->key);
46 auto type = static_cast<KeyType>(r->keyType);
49 LOG_INFO <<
"Got info on IP Secondary: "
50 <<
"hw-ID: " << hw_id <<
" serial: " << serial;
52 return std::make_shared<IpUptaneSecondary>(address, port, serial, hw_id, pub_key);
55 IpUptaneSecondary::IpUptaneSecondary(
const std::string& address,
unsigned short port, EcuSerial serial,
56 HardwareIdentifier hw_id,
PublicKey pub_key)
57 : addr_{address, port}, serial_{std::move(serial)}, hw_id_{std::move(hw_id)}, pub_key_{std::move(pub_key)} {}
59 bool IpUptaneSecondary::putMetadata(
const RawMetaPack& meta_pack) {
60 LOG_INFO <<
"Sending Uptane metadata to the secondary";
62 req->present(AKIpUptaneMes_PR_putMetaReq);
64 auto m = req->putMetaReq();
65 m->image.present = image_PR_json;
66 SetString(&m->image.choice.json.root, meta_pack.image_root);
67 SetString(&m->image.choice.json.targets, meta_pack.image_targets);
68 SetString(&m->image.choice.json.snapshot, meta_pack.image_snapshot);
69 SetString(&m->image.choice.json.timestamp, meta_pack.image_timestamp);
71 m->director.present = director_PR_json;
72 SetString(&m->director.choice.json.root, meta_pack.director_root);
73 SetString(&m->director.choice.json.targets, meta_pack.director_targets);
75 auto resp = Asn1Rpc(req, getAddr());
77 if (resp->present() != AKIpUptaneMes_PR_putMetaResp) {
78 LOG_ERROR <<
"Failed to get response to sending manifest to secondary";
82 auto r = resp->putMetaResp();
83 return r->result == AKInstallationResult_success;
86 bool IpUptaneSecondary::sendFirmware(
const std::string&
data) {
87 std::lock_guard<std::mutex> l(install_mutex);
88 LOG_INFO <<
"Sending firmware to the secondary";
90 req->present(AKIpUptaneMes_PR_sendFirmwareReq);
92 auto m = req->sendFirmwareReq();
93 SetString(&m->firmware,
data);
94 auto resp = Asn1Rpc(req, getAddr());
96 if (resp->present() != AKIpUptaneMes_PR_sendFirmwareResp) {
97 LOG_ERROR <<
"Failed to get response to sending firmware to secondary";
101 auto r = resp->sendFirmwareResp();
102 return r->result == AKInstallationResult_success;
106 LOG_INFO <<
"Invoking an installation of the target on the secondary: " << target_name;
109 req->present(AKIpUptaneMes_PR_installReq);
112 auto req_mes = req->installReq();
113 SetString(&req_mes->hash, target_name);
115 auto resp = Asn1Rpc(req, getAddr());
118 if (resp->present() != AKIpUptaneMes_PR_installResp) {
119 LOG_ERROR <<
"Failed to get response to an installation request to secondary";
124 auto r = resp->installResp();
126 return static_cast<data::ResultCode::Numeric>(r->result);
129 Manifest IpUptaneSecondary::getManifest()
const {
130 LOG_DEBUG <<
"Getting the manifest from secondary with serial " << getSerial();
133 req->present(AKIpUptaneMes_PR_manifestReq);
135 auto resp = Asn1Rpc(req, getAddr());
137 if (resp->present() != AKIpUptaneMes_PR_manifestResp) {
138 LOG_ERROR <<
"Failed to get public key response message from secondary";
139 return Json::Value();
141 auto r = resp->manifestResp();
143 if (r->manifest.present != manifest_PR_json) {
144 LOG_ERROR <<
"Manifest wasn't in json format";
145 return Json::Value();
147 std::string manifest = ToString(r->manifest.choice.json);
148 return Utils::parseJSON(manifest);