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

Trouble trying to sync Handspring Treo 90 #13

Open
Lana-chan opened this issue Nov 1, 2022 · 4 comments
Open

Trouble trying to sync Handspring Treo 90 #13

Lana-chan opened this issue Nov 1, 2022 · 4 comments

Comments

@Lana-chan
Copy link

Lana-chan commented Nov 1, 2022

I'm trying to hotsync a Treo 90, which doesn't seem to work with the usbserial/visor kernel modules, so it seems it needs the libusb mode. I can sync a Visor Neo with this method fine, but not the Treo. Using the debug log, I found this:

libusb.c: 132, 0x082d 0x0200.
libusb.c: trying to open device 0x55b392af2d20
libusb.c: USB_handle=0x55b392af4180
usb: PALM_GET_EXT_CONNECTION_INFORMATION, num_ports=16, endpoint_numbers_different=147
    [0] port_function_id='�U'
    [0] port=32
    [0] endpoint_info=80
    [1] port_function_id='�U'
    [1] port=0
    [1] endpoint_info=0
    [2] port_function_id=''
    [2] port=0
    [2] endpoint_info=73
    [3] port_function_id='89��'
    [3] port=176
    [3] endpoint_info=149
    [4] port_function_id='�'
    [4] port=80
    [4] endpoint_info=211
    [5] port_function_id='�'
    [5] port=0
    [5] endpoint_info=0
    [6] port_function_id=''
    [6] port=210
    [6] endpoint_info=149
    [7] port_function_id='�'
    [7] port=209
    [7] endpoint_info=149
    [8] port_function_id='�'
    [8] port=224
    [8] endpoint_info=170
    [9] port_function_id='�U'
    [9] port=128
    [9] endpoint_info=65
    [10] port_function_id='�U'
    [10] port=150
    [10] endpoint_info=40
    [11] port_function_id=''
    [11] port=0
    [11] endpoint_info=150
    [12] port_function_id='�'
    [12] port=0
    [12] endpoint_info=73
    [13] port_function_id='89��'
    [13] port=0
    [13] endpoint_info=150
    [14] port_function_id='�'
    [14] port=16
    [14] endpoint_info=220
    [15] port_function_id='�'
    [15] port=208
    [15] endpoint_info=157
usb: PALM_GET_EXT_CONNECTION_INFORMATION - no hotsync port found.
libusb.c: USB configure failed for familar device: 0x082d 0x0200. (LifeDrive issue?)

On a whim I tried to set the Treo's device configuration with the visor flag and recompiled pilot-link, just in case it would somehow work, but it doesn't:

libusb.c: 132, 0x082d 0x0200.
libusb.c: trying to open device 0x55dc116ebd20
libusb.c: USB_handle=0x55dc116ed180
usb: VISOR_GET_CONNECTION_INFORMATION, num_ports=0
GENERIC_REQUEST_BYTES_AVAILABLE returns 0x0000
Out: 0x3 0xff.
In: 0x84 0xff.
Config: 0, 0xff 0xff | 0x84 0x3.
libusb.c: 225.
libusb.c 453 (u_poll).
libusb.c 499 (u_read_i): 1 1 0
libusb.c 522 (u_read_i): 1 0.
Reading: len: 64, timeout: 0.
libusb.c 281 (RD_do_read): 0
Reading: len: 64, timeout: 0.
libusb.c 281 (RD_do_read): 0
Reading: len: 64, timeout: 0.
libusb.c 281 (RD_do_read): 0
Reading: len: 64, timeout: 0.
[...]

Any ideas?

EDIT: This Treo hotsyncs fine on Windows machines with Palm Desktop, so I know neither the device or the cable should be the issue.

@Lana-chan
Copy link
Author

Lana-chan commented Nov 1, 2022

I managed to capture a complete hotsync transaction with Wireshark on my Windows machine using Palm Desktop 6.2.2. Of note I can see the proper "cnys" id that pilot-link looks for in the following frame:
image
I'm not well versed in USB protocols but I'm going to try moving forward with this. If anyone is interested in the capture (which I've saved truncated up until the point where the device identifies my hotsync username) please contact me.

@Lana-chan
Copy link
Author

Lana-chan commented Nov 1, 2022

I tried adding a new USB init flag for the Treo (which would undoubtedly break other Treo models, but at least for sake of attempted fixes for now) and modifying USB_configure_generic like so (which also involved adding the interrupt_read handler to libusb.c):

    if (flags & USB_INIT_TREO) {
        // weird beast
        unsigned char buf[sizeof(palm_ext_connection_info_t) + 6];
        ret = dev->impl.control_request (dev, 0xc2, VISOR_GET_CONNECTION_INFORMATION, 0, 0, &ci, sizeof (ci), 0);
        LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, "usb: VISOR_GET_CONNECTION_INFORMATION (ret=%08x)\n", ret));
        ret = dev->impl.control_request (dev, 0xc2, PALM_GET_EXT_CONNECTION_INFORMATION, 0, 0, &ci, sizeof (ci), 0);
        LOG((PI_DBG_DEV, PI_DBG_LVL_ERR, "usb: PALM_GET_EXT_CONNECTION_INFORMATION (ret=%08x)\n", ret));
        ret = dev->impl.interrupt_read (dev, 0x82, &buf, sizeof (buf), 0);
        memcpy(&ci, (buf+6), sizeof (ci));
    } else {
        ret = dev->impl.control_request (dev, 0xc2, PALM_GET_EXT_CONNECTION_INFORMATION, 0, 0, &ci, sizeof (ci), 0);
    }

However, despite getting the correct Palm hotsync header and USB endpoints (which match the ones used in the USB bulk transfers on Windows) now, the device still doesn't go any further:

libusb.c: 135, 0x082d 0x0200.
libusb.c: trying to open device 0x563af1a74410
libusb.c: USB_handle=0x563af1a75ee0
usb: VISOR_GET_CONNECTION_INFORMATION (ret=00000000)
usb: PALM_GET_EXT_CONNECTION_INFORMATION (ret=00000000)
usb: PALM_GET_EXT_CONNECTION_INFORMATION, num_ports=1, endpoint_numbers_different=1
    [0] port_function_id='cnys'
    [0] port=0
    [0] endpoint_info=67
GENERIC_REQUEST_BYTES_AVAILABLE returns 0x0000
Out: 0x3 0x3.
In: 0x84 0x4.
Config: 0, 0x4 0x3 | 0x84 0x3.
libusb.c: 228.
libusb.c 456 (u_poll).
libusb.c 502 (u_read_i): 1 1 0
libusb.c 525 (u_read_i): 1 0.
Reading: len: 64, timeout: 0.

EDIT: Looking closer at the USB capture, a simpler way to modify USB_configure_generic follows:

    ret = dev->impl.control_request (dev, 0xc2, PALM_GET_EXT_CONNECTION_INFORMATION, 0, 0, &ci, sizeof (ci), 0);

    if (ret == 0) {
        // empty response from PALM_GET_EXT_CONNECTION_INFORMATION, try interrupt
        unsigned char buf[sizeof(palm_ext_connection_info_t) + 6];
        // 6 first bytes seem to indicate a vendor id, we don't use that yet
        ret = dev->impl.interrupt_read (dev, 0x82, &buf, sizeof (buf), 0);
        memcpy(&ci, (buf+6), sizeof (ci));
    }

This way the need to single out the Treo 90 with a USB init flag is no longer necessary, and my Palm TX still syncs over libusb without change. However the debug log for the Treo above still follows, getting the correct USB endpoints but then getting stuck.

@Lana-chan
Copy link
Author

Lana-chan commented Nov 1, 2022

I'm comparing the bulk transfers past the hotsync endpoint handshake between the Treo 90 and my Palm TX from USB captures with Palm Desktop 6.2.2 and so far I haven't seen any differences that jump out to me. Which makes me think there's still some extraneous part of the device detection that's hanging when trying to read the first couple of bulk packets before sending more data, rather than a difference in the hotsync protocol itself.

For comparison here's a partial dump from the TX syncing with pilot-link (flag -l to list packages):

libusb.c: 135, 0x0830 0x0061.
libusb.c: trying to open device 0x55dc3e65c5b0
libusb.c: USB_handle=0x55dc3e65dfb0
usb: PALM_GET_EXT_CONNECTION_INFORMATION, num_ports=1, endpoint_numbers_different=1
    [0] port_function_id='cnys'
    [0] port=0
    [0] endpoint_info=103
In: 0x81 0x6.
Out: 0x2 0x7.
In: 0x86 0x6.
Out: 0x7 0x7.
Config: 0, 0x6 0x7 | 0x86 0x7.
libusb.c: 228.
libusb.c 456 (u_poll).
libusb.c 502 (u_read_i): 1 1 0
Reading: len: 64, timeout: 0.
libusb.c 525 (u_read_i): 1 0.
libusb.c 284 (RD_do_read): 6
Reading: len: 64, timeout: 0.
libusb.c 546 (u_read_i): 1 6.
libusb.c 553 (u_read_i): 1 6.
libusb.c 580 (u_read_i).
libusb.c 502 (u_read_i): 10 1 0
libusb.c 525 (u_read_i): 10 6.
libusb.c 284 (RD_do_read): 22
Reading: len: 64, timeout: 0.
libusb.c 546 (u_read_i): 10 28.
libusb.c 553 (u_read_i): 10 28.
libusb.c 580 (u_read_i).
Read: 10 (10).
usb.c: 434, prot: 0x6, type: 0x10, cmd: 0x2.
usb.c: 477, net rx.

On my USB captures, both the Treo 90 and the TX exhibit the first two bulk reads with packet lengths 6 and 22 (the Treo immediately after the interrupt read, and the TX immediately after the palm control request), which matches the first two pilot-link reads of the TX's debug. However the Treo simply doesn't send them to pilot-link and it hangs on RD_do_read instead, until it times out with 0 bytes read. Perhaps something is needed to free the device after the interrupt read, but I'm not clear on what yet.

@Lana-chan
Copy link
Author

Perhaps something is needed to free the device after the interrupt read, but I'm not clear on what yet.

Ha, the answer was really quite that obvious. I noted the packet from the interrupt read in my USB capture was 64 bytes long, which meant that in trying to make it similar to the control request and asking only for as many bytes to fill the palm_ext_connection_info struct, the Treo didn't know what to do with the remaining bytes and would wait for a remaining read that never happened. Once I hardcoded the size of the buffer in my patch to 64 bytes instead, the Treo instantly synced with pilot-link.

Now I need to clean up my code so I can submit a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant