radio_tool 0.2.1
Loading...
Searching...
No Matches
tyt_hid.cpp
1
18#include <radio_tool/hid/tyt_hid.hpp>
19#include <radio_tool/util.hpp>
20
21#include <stdexcept>
22
23using namespace radio_tool::hid;
24
25auto TYTHID::Setup() -> void
26{
27 auto err = 0;
28
29 err = libusb_set_configuration(device, 0x01);
30 if (err != LIBUSB_SUCCESS)
31 {
32 libusb_close(device);
33 throw std::runtime_error(libusb_error_name(err));
34 }
35 err = libusb_claim_interface(device, 0x00);
36 if (err != LIBUSB_SUCCESS)
37 {
38 libusb_close(device);
39 throw std::runtime_error(libusb_error_name(err));
40 }
41 err = libusb_control_transfer(device, 0x21, 0x0a, 0, 0, nullptr, 0, timeout);
42 if (err != LIBUSB_SUCCESS)
43 {
44 libusb_close(device);
45 throw std::runtime_error(libusb_error_name(err));
46 }
47
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)
52 {
53 auto self = (TYTHID*)tx->user_data;
54 self->OnTransfer(tx);
55 },
56 this, 5000);
57 libusb_submit_transfer(tx);
58}
59
60auto TYTHID::OnTransfer(libusb_transfer* tx) -> void
61{
62 if (tx->status == LIBUSB_TRANSFER_COMPLETED ||
63 tx->status == LIBUSB_TRANSFER_TIMED_OUT)
64 {
65 {
66 std::lock_guard<std::mutex> lk(signalCallback);
67 this->tx = tx;
68 }
69 signalReady.notify_one();
70
71 //wait again for item to be read
72 {
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; });
77 }
78 }
79 libusb_submit_transfer(tx);
80}
81
82auto TYTHID::SendCommand(const tyt::Command& cmd) -> void
83{
84 std::vector<uint8_t> payload(std::max(42, (int)cmd.data.size()));
85 std::fill(payload.begin(), payload.end(), 0x00);
86
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);
91
92 InterruptWrite(TYTHID::EP_OUT, payload);
93}
94
95auto TYTHID::SendCommand(const std::vector<uint8_t>& cmd) -> void
96{
97 SendCommand(tyt::Command(tyt::CommandType::DeviceToHost, cmd.size(), cmd));
98}
99
100auto TYTHID::SendCommand(const std::vector<uint8_t>& cmd, const uint8_t& size, const uint8_t& fill) -> void
101{
102 auto ncmd = std::vector<uint8_t>(size, fill);
103 std::copy(cmd.begin(), cmd.end(), ncmd.begin());
104
105 SendCommand(ncmd);
106}
107
108auto TYTHID::WaitForReply() -> tyt::Command
109{
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; });
114
115 if (tx->status == LIBUSB_TRANSFER_COMPLETED)
116 {
117 //setup return
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());
121
122 tx = nullptr;
123 lk.unlock();
124 signalReady.notify_one();
125 return ret;
126 }
127
128 throw std::runtime_error("USB TRANSFER ERROR");
129}
130
131auto TYTHID::SendCommandAndOk(const tyt::Command& cmd) -> void
132{
133 SendCommand(cmd);
134 auto ok = WaitForReply();
135 if (!(ok == tyt::OKResponse))
136 {
137 radio_tool::PrintHex(ok.data.begin(), ok.data.end());
138 throw std::runtime_error("Invalid usb response from device");
139 }
140}
141
142auto TYTHID::SendCommandAndOk(const std::vector<uint8_t>& cmd) -> void
143{
144 SendCommand(cmd);
145 auto ok = WaitForReply();
146 if (!(ok == tyt::OKResponse))
147 {
148 radio_tool::PrintHex(ok.data.begin(), ok.data.end());
149 throw std::runtime_error("Invalid usb response from device");
150 }
151}
152
153auto TYTHID::SendCommandAndOk(const std::vector<uint8_t>& cmd, const uint8_t& size, const uint8_t& fill) -> void
154{
155 SendCommand(cmd, size, fill);
156 auto ok = WaitForReply();
157 if (!(ok == tyt::OKResponse))
158 {
159 radio_tool::PrintHex(ok.data.begin(), ok.data.end());
160 throw std::runtime_error("Invalid usb response from device");
161 }
162}