Since isotp.TransportLayer calls rxfn and txfn without additional arguments, you cannot pass hardware handles (like file descriptors or API handles) directly to them. To solve this, use functools.partial to wrap your functions with the required handles before passing them to the TransportLayer constructor.
import isotp
import functools
from typing import Optional
def my_rxfn(hardware_handle, timeout:float) -> Optional[isotp.CanMesage]:
msg = my_hardware_api_recv(hardware_handle, timeout)
if msg is None:
return None
return isotp.CanMesage(arbitration_id=msg.get_id(), data=msg.get_data(), dlc=msg.get_dlc(), extended_id=msg.is_extended_id())
def my_txfn(hardware_handle, isotp_msg:isotp.CanMesage):
msg = my_hardware_api_make_msg()
msg.set_id(isotp_msg.arbitration_id)
msg.set_data(isotp_msg.data)
msg.set_dlc(isotp_msg.dlc)
msg.set_extended_id(isotp_msg.is_extended_id)
my_hardware_api_send(hardware_handle, msg)
hardware_handle = my_hardware_open()
addr = isotp.Address(isotp.AddressingMode.Normal_29bits, txid=0x123456, rxid = 0x123457)
# Wrap functions with the handle
partial_rxfn = functools.partial(my_rxfn, hardware_handle)
partial_txfn = functools.partial(my_txfn, hardware_handle)
layer = isotp.TransportLayer(rxfn=partial_rxfn, txfn=partial_txfn, address=addr)
layer.start()
# ... rest of program
layer.stop()
my_hardware_close()