fix set interface
This commit is contained in:
parent
9d10beec9b
commit
e327bad9c6
BIN
bin/usb-client
BIN
bin/usb-client
Binary file not shown.
BIN
bin/usb-relay
BIN
bin/usb-relay
Binary file not shown.
|
|
@ -360,21 +360,59 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
|||
}
|
||||
|
||||
if endpoint == 0 && hdr.Direction == DirOut {
|
||||
buf := transferBuf
|
||||
if buf == nil {
|
||||
buf = make([]byte, 0)
|
||||
}
|
||||
_, err := s.handle.ControlTransfer(
|
||||
body.Setup[0], body.Setup[1],
|
||||
binary.LittleEndian.Uint16(body.Setup[2:4]),
|
||||
binary.LittleEndian.Uint16(body.Setup[4:6]),
|
||||
binary.LittleEndian.Uint16(body.Setup[6:8]),
|
||||
5000, buf,
|
||||
)
|
||||
bmRequestType := body.Setup[0]
|
||||
bRequest := body.Setup[1]
|
||||
wValue := binary.LittleEndian.Uint16(body.Setup[2:4])
|
||||
wIndex := binary.LittleEndian.Uint16(body.Setup[4:6])
|
||||
|
||||
var status int32
|
||||
if err != nil {
|
||||
status = -32 // -EPIPE
|
||||
|
||||
// Intercept standard USB requests that require special usbdevfs ioctls.
|
||||
// Raw control transfers via USBDEVFS_CONTROL don't update kernel state.
|
||||
switch {
|
||||
case bmRequestType == 0x01 && bRequest == 0x0B:
|
||||
// SET_INTERFACE (Standard, Interface recipient)
|
||||
// MUST use USBDEVFS_SETINTERFACE so the kernel updates endpoint state
|
||||
// and allocates bandwidth for ISO endpoints (critical for webcams).
|
||||
if err := s.handle.SetInterface(uint32(wIndex), uint32(wValue)); err != nil {
|
||||
log.Printf("[usbip-server] SET_INTERFACE(iface=%d, alt=%d) failed: %v", wIndex, wValue, err)
|
||||
status = -32 // -EPIPE
|
||||
} else {
|
||||
log.Printf("[usbip-server] SET_INTERFACE(iface=%d, alt=%d) OK", wIndex, wValue)
|
||||
}
|
||||
|
||||
case bmRequestType == 0x00 && bRequest == 0x09:
|
||||
// SET_CONFIGURATION (Standard, Device recipient)
|
||||
if err := s.handle.SetConfiguration(uint32(wValue)); err != nil {
|
||||
log.Printf("[usbip-server] SET_CONFIGURATION(%d) failed: %v", wValue, err)
|
||||
status = -32
|
||||
} else {
|
||||
log.Printf("[usbip-server] SET_CONFIGURATION(%d) OK", wValue)
|
||||
}
|
||||
|
||||
case bmRequestType == 0x02 && bRequest == 0x01 && wValue == 0x0000:
|
||||
// CLEAR_FEATURE(ENDPOINT_HALT) (Standard, Endpoint recipient)
|
||||
if err := s.handle.ClearHalt(uint32(wIndex)); err != nil {
|
||||
log.Printf("[usbip-server] CLEAR_HALT(ep=0x%02x) failed: %v", wIndex, err)
|
||||
status = -32
|
||||
}
|
||||
|
||||
default:
|
||||
// Generic OUT control transfer
|
||||
buf := transferBuf
|
||||
if buf == nil {
|
||||
buf = make([]byte, 0)
|
||||
}
|
||||
_, err := s.handle.ControlTransfer(
|
||||
bmRequestType, bRequest, wValue, wIndex,
|
||||
binary.LittleEndian.Uint16(body.Setup[6:8]),
|
||||
5000, buf,
|
||||
)
|
||||
if err != nil {
|
||||
status = -32 // -EPIPE
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, status, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -388,8 +426,11 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
|||
ep |= 0x80
|
||||
}
|
||||
|
||||
// Handle isochronous transfers
|
||||
if urbType == 0 && numPackets > 0 {
|
||||
// Handle isochronous transfers.
|
||||
// Trust the USB/IP NumberOfPackets field rather than our endpoint type map,
|
||||
// because the map is built at enumeration time (alternate setting 0) and
|
||||
// webcams only activate ISO endpoints after SET_INTERFACE to alt > 0.
|
||||
if numPackets > 0 {
|
||||
return s.handleISOSubmit(hdr, body, transferBuf, isoDescs, numPackets, ep, retChan)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue