hplp icon indicating copy to clipboard operation
hplp copied to clipboard

Implement new Prime protocol for sending files

Open danielmewes opened this issue 7 years ago • 3 comments

After upgrading my Prime to firmware version 2016 08 29 (10637), I noticed that sending large files from my PC onto the Prime did no longer work. The transfer always got stuck once the packet sequence number overflowed from 0xFE back to 0x00.

So I did some USB sniffing and reverse engineering on a Windows PC with the official connectivity kit. To my surprise, none of the packages, except for the very first roundtrip (where the connectivity kit retrieves version info from the Prime), looked like the packages we knew about. For starters, the package sequence numbers for commands all started with 0x01 rather than 0x00. But the packet header was also different, and significantly longer. Finally I noticed that the connectivity kit compresses large files during the transfer. I haven't investigated which compression algorithm it's using. But basically it sets a different file type for the file transfer, and then transmits some kind of binary data that's smaller than the original file. Luckily this doesn't seem to be required for transmitting large files.

It took me quite a while to figure the new protocol out, but I finally got it working.

This patch implements the new protocol and uses it for file transfers from PC to the Prime. All other commands still use the old protocol. The new protocol must be enabled by sending a special packet to the prime. It must then be disabled again, or subsequent commands might not work. With this patch, this happens automatically within the send_file function.

I don't know if this was the precise version at which the old protocol broke, since I skipped a couple releases in the middle. I also don't know which version introduced the new protocol.

This patch does not implement backwards-compatibility for older Prime firmware versions. I think it's reasonable that users just check out an older revision if they don't want to upgrade?

danielmewes avatar Dec 22 '16 08:12 danielmewes

Woohoo, someone still cares about this code base :) It's been a while since HP added the new protocol with compression support, but I never got around to implementing it. I'm already not spending enough time on the libti* cousins / sources of inspiration, which have more real-world users, so libhpcalcs only comes after that...

High-level thoughts, without looking at the code in detail: I think that the choice of attempting to support older calculator firmware versions should be guided by what HP's CK does. If the latest CK (11xxx series) can still communicate with early calculator firmware versions (say, 5447 or 6030), which you'd have to test, then the case for at least trying to keep backwards compatibility is fairly strong (because then, there must be a way to detect firmware revision, or equivalently communication capability level, by sending commands and parsing the result)... assuming you're willing and able (I mean, in terms of free time - I know you have the technical skills) to do such work, that is. So first of all, what does HP's CK do ? FWIW, on the TI side:

  • the libti* cousins try to support multiple levels of OS communication capability in a single code base. For instance, the Nspire communication code does that;
  • arguably, TI's official communication software attempts to support multiple communication capability levels, too.

Also, note that from firmware version 10637 onwards, a new firmware upgrade protocol was added, so libhpcalcs should eventually be able to upgrade calculators which have such communication capability.

I will try to have a look at the code ASAP. Thanks for the detailed comments on your changes :)

debrouxl avatar Dec 22 '16 16:12 debrouxl

I believe the CK sends a get_info command using the old protocol to the Prime at the beginning of the session. The response presumably contains the firmware version of the calculator. I can look into that later, though I won't get to it before next year.

danielmewes avatar Dec 22 '16 21:12 danielmewes

Good. Presumably, pieces of information extracted from "get infos", such as the firmware revision, should be stored in _calc_handle. I suggest a new struct priv, like I did in https://github.com/debrouxl/tilibs/blob/master/libticalcs/trunk/src/ticalcs.h . Then, based on such information, multiple code paths can be created.

debrouxl avatar Dec 26 '16 11:12 debrouxl