21#include <radio_tool/fw/cs_fw.hpp>
22#include <radio_tool/fw/cipher/cs800.hpp>
23#include <radio_tool/fw/cipher/dr5xx0.hpp>
24#include <radio_tool/util.hpp>
35 std::ifstream in_file(fw, std::ios_base::binary);
36 if (in_file.is_open())
38 in_file.seekg(0, std::fstream::end);
39 auto len = in_file.tellg();
40 in_file.seekg(0, std::fstream::beg);
45 if (header.imagesize == 0)
47 throw std::runtime_error(
"Invalid firmware file");
49 if (header.imagesize + header.imageHeaderSize +
sizeof(uint16_t) != len)
51 throw std::runtime_error(
"Invalid firmware header");
54 data.resize(header.imagesize);
55 in_file.read((
char*)data.data(), header.imagesize);
56 in_file.read((
char*)&checksum,
sizeof(uint16_t));
60 ((uint8_t*)&checksum)[0] = ((uint8_t*)&checksum)[0] ^
cipher::cs800_0[header.imagesize % cipher::cs800_length];
61 ((uint8_t*)&checksum)[1] = ((uint8_t*)&checksum)[1] ^
cipher::cs800_0[(header.imagesize + 1) % cipher::cs800_length];
63 memory_ranges.push_back({ header.baseaddr_offset, header.imagesize });
66 auto cs_check = MakeChecksum();
67 if (cs_check != checksum)
70 throw std::runtime_error(
"Invalid checksum");
75 throw std::runtime_error(
"Cant open file");
79auto CSFW::UpdateHeader() ->
void
81 if (memory_ranges.size() != 1)
83 throw std::runtime_error(
"CS Firmware can only contain one segment!");
85 header.imagesize = data.size();
88 if (memory_ranges.size())
90 header.baseaddr_offset = memory_ranges[0].first;
96 std::ofstream of(fw, std::ios_base::binary);
100 auto data = MakeFiledata();
101 of.write((
char*)data.data(), data.size());
104 ApplyXOR(data.begin() + header.imageHeaderSize, data.end(),
cipher::cs800_0, cipher::cs800_length);
105 auto cs = CSChecksum(data.begin(), data.end());
108 ((uint8_t*)&cs)[0] = ((uint8_t*)&cs)[0] ^
cipher::cs800_0[header.imagesize % cipher::cs800_length];
109 ((uint8_t*)&cs)[1] = ((uint8_t*)&cs)[1] ^
cipher::cs800_0[(header.imagesize + 1) % cipher::cs800_length];
111 of.write((
char*)&cs,
sizeof(cs));
119 std::stringstream out;
121 out <<
"== Connect Systems Firmware ==" << std::endl
122 <<
"Image Size: " << FormatBytes(header.imagesize) << std::endl
123 <<
"Version: " << header.version << std::endl
124 <<
"Checksum: 0x" << std::setw(4) << std::setfill(
'0') << std::hex << checksum << std::endl
125 <<
"Data Segments: " << std::endl;
130 out <<
" " << n++ <<
": Start=0x" << std::setfill(
'0') << std::setw(8) << std::hex << m.first
131 <<
", Length=0x" << std::setfill(
'0') << std::setw(8) << std::hex << m.second
163 std::ifstream in_file(file, std::ios_base::binary);
164 if (in_file.is_open())
168 in_file.seekg(0, std::ios_base::end);
169 auto len = in_file.tellg();
173 if (header.imagesize == 0)
179 if (header.imagesize + header.imageHeaderSize +
sizeof(uint16_t) != len)
189auto CSFW::SupportsRadioModel(
const std::string& model) ->
bool
192 if (model ==
"CS800")
199auto CSFW::MakeChecksum() const -> uint16_t
202 auto to_check = MakeFiledata();
205 ApplyXOR(to_check.begin() + header.imageHeaderSize, to_check.end(),
cipher::cs800_0, cipher::cs800_length);
207 return CSChecksum(to_check.begin(), to_check.end());
210auto CSFW::MakeFiledata() const -> std::vector<uint8_t>
212 auto h_ptr = (uint8_t*)&header;
213 std::vector<uint8_t> ret;
214 ret.reserve(header.imageHeaderSize + header.imagesize);
216 std::copy(h_ptr, h_ptr +
sizeof(
CS800D_header), std::back_inserter(ret));
217 std::copy(
data.begin(),
data.end(), std::back_inserter(ret));
224 if (
typeid(Other) !=
typeid(
this)) {
228 auto afw =
dynamic_cast<const CSFW*
>(Other);