On Wed, May 20, 2015 at 11:32 AM, Linus Torvalds
<[email protected]> wrote:
>
> I'll try to figure out *why* those three dives fail to download. I
> suspect it's some issue where the length of the dive is just right to
> cause a packetization case that I don't handle right. I'll have to
> analyze those three cases more closely.
Yes.
The "receive_data()" function continues to try to read more data if
the previous packet was full - but in some cases the full packet
contained the final data, and receive_data() is just done and
shouldn't try to read any more.
The attached patch should fix it. Knock wood.
Dirk - can you make a nightly windows build with this, so that it can
get tested? The situation doesn't trigger with my dives, and while I
think I got it right...
Linus
From 529ddffe87d877869fc3a30de8e07c295e95c13f Mon Sep 17 00:00:00 2001
From: Linus Torvalds <[email protected]>
Date: Wed, 20 May 2015 14:16:56 -0700
Subject: [PATCH] suunto eon steel: fix file reading special case
The "receive_data()" function would continue to try to read packets as
long as the previous packet was full-sized, but with just the right size
of file and the right chunking, the file might end at a packet boundary.
Then receive_data() would try to read more data, which fails - there are
no more packets, despite the last packet being full.
This never triggered for me, but Robert Helling forwarded a data dump of
a filure to read a dive due to this.
Since I don't trigger this case, I can't really test it, but I did check
that the new "stop early" logic works for me (ie never triggers ;).
Reported-by: Robert C. Helling <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
---
src/suunto_eonsteel.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c
index ab090bfa29af..35249031a7dd 100644
--- a/src/suunto_eonsteel.c
+++ b/src/suunto_eonsteel.c
@@ -131,7 +131,7 @@ static int receive_data(suunto_eonsteel_device_t *eon, unsigned char *buffer, in
unsigned char buf[64];
int ret = 0;
- for (;;) {
+ while (size > 0) {
int rc, transferred, len;
rc = libusb_interrupt_transfer(eon->handle, InEndpoint, buf, sizeof(buf), &transferred, 5000);
@@ -233,12 +233,15 @@ static int send_receive(suunto_eonsteel_device_t *eon,
unsigned int len_out, const unsigned char *out,
unsigned int len_in, unsigned char *in)
{
- int len, actual;
+ int len, actual, max;
unsigned char buf[2048];
if (send_cmd(eon, cmd, len_out, out) < 0)
return -1;
- len = receive_data(eon, buf, sizeof(buf));
+ max = len_in + 12;
+ if (max > sizeof(buf))
+ max = sizeof(buf);
+ len = receive_data(eon, buf, max);
if (len < 10) {
ERROR(eon->base.context, "short command reply (%d)", len);
return -1;
@@ -316,7 +319,7 @@ static int read_file(suunto_eonsteel_device_t *eon, const char *filename, dc_buf
put_le32(ask, cmdbuf+4); // Size of read
rc = send_receive(eon, FILE_READ_CMD,
8, cmdbuf,
- sizeof(result), result);
+ ask+8, result);
if (rc < 0) {
ERROR(eon->base.context, "unable to read %s", filename);
return -1;
--
2.4.0.53.g8440f74
_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface