radio_tool 0.2.1
Loading...
Searching...
No Matches
tyt_fw.hpp
1
18#pragma once
19
20#include <radio_tool/fw/fw.hpp>
21#include <radio_tool/fw/cipher/uv3x0.hpp>
22#include <radio_tool/fw/cipher/dm1701.hpp>
23#include <radio_tool/fw/cipher/md380.hpp>
24#include <radio_tool/fw/cipher/md9600.hpp>
25
26#include <fstream>
27#include <cstring>
28#include <sstream>
29#include <memory>
30#include <iomanip>
31
32namespace radio_tool::fw
33{
38 {
39 public:
40 TYTRadioConfig(const std::string& model, const std::string& fw_model, const std::vector<uint8_t>& c_magic, const uint8_t* cipher, const uint32_t& cipher_l)
41 : radio_model(model), firmware_model(fw_model), counter_magic(c_magic), cipher(cipher), cipher_len(cipher_l)
42 {
43 }
44
48 const std::string radio_model;
49
53 const std::string firmware_model;
54
58 const std::vector<uint8_t> counter_magic;
59
63 const uint8_t* cipher;
64
68 const uint32_t cipher_len;
69 };
70
71 namespace tyt::magic
72 {
73 using namespace std::literals::string_literals;
74
75 //OutSecurityBin\0\0
76 const std::vector<uint8_t> begin = { 0x4f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x42, 0x69, 0x6e, 0x00, 0x00 };
77 //OutSecurityBinEnd
78 const std::vector<uint8_t> end = { 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x64 };
79
80 /*
81 * +GPS = Both GPS and Non-GPS versions have the same magic value
82 * CSV = DMR Database upload as CSV support
83 * REC = Recording
84 */
85 const std::vector<uint8_t> MD2017_D = { 0x02, 0x19, 0x0c }; //MD-2017 (REC)
86 const std::vector<uint8_t> MD2017_S = { 0x02, 0x18, 0x0c }; //MD-2017 GPS (REC)
87 const std::vector<uint8_t> MD2017_V = { 0x01, 0x19 }; //MD-2017 (CSV)
88 const std::vector<uint8_t> MD2017_P = { 0x01, 0x18 }; //MD-2017 GPS (CSV)
89
90 const std::vector<uint8_t> MD9600 = { 0x01, 0x14 }; //MD-9600 (REC/CSV) +GPS
91
92 const std::vector<uint8_t> UV3X0_GPS = { 0x02, 0x16, 0x0c }; //MD-UV3X0 (REC/CSV)(GPS) / RT3S
93 const std::vector<uint8_t> UV3X0 = { 0x02, 0x17, 0x0c }; //MD-UV3X0 (REC/CSV) / RT3S
94
95 const std::vector<uint8_t> DM1701 = { 0x01, 0x0f }; //DM-1701
96
97 const std::vector<uint8_t> MD390 = { 0x01, 0x10 }; //MD-390
98 const std::vector<uint8_t> MD380 = { 0x01, 0x0d }; //MD-380 / MD-446
99 const std::vector<uint8_t> MD280 = { 0x01, 0x1b }; //MD-280
100 } // namespace tyt::magic
101
102 namespace tyt::config
103 {
104 const std::vector<TYTRadioConfig> All = {
105 TYTRadioConfig("MD2017" /* REC */, "MD-9600", tyt::magic::MD2017_D, cipher::uv3x0, cipher::uv3x0_length),
106 TYTRadioConfig("MD2017 GPS" /* REC */, "MD-9600", tyt::magic::MD2017_S, cipher::uv3x0, cipher::uv3x0_length),
107 TYTRadioConfig("MD2017" /* CSV */, "MD-9600", tyt::magic::MD2017_V, cipher::uv3x0, cipher::uv3x0_length),
108 TYTRadioConfig("MD2017 GPS" /* CSV */, "MD-9600", tyt::magic::MD2017_P, cipher::uv3x0, cipher::uv3x0_length),
109 TYTRadioConfig("MD9600", "MD-9600", tyt::magic::MD9600, cipher::md9600, cipher::md9600_length),
110 TYTRadioConfig("UV3X0 GPS", "MD-9600", tyt::magic::UV3X0_GPS, cipher::uv3x0, cipher::uv3x0_length),
111 TYTRadioConfig("UV3X0", "MD-9600", tyt::magic::UV3X0, cipher::uv3x0, cipher::uv3x0_length),
112 TYTRadioConfig("DM1701", "DM1701", tyt::magic::DM1701, cipher::dm1701, cipher::dm1701_length),
113 TYTRadioConfig("MD390", "JST51", tyt::magic::MD390, cipher::md380, cipher::md380_length),
114 TYTRadioConfig("MD380", "JST51", tyt::magic::MD380, cipher::md380, cipher::md380_length),
115 TYTRadioConfig("MD446", "JST51", tyt::magic::MD380, cipher::md380, cipher::md380_length),
116 TYTRadioConfig("MD280", "JST51", tyt::magic::MD280, cipher::md380, cipher::md380_length)
117 };
118 }
122 typedef struct
123 {
124 uint8_t magic[16];
125 uint8_t radio[16];
126 uint32_t n1, n2, n3, n4;
127 uint8_t counter_magic[76];
128 uint32_t n_regions;
130 static_assert(sizeof(TYTFirmwareHeader) == 128);
131
132 class TYTFW : public FirmwareSupport
133 {
134 public:
135 TYTFW() {}
136 TYTFW(const std::vector<uint8_t>& cMagic)
137 : FirmwareSupport(0x200), counterMagic(cMagic)
138 { }
139
140 auto Read(const std::string& file) -> void override;
141 auto Write(const std::string& file) -> void override;
142 auto ToString() const->std::string override;
143 auto Decrypt() -> void override;
144 auto Encrypt() -> void override;
145 auto SetRadioModel(const std::string&) -> void override;
146 auto IsCompatible(const FirmwareSupport* Other) const -> bool override;
147
151 auto GetRadioModel() const -> const std::string override;
152
157 static auto GetCounterMagic(const std::string& radio) -> const std::vector<uint8_t>
158 {
159 for (const auto& r : tyt::config::All)
160 {
161 if (r.radio_model == radio)
162 {
163 return r.counter_magic;
164 }
165 }
166 throw std::runtime_error("Radio not supported");
167 }
168
173 static auto GetRadioFromMagic(const std::vector<uint8_t>& cm) -> const std::string
174 {
175 for (const auto& r : tyt::config::All)
176 {
177 if (r.counter_magic.size() != cm.size())
178 continue;
179 /* GCC doesnt seem to mind which is longer, MSVC tries to read past the end of [first2] */
180 if (std::equal(cm.begin(), cm.end(), r.counter_magic.begin()))
181 {
182 return r.radio_model;
183 }
184 }
185 throw std::runtime_error("Radio not supported");
186 }
187
191 static auto SupportsFirmwareFile(const std::string& file) -> bool;
192
196 static auto SupportsRadioModel(const std::string& model) -> bool;
197
201 static auto Create() -> std::unique_ptr<FirmwareSupport>
202 {
203 return std::make_unique<TYTFW>();
204 }
205
206 private:
207 std::vector<uint8_t> counterMagic; //2-3 bytes
208 std::string firmware_model, radio_model;
209
210 static auto ReadHeader(std::ifstream&)->TYTFirmwareHeader;
211 static auto CheckHeader(const TYTFirmwareHeader&) -> void;
212 auto ApplyXOR() -> void;
213 };
214
215} // namespace radio_tool::fw
auto Write(const std::string &file) -> void override
Definition: tyt_fw.cpp:58
auto Read(const std::string &file) -> void override
Definition: tyt_fw.cpp:23
static auto GetRadioFromMagic(const std::vector< uint8_t > &cm) -> const std::string
Definition: tyt_fw.hpp:173
static auto Create() -> std::unique_ptr< FirmwareSupport >
Definition: tyt_fw.hpp:201
auto IsCompatible(const FirmwareSupport *Other) const -> bool override
Definition: tyt_fw.cpp:270
static auto SupportsRadioModel(const std::string &model) -> bool
Definition: tyt_fw.cpp:205
auto SetRadioModel(const std::string &) -> void override
Definition: tyt_fw.cpp:223
auto GetRadioModel() const -> const std::string override
Definition: tyt_fw.cpp:217
auto Decrypt() -> void override
Definition: tyt_fw.cpp:237
auto Encrypt() -> void override
Definition: tyt_fw.cpp:242
auto ToString() const -> std::string override
Definition: tyt_fw.cpp:115
static auto GetCounterMagic(const std::string &radio) -> const std::vector< uint8_t >
Definition: tyt_fw.hpp:157
static auto SupportsFirmwareFile(const std::string &file) -> bool
Definition: tyt_fw.cpp:179
const uint8_t * cipher
Definition: tyt_fw.hpp:63
const std::vector< uint8_t > counter_magic
Definition: tyt_fw.hpp:58
const std::string firmware_model
Definition: tyt_fw.hpp:53
const uint32_t cipher_len
Definition: tyt_fw.hpp:68
const std::string radio_model
Definition: tyt_fw.hpp:48
const unsigned char md380[md380_length]
Definition: md380.hpp:26
const unsigned char dm1701[dm1701_length]
Definition: dm1701.hpp:27