Fix ActualLength=0 for OUT transfers in BuildRetSubmit
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -267,8 +267,11 @@ func BuildImportReply(status uint32, dev *DeviceDescriptor) ([]byte, error) {
|
|||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildRetSubmit builds a RET_SUBMIT message
|
// BuildRetSubmit builds a RET_SUBMIT message.
|
||||||
func BuildRetSubmit(seqNum, devID, direction, endpoint uint32, status int32, data []byte) ([]byte, error) {
|
// actualLength must be set for BOTH directions: it reports how many bytes
|
||||||
|
// were actually transferred. For OUT transfers the kernel driver checks this
|
||||||
|
// (e.g. UVC probe control expects actualLength == 26).
|
||||||
|
func BuildRetSubmit(seqNum, devID, direction, endpoint uint32, status int32, actualLength uint32, data []byte) ([]byte, error) {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
|
|
||||||
hdr := &URBHeader{
|
hdr := &URBHeader{
|
||||||
@@ -282,14 +285,9 @@ func BuildRetSubmit(seqNum, devID, direction, endpoint uint32, status int32, dat
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
actualLen := uint32(0)
|
|
||||||
if direction == DirIn && data != nil {
|
|
||||||
actualLen = uint32(len(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
body := &RetSubmitBody{
|
body := &RetSubmitBody{
|
||||||
Status: status,
|
Status: status,
|
||||||
ActualLength: actualLen,
|
ActualLength: actualLength,
|
||||||
NumberOfPackets: 0xFFFFFFFF,
|
NumberOfPackets: 0xFFFFFFFF,
|
||||||
}
|
}
|
||||||
if err := WriteRetSubmit(buf, body); err != nil {
|
if err := WriteRetSubmit(buf, body); err != nil {
|
||||||
@@ -307,7 +305,7 @@ func BuildRetSubmit(seqNum, devID, direction, endpoint uint32, status int32, dat
|
|||||||
// BuildRetSubmitISO builds a RET_SUBMIT message for isochronous transfers.
|
// BuildRetSubmitISO builds a RET_SUBMIT message for isochronous transfers.
|
||||||
// The transfer data must already be packed (compact, no gaps).
|
// The transfer data must already be packed (compact, no gaps).
|
||||||
func BuildRetSubmitISO(seqNum, devID, direction, endpoint uint32, status int32,
|
func BuildRetSubmitISO(seqNum, devID, direction, endpoint uint32, status int32,
|
||||||
packedData []byte, startFrame uint32, numPackets int32, errorCount int32,
|
actualLength uint32, packedData []byte, startFrame uint32, numPackets int32, errorCount int32,
|
||||||
isoDescs []ISOPacketDescriptor) ([]byte, error) {
|
isoDescs []ISOPacketDescriptor) ([]byte, error) {
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
@@ -323,14 +321,9 @@ func BuildRetSubmitISO(seqNum, devID, direction, endpoint uint32, status int32,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
actualLen := uint32(0)
|
|
||||||
if direction == DirIn && packedData != nil {
|
|
||||||
actualLen = uint32(len(packedData))
|
|
||||||
}
|
|
||||||
|
|
||||||
body := &RetSubmitBody{
|
body := &RetSubmitBody{
|
||||||
Status: status,
|
Status: status,
|
||||||
ActualLength: actualLen,
|
ActualLength: actualLength,
|
||||||
StartFrame: startFrame,
|
StartFrame: startFrame,
|
||||||
NumberOfPackets: uint32(numPackets),
|
NumberOfPackets: uint32(numPackets),
|
||||||
ErrorCount: uint32(errorCount),
|
ErrorCount: uint32(errorCount),
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
|||||||
status = -32 // -EPIPE
|
status = -32 // -EPIPE
|
||||||
n = 0
|
n = 0
|
||||||
}
|
}
|
||||||
resp, err := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, status, buf[:n])
|
resp, err := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, status, uint32(n), buf[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -387,6 +387,7 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
|||||||
wIndex := binary.LittleEndian.Uint16(body.Setup[4:6])
|
wIndex := binary.LittleEndian.Uint16(body.Setup[4:6])
|
||||||
|
|
||||||
var status int32
|
var status int32
|
||||||
|
var actualLength uint32
|
||||||
|
|
||||||
// Intercept standard USB requests that require special usbdevfs ioctls.
|
// Intercept standard USB requests that require special usbdevfs ioctls.
|
||||||
// Raw control transfers via USBDEVFS_CONTROL don't update kernel state.
|
// Raw control transfers via USBDEVFS_CONTROL don't update kernel state.
|
||||||
@@ -415,7 +416,7 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
|||||||
if buf == nil {
|
if buf == nil {
|
||||||
buf = make([]byte, 0)
|
buf = make([]byte, 0)
|
||||||
}
|
}
|
||||||
_, err := s.handle.ControlTransfer(
|
n, err := s.handle.ControlTransfer(
|
||||||
bmRequestType, bRequest, wValue, wIndex,
|
bmRequestType, bRequest, wValue, wIndex,
|
||||||
binary.LittleEndian.Uint16(body.Setup[6:8]),
|
binary.LittleEndian.Uint16(body.Setup[6:8]),
|
||||||
5000, buf,
|
5000, buf,
|
||||||
@@ -424,13 +425,14 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
|||||||
log.Printf("[usbip-server] CTRL OUT seq=%d failed: %v", hdr.SeqNum, err)
|
log.Printf("[usbip-server] CTRL OUT seq=%d failed: %v", hdr.SeqNum, err)
|
||||||
status = -32 // -EPIPE
|
status = -32 // -EPIPE
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[usbip-server] CTRL OUT seq=%d OK (bmReqType=0x%02x bReq=0x%02x wVal=0x%04x)",
|
actualLength = uint32(n)
|
||||||
hdr.SeqNum, bmRequestType, bRequest, wValue)
|
log.Printf("[usbip-server] CTRL OUT seq=%d OK actualLength=%d (bmReqType=0x%02x bReq=0x%02x wVal=0x%04x)",
|
||||||
|
hdr.SeqNum, n, bmRequestType, bRequest, wValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[usbip-server] CTRL OUT seq=%d → response status=%d", hdr.SeqNum, status)
|
log.Printf("[usbip-server] CTRL OUT seq=%d → response status=%d actualLength=%d", hdr.SeqNum, status, actualLength)
|
||||||
resp, err := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, status, nil)
|
resp, err := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, status, actualLength, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -468,7 +470,7 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[usbip-server] SubmitURB(ep=0x%02x, type=%d, len=%d) FAILED: %v", ep, urbType, len(buf), err)
|
log.Printf("[usbip-server] SubmitURB(ep=0x%02x, type=%d, len=%d) FAILED: %v", ep, urbType, len(buf), err)
|
||||||
resp, _ := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, -32, nil)
|
resp, _ := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, -32, 0, nil)
|
||||||
retChan <- resp
|
retChan <- resp
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -535,7 +537,7 @@ func (s *Server) handleISOSubmit(hdr *URBHeader, body *CmdSubmitBody, transferBu
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[usbip-server] ISO submit FAILED: %v", err)
|
log.Printf("[usbip-server] ISO submit FAILED: %v", err)
|
||||||
// Submit failed - send error response
|
// Submit failed - send error response
|
||||||
resp, _ := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, -32, nil)
|
resp, _ := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, -32, 0, nil)
|
||||||
retChan <- resp
|
retChan <- resp
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -653,6 +655,7 @@ func (s *Server) reapLoop(retChan chan<- []byte, done <-chan struct{}) {
|
|||||||
pending.direction,
|
pending.direction,
|
||||||
pending.endpoint,
|
pending.endpoint,
|
||||||
urbInfo.Status,
|
urbInfo.Status,
|
||||||
|
uint32(urbInfo.ActualLength),
|
||||||
data,
|
data,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -708,6 +711,7 @@ func (s *Server) buildISOResponse(urbInfo *usb.ReapedURBInfo, pending *pendingUR
|
|||||||
pending.direction,
|
pending.direction,
|
||||||
pending.endpoint,
|
pending.endpoint,
|
||||||
urbInfo.Status,
|
urbInfo.Status,
|
||||||
|
uint32(urbInfo.ActualLength),
|
||||||
packedData,
|
packedData,
|
||||||
uint32(urbInfo.StartFrame),
|
uint32(urbInfo.StartFrame),
|
||||||
pending.numPackets,
|
pending.numPackets,
|
||||||
|
|||||||
Reference in New Issue
Block a user