<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi everybody,</p>
    <p>There seems to be some general problems with Suunto dive computer
      synchronisation.</p>
    <p>We got reports so far from the following Suunto computers which
      use some different libdivecomputer-classes (according to
<a class="moz-txt-link-freetext" href="https://github.com/Subsurface-divelog/subsurface/blob/master/descriptor3.tsv">https://github.com/Subsurface-divelog/subsurface/blob/master/descriptor3.tsv</a><tt>):</tt></p>
    <p>- Suunto Zoop (uses SUUNTO_VYPER): Does not work. After
      Timeout-Fix: First read returns size=0<br>
      - Suunto D4 (uses SUUNTO_D9): App (or Download?) Crashes after
      about 4 downloaded drives. There should be a mail with logs in the
      support mail address.<br>
      - Suunto D4i (uses SUUNTO_D9): Report of working download<br>
      - Suunto Vyper Air (uses SUUNTO_VYPER2): Gets stuck on
      "Connecting", might be because of unofficial cable.</p>
    <p>The "sleep and purge to surpress possible echo" thing seems to be
      exclusive to the suunto_vyper computers.</p>
    <p>What I find interesting is that the D4 and D4i (which are using
      the same driver suunto_d9) have different results. <br>
    </p>
    <p>For better debugging I think Jef is right that it would be really
      nice to have timestamps in the libdc-logs. I attached a possible
      patch (porting of logfunc from libdivecomputer to
      libdivecomputer.c), but I'm currently away from my main computer.
      Maybe somebody could give it a try if it compiles and produces
      timestamps? With this we can check if the read-function still
      returns too early for whatever reason.</p>
    <p>Best regards<br>
      Christof<br>
    </p>
    <p><br>
    </p>
    <div class="moz-cite-prefix">Am 09.03.20 um 11:19 schrieb Stephen
      Goodall:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAL0txNo_USbwu6ALmGgza8BQaEj7OqR9qiU8VnYX=RJn-sYEaA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="auto">Hi christof,
        <div dir="auto">I'm still getting "failed to receive answer" for
          the Suunto, Cressi is still working so the timeout change is
          good for that one and hasn't broken it or anything. Is the
          version below the correct one?</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">Suunto:</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">
          <div dir="auto">Subsurface: v4.9.3-1050-g38ca3f684202, built
            with libdivecomputer v0.7.0-devel-Subsurface-NG
            (0714e327b70bb08f5289c9781c09dc10884881c9)</div>
          <div dir="auto">INFO: Open: transport=1</div>
          <div dir="auto">INFO: Configure: baudrate=2400, databits=8,
            parity=1, stopbits=0, flowcontrol=0</div>
          <div dir="auto">INFO: Timeout: value=1000</div>
          <div dir="auto">INFO: DTR: value=1</div>
          <div dir="auto">INFO: Sleep: value=100</div>
          <div dir="auto">INFO: Purge: direction=3</div>
          <div dir="auto">INFO: Sleep: value=500</div>
          <div dir="auto">INFO: RTS: value=1</div>
          <div dir="auto">INFO: Write: size=5, data=0500161407</div>
          <div dir="auto">INFO: Sleep: value=200</div>
          <div dir="auto">INFO: Purge: direction=1</div>
          <div dir="auto">INFO: RTS: value=0</div>
          <div dir="auto">INFO: Read: size=0, data=</div>
          <div dir="auto">ERROR: Failed to receive the answer. [in
            /__w/subsurface/subsurface/libdivecomputer/src/suunto_vyper.c:212
            (suunto_vyper_transfer)]</div>
          <div dir="auto"><br>
          </div>
        </div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">Is there any way to get more verbose
          libdivecomputer logs or something?</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">Cheers</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto"><br>
        </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Mon, 9 Mar 2020, 2:26 am
          Christof Arnosti, <<a href="mailto:charno@charno.ch"
            target="_blank" rel="noreferrer" moz-do-not-send="true">charno@charno.ch</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0 0 0
          .8ex;border-left:1px #ccc solid;padding-left:1ex">
          <div>
            <p>Hi Stephen,</p>
            <p>The build with the improved timeout handling is finished,
              the result is at
              <a
href="https://github.com/Subsurface-divelog/subsurface/suites/506855270/artifacts/2655791"
                rel="noreferrer noreferrer" target="_blank"
                moz-do-not-send="true">https://github.com/Subsurface-divelog/subsurface/suites/506855270/artifacts/2655791</a>
              . Can you test again with your computers?</p>
            <p>Thanks<br>
              Christof<br>
            </p>
            <div>On 08.03.20 15:38, Christof Arnosti wrote:<br>
            </div>
            <blockquote type="cite">
              <p>So I just opened a pull request (<a
                  href="https://github.com/Subsurface-divelog/subsurface/pull/2656"
                  rel="noreferrer noreferrer" target="_blank"
                  moz-do-not-send="true">https://github.com/Subsurface-divelog/subsurface/pull/2656</a>).
                With this the CI will build the updated version and we
                can test again with our computers. The Mares Puck Pro
                still works as expected.</p>
              <p>Best regards<br>
                Christof<br>
              </p>
              <div>On 08.03.20 14:39, Christof Arnosti wrote:<br>
              </div>
              <blockquote type="cite">
                <p>Hi Jef,</p>
                <p>Thanks for your comments.<br>
                </p>
                <div>On 08.03.20 09:27, Jef Driesen wrote:<br>
                </div>
                <blockquote type="cite">On 8/03/2020 06:31, Dirk Hohndel
                  wrote: <br>
                  <blockquote type="cite">
                    <blockquote type="cite">On Mar 7, 2020, at 9:17 PM,
                      Stephen Goodall <<a
                        href="mailto:stephen.goodall88@googlemail.com"
                        rel="noreferrer noreferrer" target="_blank"
                        moz-do-not-send="true">stephen.goodall88@googlemail.com</a>
                      <a href="mailto:stephen.goodall88@googlemail.com"
                        rel="noreferrer noreferrer" target="_blank"
                        moz-do-not-send="true"><mailto:stephen.goodall88@googlemail.com></a>>
                      wrote: <br>
                      Subsurface: v4.9.3-1049-g4529add7053f, built with
                      libdivecomputer v0.7.0-devel-Subsurface-NG
                      (0714e327b70bb08f5289c9781c09dc10884881c9) <br>
                      INFO: Open: transport=1 <br>
                      INFO: Configure: baudrate=2400, databits=8,
                      parity=1, stopbits=0, flowcontrol=0 <br>
                      INFO: Timeout: value=1000 <br>
                      INFO: DTR: value=1 <br>
                      INFO: Sleep: value=100 <br>
                      INFO: Purge: direction=3 <br>
                      INFO: Sleep: value=500 <br>
                      INFO: RTS: value=1 <br>
                      INFO: Write: size=5, data=0500161407 <br>
                      INFO: Sleep: value=200 <br>
                      INFO: Purge: direction=1 <br>
                      INFO: RTS: value=0 <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=0, data= <br>
                      INFO: Read: size=1, data=05 <br>
                      INFO: Read: size=4, data=00161400 <br>
                      INFO: Read: size=3, data=01A01C <br>
                      INFO: Read: size=4, data=00000000 <br>
                      INFO: Read: size=3, data=46B60D <br>
                      INFO: Read: size=4, data=0D004316 <br>
                      INFO: Read: size=3, data=0A1F0A <br>
                      INFO: Read: size=3, data=083B33 <br>
                      Event: model=22 (0x00000016), firmware=10
                      (0x0000000a), serial=31100859 (0x01da8fbb) <br>
                      INFO: Sleep: value=500 <br>
                      INFO: RTS: value=1 <br>
                      INFO: Write: size=3, data=08A5AD <br>
                      INFO: Sleep: value=200 <br>
                      INFO: Purge: direction=1 <br>
                      INFO: RTS: value=0 <br>
                      INFO: Read: size=0, data= <br>
                      ERROR: Unexpected answer start byte(s). [in
                      /__w/subsurface/subsurface/libdivecomputer/src/suunto_vyper.c:354
                      (suunto_vyper_read_dive)] <br>
                    </blockquote>
                    <br>
                    I'm adding Jef to this thread - he's the brains
                    behind libdivecomputer and might look at that log
                    and go "oh, this is what you are doing wrong"... :-)
                    <br>
                  </blockquote>
                  <br>
                  If I look at the above log, then there is indeed
                  something suspicious. For the first packet, there are
                  several read attempts returning no data. I'm not sure
                  what is going on here, but normally libdivecomputer
                  should only do a single request. Is this something
                  subsurface specific? In the second request, there is
                  also an empty read returned, and then it fails
                  immediately, exactly as I would expect. <br>
                  <br>
                  I'm not sure if you are aware of this, but for the
                  non-packet based transports (which includes serial
                  communication), libdivecomputer expects that the read
                  function returns DC_STATUS_TIMEOUT for a partial read
                  (e.g. the actual number of bytes is less than the
                  requested number of bytes). Looking at the code path
                  that was taking based on the error message, I think
                  the read function returned DC_STATUS_SUCCESS with 0
                  bytes in the actual output parameter. <br>
                </blockquote>
                <p>Yes, you are right. Currently it's always returning
                  DC_STATUS_SUCCESS when the underlying implementation
                  does not return an error.</p>
                <p>The usb-serial-for-android timeout implementation (or
                  rather: the Android USB stack timeout implementation)
                  is buggy, so I always read with a timeout of 0
                  (infinite). This "works" on my CP210x cable (it's
                  blocking until data is there), but the FTDI driver
                  seems to behave differently and return the bytes in
                  the chips buffer imediately (even if less than
                  requested) instead of waiting.</p>
                <p>I will rework the gluecode with a while (starttime +
                  timeout  < now() && readBuffer.size() <
                  numBytesToRead)-Loop so that this case should be
                  catched as well. Also I will return DC_STATUS_TIMEOUT
                  when there's less bytes to return than requested (but
                  still return the bytes, correct?)<br>
                </p>
              </blockquote>
              I even managed to put in the time comparison the correct
              way around ;-)<br>
              <blockquote type="cite">
                <p> </p>
                <blockquote type="cite"> <br>
                  Is the timeout respected? Did we return sooner. I
                  can't tell based on the info in the log because there
                  are no timestamps. <br>
                  <br>
                  Another thing that could cause issues for the older
                  Suunto's is the fact that the protocol is sensitive to
                  timings. That's because there are several variants of
                  the interface available. Some of those interfaces do
                  echo the command back, and some don't. To handle both
                  variants, the suunto_vyper_send() function waits 200ms
                  (which is long enough for the echo to appear), then
                  purges the input buffer to discard the echo if there
                  is one, and then reads the actual response. So if the
                  Android custom I/O implementation behaves a bit
                  different timing wise, then this could cause problems.
                  <br>
                </blockquote>
                I guess this should work. At least the purge-call is
                implemented (and clears the readBuffer in application
                layer as well as calls the purge functionality of the
                driver), and the sleep-functionality is also
                implemented.<br>
                <blockquote type="cite"> <br>
                  For debugging timing related issues, it would be good
                  to have a timestamp included in the libdivecomputer
                  log, like dctool does. @Dirk: Can we add this to the
                  subsurface log function? (I can implement this and
                  send you a patch, but I won't have time for it today.)
                  <br>
                  <br>
                  The RTS line is also required for the Suunto protocol.
                  Is this implemented correctly? <br>
                </blockquote>
                It is implemented. Correctly? I don't know, but I guess
                so since two of the working computer (Mares Puck Pro /
                Cressi Leonardo) set the RTS line to the fixed values of
                0 or 1 respectively.<br>
                <blockquote type="cite"> <br>
                  Jef <br>
                </blockquote>
                Best regards<br>
                Christof<br>
              </blockquote>
            </blockquote>
          </div>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>