18#include <radio_tool/hid/tyt_hid.hpp>
19#include <radio_tool/util.hpp>
25auto TYTHID::Setup() ->
void
29 err = libusb_set_configuration(device, 0x01);
30 if (err != LIBUSB_SUCCESS)
33 throw std::runtime_error(libusb_error_name(err));
35 err = libusb_claim_interface(device, 0x00);
36 if (err != LIBUSB_SUCCESS)
39 throw std::runtime_error(libusb_error_name(err));
41 err = libusb_control_transfer(device, 0x21, 0x0a, 0, 0,
nullptr, 0, timeout);
42 if (err != LIBUSB_SUCCESS)
45 throw std::runtime_error(libusb_error_name(err));
48 auto buffer = (uint8_t*)malloc(64);
49 auto tx = libusb_alloc_transfer(0);
50 libusb_fill_interrupt_transfer(
51 tx, device, TYTHID::EP_IN, buffer, 64, [](libusb_transfer* tx)
53 auto self = (
TYTHID*)tx->user_data;
57 libusb_submit_transfer(tx);
60auto TYTHID::OnTransfer(libusb_transfer* tx) ->
void
62 if (tx->status == LIBUSB_TRANSFER_COMPLETED ||
63 tx->status == LIBUSB_TRANSFER_TIMED_OUT)
66 std::lock_guard<std::mutex> lk(signalCallback);
69 signalReady.notify_one();
73 std::unique_lock<std::mutex> lk(signalCallback);
74 auto tx_local = &this->tx;
75 signalReady.wait(lk, [tx_local]
76 {
return *tx_local ==
nullptr; });
79 libusb_submit_transfer(tx);
84 std::vector<uint8_t> payload(std::max(42, (
int)cmd.data.size()));
85 std::fill(payload.begin(), payload.end(), 0x00);
87 auto nums = (uint16_t*)payload.data();
88 nums[0] = (uint16_t)cmd.type;
89 nums[1] = cmd.data.size();
90 std::copy(cmd.data.begin(), cmd.data.end(), payload.begin() + 4);
92 InterruptWrite(TYTHID::EP_OUT, payload);
95auto TYTHID::SendCommand(
const std::vector<uint8_t>& cmd) ->
void
97 SendCommand(
tyt::Command(tyt::CommandType::DeviceToHost, cmd.size(), cmd));
100auto TYTHID::SendCommand(
const std::vector<uint8_t>& cmd,
const uint8_t& size,
const uint8_t& fill) ->
void
102 auto ncmd = std::vector<uint8_t>(size, fill);
103 std::copy(cmd.begin(), cmd.end(), ncmd.begin());
110 std::unique_lock<std::mutex> lk(signalCallback);
111 auto tx_local = &this->tx;
112 signalReady.wait(lk, [tx_local]
113 {
return *tx_local !=
nullptr; });
115 if (tx->status == LIBUSB_TRANSFER_COMPLETED)
118 auto nums = (uint16_t*)tx->buffer;
119 auto ret =
tyt::Command((tyt::CommandType)nums[0], nums[1], std::vector<uint8_t>(tx->buffer + 4, tx->buffer + 4 + nums[1]));
120 radio_tool::PrintHex(ret.data.begin(), ret.data.end());
124 signalReady.notify_one();
128 throw std::runtime_error(
"USB TRANSFER ERROR");
131auto TYTHID::SendCommandAndOk(
const tyt::Command& cmd) ->
void
134 auto ok = WaitForReply();
135 if (!(ok == tyt::OKResponse))
137 radio_tool::PrintHex(ok.data.begin(), ok.data.end());
138 throw std::runtime_error(
"Invalid usb response from device");
142auto TYTHID::SendCommandAndOk(
const std::vector<uint8_t>& cmd) ->
void
145 auto ok = WaitForReply();
146 if (!(ok == tyt::OKResponse))
148 radio_tool::PrintHex(ok.data.begin(), ok.data.end());
149 throw std::runtime_error(
"Invalid usb response from device");
153auto TYTHID::SendCommandAndOk(
const std::vector<uint8_t>& cmd,
const uint8_t& size,
const uint8_t& fill) ->
void
155 SendCommand(cmd, size, fill);
156 auto ok = WaitForReply();
157 if (!(ok == tyt::OKResponse))
159 radio_tool::PrintHex(ok.data.begin(), ok.data.end());
160 throw std::runtime_error(
"Invalid usb response from device");