18#include <radio_tool/radio/tyt_sgl_radio.hpp>
19#include <radio_tool/radio/radio_factory.hpp>
20#include <radio_tool/fw/tyt_fw_sgl.hpp>
29TYTSGLRadio::TYTSGLRadio(libusb_device_handle *h) : device(h)
36 std::stringstream out;
38 out <<
"== TYT SGL Radio Info ==" << std::endl
51 auto config = fw.GetConfig();
53 device.SendCommand(hid::tyt::commands::Download);
54 auto rsp = device.WaitForReply();
55 if (std::equal(rsp.data.begin(), rsp.data.end(), hid::tyt::commands::Update.begin()))
57 device.SendCommandAndOk(hid::tyt::OK);
61 auto download_rsp = std::string(rsp.data.begin(), rsp.data.end());
62 auto update_rsp = std::string(hid::tyt::commands::Update.begin(), hid::tyt::commands::Update.end());
63 std::stringstream msg(
"Invalid response, expected '");
64 msg << update_rsp <<
"'"
65 <<
" got '" << download_rsp <<
"'";
67 throw new std::runtime_error(msg.str());
71 device.SendCommand(std::vector<uint8_t>(config->header.model_key.begin(), config->header.model_key.end()), 0x08, 0xff);
72 auto rsp_key = device.WaitForReply();
73 if (!std::equal(rsp_key.data.begin(), rsp_key.data.end(), config->header.model_key.begin()))
75 auto key_rsp = std::string(rsp_key.data.begin(), rsp_key.data.end());
76 std::stringstream msg(
"Invalid response, expected firmware key '");
77 msg << config->header.model_key <<
"'"
78 <<
" got '" << key_rsp <<
"'";
80 throw new std::runtime_error(msg.str());
83 device.SendCommandAndOk(hid::tyt::commands::FlashProgram);
85 device.SendCommandAndOk(std::vector<uint8_t>(config->header.radio_group.begin(), config->header.radio_group.end()), 0x10, 0xff);
86 device.SendCommandAndOk(std::vector<uint8_t>(config->header.radio_model.begin(), config->header.radio_model.end()), 0x08, 0xff);
87 device.SendCommandAndOk(std::vector<uint8_t>(config->header.protocol_version.begin(), config->header.protocol_version.end()));
89 device.SendCommandAndOk(hid::tyt::commands::FlashErase);
90 device.SendCommandAndOk(hid::tyt::OK);
91 device.SendCommandAndOk(hid::tyt::commands::Program);
93 constexpr auto TransferSize = 0x20u;
94 constexpr auto HeaderSize = 0x06u;
95 constexpr auto ChecksumBlockSize = 0x400u;
97 auto buf = std::vector<uint8_t>(TransferSize + HeaderSize);
100 auto checksumBlock = 0;
101 while (address < binary.size)
103 auto transferSize = std::min(TransferSize, binary.size - address);
104 *(uint32_t *)buf.data() = address;
105 *(uint16_t *)(buf.data() + 4) = transferSize;
107 auto src = binary.data.begin() + address;
108 std::copy(src, src + transferSize, buf.begin() + HeaderSize);
110 device.SendCommandAndOk(buf);
112 address += transferSize;
113 if (address % ChecksumBlockSize == 0 || address == binary.size)
115 auto start = ChecksumBlockSize * checksumBlock;
118 auto checksumCommand = std::vector<uint8_t>(hid::tyt::commands::End.size() + 5, 0xff);
119 std::copy(hid::tyt::commands::End.begin(), hid::tyt::commands::End.end(), checksumCommand.begin());
120 *(uint32_t *)(checksumCommand.data() + hid::tyt::commands::End.size()) = checksum(binary.data.begin() + start, binary.data.begin() + end);
121 device.SendCommandAndOk(checksumCommand);
128auto TYTSGLRadio::checksum(std::vector<uint8_t>::const_iterator &&begin, std::vector<uint8_t>::const_iterator &&end)
const -> uint32_t
130 uint32_t counter = 0;
134 std::advance(begin, 1);