pygarmin icon indicating copy to clipboard operation
pygarmin copied to clipboard

Invalid endpoint address 0x2

Open DremOSDeveloperTeam opened this issue 11 months ago • 8 comments

Greetings,

I'm having a bit of trouble getting this project to work. It's throwing up a bunch of errors that I, as someone who doesn't really work with USB... ever, don't really know what to do with.

System information: Arch Linux (x86_64) Using a venv with only the latest version of pygarmin (and it's dependencies) installed.

I did notice that GNU/Linux users should remove and blacklist garmin_gps, but it is not currently loaded for me.

The Garmin device I'm using is the Garmin GLO 2. I'm not sure if this GPS is supported, but I don't see why Garmin would pull a switcharoo with this one in particular.

I'm probably just forgetting something, or making a silly mistake, but I'm not entirely sure where to go from here.

Thanks for your help!

Error log (with --debug):

Version 1.2.0
2024-03-24 04:09:48,599 Version 1.2.0
Start USB session
2024-03-24 04:09:48,599 Start USB session
Send Start Session packet
2024-03-24 04:09:48,599 Send Start Session packet
Pack packet
2024-03-24 04:09:48,599 Pack packet
Data size: 0
2024-03-24 04:09:48,599 Data size: 0
< packet 5: 
2024-03-24 04:09:48,599 < packet 5: 
Traceback (most recent call last):
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/usb/core.py", line 236, in get_interface_and_endpoint
    return self._ep_info[endpoint_address]
           ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
KeyError: 2

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/$USER/Projects/nightui/src/venv/bin/pygarmin", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/pygarmin/pygarmin.py", line 1501, in main
    app = Pygarmin(args.port)
          ^^^^^^^^^^^^^^^^^^^
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/pygarmin/pygarmin.py", line 236, in __init__
    self.gps = self.get_gps(self.port)
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/pygarmin/pygarmin.py", line 240, in get_gps
    phys = mod_link.USBLink() if port == 'usb:' else mod_link.SerialLink(port)
           ^^^^^^^^^^^^^^^^^^
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/pygarmin/link.py", line 322, in __init__
    self.start_session()
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/pygarmin/link.py", line 568, in start_session
    self.send_start_session_packet()
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/pygarmin/link.py", line 536, in send_start_session_packet
    self.write(buffer)
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/pygarmin/link.py", line 481, in write
    self.dev.write(endpoint, buffer, timeout=timeout)
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/usb/core.py", line 986, in write
    intf, ep = self._ctx.setup_request(self, endpoint)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/usb/core.py", line 113, in wrapper
    return f(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/usb/core.py", line 228, in setup_request
    intf, ep = self.get_interface_and_endpoint(device, endpoint_address)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/usb/core.py", line 113, in wrapper
    return f(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/$USER/Projects/nightui/src/venv/lib/python3.11/site-packages/usb/core.py", line 244, in get_interface_and_endpoint
    raise ValueError('Invalid endpoint address ' + hex(endpoint_address))
ValueError: Invalid endpoint address 0x2

Information I was able to gather using usb.core.find() (in case it may come in handy):

DEVICE ID 091e:0003 on Bus 001 Address 021 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x110 USB 1.1
 bDeviceClass           :   0xff Vendor-specific
 bDeviceSubClass        :   0xff
 bDeviceProtocol        :   0xff
 bMaxPacketSize0        :   0x40 (64 bytes)
 idVendor               : 0x091e
 idProduct              : 0x0003
 bcdDevice              :    0x1 Device 0.01
 iManufacturer          :    0x0 
 iProduct               :    0x0 
 iSerialNumber          :    0x0 
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 500 mA ==================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x27 (39 bytes)
   bNumInterfaces       :    0x1
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0x80 Bus Powered
   bMaxPower            :   0xfa (500 mA)
    INTERFACE 0: Vendor Specific ===========================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x3
     bInterfaceClass    :   0xff Vendor Specific
     bInterfaceSubClass :   0xff
     bInterfaceProtocol :   0xff
     iInterface         :    0x0 
      ENDPOINT 0x82: Interrupt IN ==========================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x82 IN
       bmAttributes     :    0x3 Interrupt
       wMaxPacketSize   :   0x10 (16 bytes)
       bInterval        :    0x1
      ENDPOINT 0x1: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x1 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
      ENDPOINT 0x81: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0

DremOSDeveloperTeam avatar Mar 24 '24 09:03 DremOSDeveloperTeam

I also made mistakes at first. Solution: just installed all the libraries used in Pygarmin. It helped me. The test was carried out on the Garmin Strike 4 plus echo sounder and on the GPSMAP 60csx, both devices were connected via a computer, on Windows 10, via a com port.

R1BGW avatar Apr 28 '24 18:04 R1BGW

I also got this exact same error : "Invalid endpoint address 0x2". Tested this on Manjaro (Arch) in virtual environment with Python 3.11 and on Ubuntu 22.04 with system wide package installation and Python 3.10. I also tried the solution from R1BGW to install dependencies seperatelly. But it always said the packages are all installed. No solution found yet. I try to upload gpx-routes to internal storage of my old Garmin GPSMAP 60csx.

JEffnot avatar May 06 '24 12:05 JEffnot

Are you trying to download data via USB? I used a serial port (USB-COM adapter) on my GPS devices . At the same time, in the Garmin library (line 137) where : self.baudrate = baudrate (changed to port speed) that is : self.baudrate = 9600 ( 9600 speed for 60CSx) and (115200 for Striker 4 plus) . I also tried to connect via USB, there were also errors, so I stopped further attempts. get-tracks.txt

get-waypoints.txt

help.txt

info.txt

protocols.txt

pvt.txt

time ,position.txt

Something like this.

Maybe you should try another software. Not everything is clear with this library, at least the output of waypoints (the GPX file is not readable by other programs, it is not saved in XML format) needs to be edited.

It is important that in programs where the serial port is used, the ports must be closed. I have software installed to work with my devices (DNR GARMIN, GPS GARMIN), in the first one the COM port is used and it has to be forcibly controlled (Port Close). This is from personal experience.

R1BGW avatar May 06 '24 17:05 R1BGW

Apologies in advance as this doesn't pertain directly to the issue.

@R1BGW

I've seen that you have managed to connect your Striker Plus 4 via a usb to serial connection. I am currently attempting to connect a Striker 4 (non-plus) version. I have made the connection using a usb to serial adapter and hooking up with tx/rx/gnd wires to the back of the Striker. Researching this device has led me to discover that the signal uses inversion and sends a packet burst every 10 seconds. Using a serial monitor, I can see the packet burst every 10 seconds but noting useful in the way of data.

I have successfully been able to communicate with an older etrex venture using this same serial method.

Just wondering if you would be able to provide some more info on how you made the connections to your Striker Plus 4. I assume that it is an updated version of the Striker 4.

nremenda avatar May 08 '24 01:05 nremenda

For data input/output from Striker 4+ (+ this is a modification of a previously released device, another firmware version) . I initially used GARMIN's DNR program with a serial port and an RS-232 interface. During the use of the program, errors were identified: 1. Conversion to GPX (although the output file is saved in the XML protocol (you can view and edit it in a text editor), but the file is not readable in other programs, an error occurs), so you have to edit it in a text editor. 2. When uploading points to Striker, through the GARMIN DNR program, the coordinates of the points are recorded only integer values (perhaps I did not fully understand the program .There is a link to the forum. https://www.rusfishing.ru/forum/threads/po-dlja-garmin-strajk-4-pljus.508439 The default transfer rate is 9600 If you use the Pygarmin library: You need to go to the folder (site-package) on the way(at my place) C:\Users\vers\AppData\Local\Programs\Python\Python312\Lib\site-packages\garmin , select the garmin folder and in the garmin code on line 137 (self.baudrate = baudrate) change to (self.baudrate= 115200) , this is the data transfer rate to the serial port (COM-port). Be sure to save the changes .Next, go to the device manager, find our adapter (USB-COM) and remember the port number. Further, as it is written in the instructions for the library : pygarmin -h (displays all additional library functions). help.txt pygarmin -p comx info (where x is our port number)Will output a message: info.txt Further, as in the description of the library or in the help (-h) Something like that. The output of the GPX file when using the library is most likely a table that needs to be converted further into the required format (gpx). I'm currently studying and trying to write code in Python for GPS devices , it won't be soon .

R1BGW avatar May 08 '24 05:05 R1BGW

ok, I got rid of the Invalid Endpoint Address 0x2. As you can see also in DremOSDeveloperTeam post, the USB Device Endpoints dont match. This is also for my Device. I changed in pygarmin link.py in line 311 the endpoint addresses to the endpoint addresses my device uses.

#Bulk_OUT = 2        # 0x02
#Interrupt_IN = 129  # 0x81
#Bulk_IN = 131       # 0x83  # unused
Bulk_OUT = 3        # 0x03
Interrupt_IN = 130  # 0x82
Bulk_IN = 129       # 0x81  # unused

Also i changed in pygarmin.py in line 240 to only use the usblink()

    #phys = mod_link.USBLink() if port == 'usb:' else mod_link.SerialLink(port)
    phys = mod_link.USBLink()

But now I got a new error: pygarmin.error.LinkError: 'Resource busy'

It seems something is blocking my gps device. I tried: lsof | grep '/dev/bus/usb/003/019' to show which process is using my usb device... but there is no other process...

JEffnot avatar May 08 '24 12:05 JEffnot

I will look into the USB errors, but I only have a Garmin Etrex Legend C and a Garmin Forerunner 305 to test with and they work fine with the hardcoded USB endpoints addresses.

@DremOSDeveloperTeam: I'm not sure the Garmin GLO 2 will work with the old Garmin protocol. The device isn't mentioned in the Garmin Device Interface SDK nor in GPSBabel's documentation of the protocol.

@R1BGW: if you experience problems with the gpx import or export, please create an issue and I will look into that as well.

fvdbeek avatar Jun 05 '24 23:06 fvdbeek

The endpoints are now dynamically determined instead of hard coded. This should fix the error "Invalid endpoint address 0x2". Please let me know if this resolves the issue.

Pygarmin still always uses the Bulk OUT pipe for communication from the host to the device and the Interrupt IN pipe from the device to the host. However, the Garmin Device Interface SDK mentions that the device can choose to transmit to the host over either the Interrupt IN pipe or the Bulk IN pipe. This isn't implemented yet.

fvdbeek avatar Jun 08 '24 21:06 fvdbeek