Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix two issues preventing Garmin devices working #1

Merged
merged 2 commits into from
Nov 1, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Fix not reading partial responses correctly
When dealing with a separate header and payload, make sure that we
do not expect to receive additional USB packet headers in the payload portion of
the transfer. Previously, we were assuming that this would only occur when the
device was sending more than a full packet's worth of data, but this is not correct -
we should continue the bulk transfer any time the device sends us less data than
the header says it will be sending.
  • Loading branch information
CodyJung committed Jul 24, 2022
commit d76b37a6329c3bf976bb3d0f848d0e6a41e22744
19 changes: 10 additions & 9 deletions mtp/mtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,21 +304,21 @@ func (d *Device) sendReq(req *Container) error {

// Fetches one USB packet. The header is split off, and the remainder is returned.
// dest should be at least 512bytes.
func (d *Device) fetchPacket(dest []byte, header *usbBulkHeader) (rest []byte, err error) {
func (d *Device) fetchPacket(dest []byte, header *usbBulkHeader) (rest []byte, bytesRead int, err error) {
n, err := d.h.BulkTransfer(d.fetchEP, dest[:d.fetchMaxPacketSize()], d.Timeout)
if n > 0 {
d.dataPrint(d.fetchEP, dest[:n])
}

if err != nil {
return nil, err
return nil, n, err
}

buf := bytes.NewBuffer(dest[:n])
if err = binary.Read(buf, binary.LittleEndian, header); err != nil {
return nil, err
return nil, n, err
}
return buf.Bytes(), nil
return buf.Bytes(), n, nil
}

func (d *Device) decodeRep(h *usbBulkHeader, rest []byte, rep *Container) error {
Expand Down Expand Up @@ -419,7 +419,7 @@ func (d *Device) runTransaction(req *Container, rep *Container,
fetchPacketSize := d.fetchMaxPacketSize()
data := make([]byte, fetchPacketSize)
h := &usbBulkHeader{}
rest, err := d.fetchPacket(data[:], h)
rest, n, err := d.fetchPacket(data[:], h)
if err != nil {
return err
}
Expand All @@ -438,9 +438,10 @@ func (d *Device) runTransaction(req *Container, rep *Container,

dest.Write(rest)

if len(rest)+usbHdrLen == fetchPacketSize {
// If this was a full packet, read until we
// have a short read.
if len(rest)+usbHdrLen == fetchPacketSize || uint32(n) < h.Length {
// If this was a full packet, or if the packet wasn't full but
// the device said it was sending more data than we received,
// continue reading until we have a read less than a full packet.
_, finalPacket, err = d.bulkRead(dest, progressCb)
if err != nil {
return err
Expand All @@ -456,7 +457,7 @@ func (d *Device) runTransaction(req *Container, rep *Container,
finalBuf := bytes.NewBuffer(finalPacket[:len(finalPacket)])
err = binary.Read(finalBuf, binary.LittleEndian, h)
} else {
rest, err = d.fetchPacket(data[:], h)
rest, _, err = d.fetchPacket(data[:], h)
}
}

Expand Down