pylessard / python-udsoncan

Python implementation of UDS (ISO-14229) standard.
MIT License
575 stars 199 forks source link

bind() must be called before using the socket #156

Closed Schuchmann closed 1 year ago

Schuchmann commented 1 year ago

Hi, I am trying a very simple example:

#!/usr/bin/env python3
import udsoncan
from udsoncan.connections import IsoTPSocketConnection
from udsoncan.client import Client
from udsoncan.exceptions import *
from udsoncan.services import *
udsoncan.setup_logging()
my_connection = IsoTPSocketConnection('canfd0', rxid=0x12, txid=0x23)
my_connection.send(b'\x11\x01\x77\x88\x99')

but I get the following error:

2023-04-12 17:20:20 [DEBUG] Connection: Sending 5 bytes : [b'1101778899']
Traceback (most recent call last):
  File "./test.py", line 12, in <module>
    my_connection.send(b'\x11\x01\x77\x88\x99')
  File "/home/pi/.local/lib/python3.7/site-packages/udsoncan/connections.py", line 65, in send
    self.specific_send(payload)
  File "/home/pi/.local/lib/python3.7/site-packages/udsoncan/connections.py", line 321, in specific_send
    self.tpsock.send(payload)
  File "/home/pi/.local/lib/python3.7/site-packages/isotp/tpsock/__init__.py", line 83, in send
    raise RuntimeError("bind() must be called before using the socket")
RuntimeError: bind() must be called before using the socket

Can someone help. What am I doing wrong?

pylessard commented 1 year ago

my_connection.open()

you can also do

with IsoTPSocketConnection('canfd0', rxid=0x12, txid=0x23) as conn:
    conn.send(bytes([1,2,3]))
Schuchmann commented 1 year ago

@pylessard Thanks for the answer, but getting nearly the same error with your exampe:

2023-04-12 18:06:19 [DEBUG] Connection: Sending 3 bytes : [b'010203']
Traceback (most recent call last):
  File "./test.py", line 14, in <module>
    conn.send(bytes([1,2,3]))
  File "/home/pi/.local/lib/python3.7/site-packages/udsoncan/connections.py", line 65, in send
    self.specific_send(payload)
  File "/home/pi/.local/lib/python3.7/site-packages/udsoncan/connections.py", line 321, in specific_send
    self.tpsock.send(payload)
  File "/home/pi/.local/lib/python3.7/site-packages/isotp/tpsock/__init__.py", line 83, in send
    raise RuntimeError("bind() must be called before using the socket")
RuntimeError: bind() must be called before using the socket

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./test.py", line 14, in <module>
    conn.send(bytes([1,2,3]))
  File "/home/pi/.local/lib/python3.7/site-packages/udsoncan/connections.py", line 297, in __exit__
    self.close()
  File "/home/pi/.local/lib/python3.7/site-packages/udsoncan/connections.py", line 315, in close
    self.rxthread.join()
AttributeError: 'IsoTPSocketConnection' object has no attribute 'rxthread'
pylessard commented 1 year ago

You are right. The connection can'T be used in a with statement. My bad. Just call open.

Schuchmann commented 1 year ago

Juhuuuu... calling open() works! Maybe something to put into the example: https://udsoncan.readthedocs.io/en/latest/udsoncan/examples.html#raw-connection

One more question: Is it possible to use extended IDs also? If I am trying my_connection = IsoTPSocketConnection(interface='canfd0', rxid=0x1ac9fef8, txid=0x1ac8f8fe) I get

ValueError: txid must be smaller than 0x7FF for 11 bits identifier

How can I switch to 29Bit Identifiers?

pylessard commented 1 year ago

It's possible. There's a small caveat. IsotpSocketConnection is the first conenction I wrote and the codebase has evolved and now I don't want to break previous interfaces.. The actual constructor won't let you do this cleanly.

import isotp
address = isotp.Address(isotp.AddressingMode.Normal_29bits, rxid=0x123456, txid=0x789ABC)
IsoTPSocketConnection(interface='canfd0', rxid=address.rxid, txid=address.txid, address=address)   # Duplication of information here.... bad interface, but will work.

For something cleaner, you can create the socket yourself and use a SocketConnection

form udsoncan.connections import SocketConnection
import isotp
address = isotp.Address(isotp.AddressingMode.Normal_29bits, rxid=0x123456, txid=0x789ABC)
sock = isotp.socket()
sock.bind(address)
conn = SocketConnection(sock)
Schuchmann commented 1 year ago

Thank you very much. Your example works with Ext-IDs!