4 #include "usbdev_iso.h"
9 #include "usbdev_utils.h"
12 void LIBUSB_CALL USBDevIso::CbStubIN(
struct libusb_transfer *xfr) {
14 self->CallbackIN(xfr);
17 void LIBUSB_CALL USBDevIso::CbStubOUT(
struct libusb_transfer *xfr) {
19 self->CallbackOUT(xfr);
23 int rc = dev_->ClaimInterface(interface);
25 return dev_->ErrorUSB(
"ERROR: Claiming interface", rc);
29 interface_ = interface;
32 epOut_ =
interface + 1U;
33 epIn_ = 0x80U | epOut_;
43 maxPacketSize_ = USBDevice::kDevIsoMaxPacketSize;
51 int rc = dev_->ReleaseInterface(interface_);
53 std::cerr <<
"" << std::endl;
60 while (inActive_ || outActive_) {
64 int rc = dev_->ReleaseInterface(interface_);
66 std::cerr <<
"" << std::endl;
73 int rc = dev_->ClaimInterface(interface_);
75 return dev_->ErrorUSB(
"ERROR: Claiming interface", rc);
94 void USBDevIso::DumpIsoTransfer(
struct libusb_transfer *xfr)
const {
95 for (
int idx = 0U; idx < xfr->num_iso_packets; idx++) {
96 struct libusb_iso_packet_descriptor *pack = &xfrIn_->iso_packet_desc[idx];
97 std::cout <<
"Requested " << pack->length <<
" actual "
98 << pack->actual_length << std::endl;
101 buffer_dump(stdout, (uint8_t *)xfr->buffer, pack->actual_length);
106 bool USBDevIso::ServiceIN() {
113 xfrIn_ = dev_->AllocTransfer(kNumIsoPackets);
119 dev_->FillIsoTransfer(xfrIn_, epIn_, space, maxPacketSize_, kNumIsoPackets,
120 CbStubIN,
this, kIsoTimeout);
121 dev_->SetIsoPacketLengths(xfrIn_, maxPacketSize_);
123 int rc = dev_->SubmitTransfer(xfrIn_);
125 return dev_->ErrorUSB(
"ERROR: Submitting IN transfer", rc);
135 bool USBDevIso::ServiceOUT() {
137 if (pktLen_.empty()) {
141 uint32_t len = pktLen_.front();
145 assert(len >=
sizeof(usbdev_stream_sig_t));
149 assert(num_bytes >= len);
153 xfrOut_ = dev_->AllocTransfer(kNumIsoPackets);
159 dev_->FillIsoTransfer(xfrOut_, epOut_, data, len, kNumIsoPackets, CbStubOUT,
161 dev_->SetIsoPacketLengths(xfrOut_, len);
163 int rc = dev_->SubmitTransfer(xfrOut_);
165 return dev_->ErrorUSB(
"ERROR: Submitting OUT transfer", rc);
179 if (!inActive_ && !ServiceIN()) {
184 if (!outActive_ && !ServiceOUT()) {
191 void USBDevIso::CallbackIN(
struct libusb_transfer *xfr) {
192 if (xfr->status != LIBUSB_TRANSFER_COMPLETED) {
193 std::cerr <<
PrefixID() <<
" Invalid/unexpected IN transfer status "
194 << xfr->status << std::endl;
200 std::cout <<
PrefixID() <<
"CallbackIN xfr " << xfr <<
" num_iso_packets "
201 << xfr->num_iso_packets << std::endl;
202 DumpIsoTransfer(xfr);
205 for (
int idx = 0U; idx < xfr->num_iso_packets; idx++) {
206 struct libusb_iso_packet_descriptor *pack = &xfr->iso_packet_desc[idx];
207 if (pack->status != LIBUSB_TRANSFER_COMPLETED) {
208 std::cerr <<
"ERROR: pack " << idx <<
" status " << pack->status
214 if (pack->actual_length) {
222 usbdev_stream_sig_t sig;
223 uint32_t dropped =
SigDetect(&sig, xfr->buffer, pack->actual_length);
224 if (
SigReceived() && dropped < pack->actual_length &&
225 sizeof(usbdev_stream_sig_t) <= pack->actual_length - dropped) {
231 uint32_t payload = pack->actual_length - dropped;
232 pktLen_.push(payload);
236 uint16_t seq = (uint16_t)((sig.seq_hi << 8) | sig.seq_lo);
237 if (seq == tst_seq_) {
239 std::cerr <<
"ERROR: Unexpected device-side LFSR value (expected 0x"
240 << std::hex <<
tst_lfsr_ <<
" received 0x"
241 << sig.init_lfsr <<
")" << std::dec << std::endl;
245 }
else if (seq < tst_seq_) {
246 std::cerr <<
"ERROR: Iso stream packets out of order (expected seq 0x"
247 << std::hex << tst_seq_ <<
" received 0x" << seq <<
")"
248 << std::dec << std::endl;
262 const size_t sig_size =
sizeof(usbdev_stream_sig_t);
263 uint8_t *dp = &xfr->buffer[dropped];
264 dp[offsetof(usbdev_stream_sig_t, init_lfsr)] =
dpi_lfsr_;
269 std::cerr <<
PrefixID() <<
" received invalid Iso packet of "
270 << pack->actual_length <<
" bytes" << std::endl;
277 failed_ = !ServiceIN();
284 void USBDevIso::CallbackOUT(
struct libusb_transfer *xfr) {
285 if (xfr->status != LIBUSB_TRANSFER_COMPLETED) {
286 std::cerr <<
PrefixID() <<
" Invalid/unexpected OUT transfer status "
287 << xfr->status << std::endl;
293 const void *buf =
reinterpret_cast<void *
>(xfr->buffer);
294 std::cout <<
PrefixID() <<
"CallbackOUT xfr " << xfr <<
" buffer " << buf
295 <<
" num_iso_packets " << xfr->num_iso_packets << std::endl;
296 DumpIsoTransfer(xfr);
299 for (
int idx = 0U; idx < xfr->num_iso_packets; idx++) {
300 struct libusb_iso_packet_descriptor *pack = &xfr->iso_packet_desc[idx];
301 if (pack->status != LIBUSB_TRANSFER_COMPLETED) {
302 std::cout <<
"ERROR: pack " << idx <<
" status " << pack->status
309 if (pack->actual_length) {
316 failed_ = !ServiceOUT();