Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
isotpsecondary.cc
1 #include "isotpsecondary.h"
2 
3 #include <linux/can.h>
4 #include <linux/can/raw.h>
5 #include <net/if.h>
6 #include <sys/ioctl.h>
7 
8 #include <boost/algorithm/hex.hpp>
9 #include <boost/lexical_cast.hpp>
10 #include <future>
11 
12 #define LIBUPTINY_ISOTP_PRIMARY_CANID 0x7D8
13 
14 constexpr size_t kChunkSize = 500;
15 
16 enum class IsoTpUptaneMesType {
17  kGetSerial = 0x01,
18  kGetSerialResp = 0x41,
19  kGetHwId = 0x02,
20  kGetHwIdResp = 0x42,
21  kGetPkey = 0x03,
22  kGetPkeyResp = 0x43,
23  kGetRootVer = 0x04,
24  kGetRootVerResp = 0x44,
25  kGetManifest = 0x05,
26  kGetManifestResp = 0x45,
27  kPutRoot = 0x06,
28  kPutTargets = 0x07,
29  kPutImageChunk = 0x08,
30  kPutImageChunkAckErr = 0x48,
31 };
32 
33 namespace Uptane {
34 
35 IsoTpSecondary::IsoTpSecondary(const std::string& can_iface, uint16_t can_id)
36  : conn(can_iface, LIBUPTINY_ISOTP_PRIMARY_CANID, can_id) {}
37 
38 EcuSerial IsoTpSecondary::getSerial() const {
39  std::string out;
40  std::string in;
41 
42  out += static_cast<char>(IsoTpUptaneMesType::kGetSerial);
43  if (!conn.SendRecv(out, &in)) {
44  return EcuSerial::Unknown();
45  }
46 
47  if (in[0] != static_cast<char>(IsoTpUptaneMesType::kGetSerialResp)) {
48  return EcuSerial::Unknown();
49  }
50  return EcuSerial(in.substr(1));
51 }
52 
53 HardwareIdentifier IsoTpSecondary::getHwId() const {
54  std::string out;
55  std::string in;
56 
57  out += static_cast<char>(IsoTpUptaneMesType::kGetHwId);
58  if (!conn.SendRecv(out, &in)) {
59  return HardwareIdentifier::Unknown();
60  }
61 
62  if (in[0] != static_cast<char>(IsoTpUptaneMesType::kGetHwIdResp)) {
63  return HardwareIdentifier::Unknown();
64  }
65  return HardwareIdentifier(in.substr(1));
66 }
67 
68 PublicKey IsoTpSecondary::getPublicKey() const {
69  std::string out;
70  std::string in;
71 
72  out += static_cast<char>(IsoTpUptaneMesType::kGetPkey);
73  if (!conn.SendRecv(out, &in)) {
74  return PublicKey("", KeyType::kUnknown);
75  }
76 
77  if (in[0] != static_cast<char>(IsoTpUptaneMesType::kGetPkeyResp)) {
78  return PublicKey("", KeyType::kUnknown);
79  }
80  return PublicKey(boost::algorithm::hex(in.substr(1)), KeyType::kED25519);
81 }
82 
83 Uptane::Manifest IsoTpSecondary::getManifest() const {
84  std::string out;
85  std::string in;
86 
87  out += static_cast<char>(IsoTpUptaneMesType::kGetManifest);
88  if (!conn.SendRecv(out, &in)) {
89  return Json::Value(Json::nullValue);
90  }
91 
92  if (in[0] != static_cast<char>(IsoTpUptaneMesType::kGetManifestResp)) {
93  return Json::Value(Json::nullValue);
94  }
95  return Utils::parseJSON(in.substr(1));
96 }
97 
98 int IsoTpSecondary::getRootVersion(bool director) const {
99  if (!director) {
100  return 0;
101  }
102 
103  std::string out;
104  std::string in;
105 
106  out += static_cast<char>(IsoTpUptaneMesType::kGetRootVer);
107  if (!conn.SendRecv(out, &in)) {
108  return -1;
109  }
110 
111  if (in[0] != static_cast<char>(IsoTpUptaneMesType::kGetRootVerResp)) {
112  return -1;
113  }
114  try {
115  return boost::lexical_cast<int>(in.substr(1));
116  } catch (boost::bad_lexical_cast const&) {
117  return -1;
118  }
119 }
120 
121 bool IsoTpSecondary::putRoot(const std::string& root, bool director) {
122  if (!director) {
123  return true;
124  }
125  std::string out;
126  out += static_cast<char>(IsoTpUptaneMesType::kPutRoot);
127  out += root;
128 
129  return conn.Send(out);
130 }
131 
132 bool IsoTpSecondary::putMetadata(const RawMetaPack& meta_pack) {
133  std::string out;
134  out += static_cast<char>(IsoTpUptaneMesType::kPutTargets);
135  out += meta_pack.director_targets;
136 
137  return conn.Send(out);
138 }
139 
140 bool IsoTpSecondary::sendFirmware(const std::string& data) {
141  size_t num_chunks = 1 + (data.length() - 1) / kChunkSize;
142 
143  if (num_chunks > 127) {
144  return false;
145  }
146 
147  for (size_t i = 0; i < num_chunks; ++i) {
148  std::string out;
149  std::string in;
150  out += static_cast<char>(IsoTpUptaneMesType::kPutImageChunk);
151  out += static_cast<char>(num_chunks);
152  out += static_cast<char>(i + 1);
153  if (i == num_chunks - 1) {
154  out += data.substr(static_cast<size_t>(i * kChunkSize));
155  } else {
156  out += data.substr(static_cast<size_t>(i * kChunkSize), static_cast<size_t>(kChunkSize));
157  }
158  if (!conn.SendRecv(out, &in)) {
159  return false;
160  }
161  if (in[0] != static_cast<char>(IsoTpUptaneMesType::kPutImageChunkAckErr)) {
162  return false;
163  }
164 
165  if (in[1] != 0x00) {
166  return false;
167  }
168  }
169  return true;
170 }
171 } // namespace Uptane
General data structures.
Definition: types.cc:55
Base data types that are used in The Update Framework (TUF), part of Uptane.