How to create an ISOTP socket?
Prriyamvradha opened this issue · 1 comments
The message I send from one host(slcan0) using isotpsend
is not received at the other host(slcan1) when I give isotprecv
.But I am able to send and receive a message in the same host either slcan0 or slcan1. Initially, I had the same issue for sending standard 8 bytes CAN message from one host to other then I created a socket using the following program
#!/bin/env python
import socket
import struct
canformat = '<IB3x8s'
class CanBridge():
def __init__(self, interface_from, interface_to):
self.interface_from = interface_from
self.interface_to = interface_to
self.canSocket_to = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
self.canSocket_from = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
try:
self.canSocket_to.bind((self.interface_to,))
self.canSocket_from.bind((self.interface_from,))
except OSError:
print("Could not bind to interfaces")
#put the sockets in blocking mode.
self.canSocket_to.settimeout(None)
self.canSocket_from.settimeout(None)
def run(self):
while True:
raw_bytes = self.canSocket_from.recv(512)
try:
self.canSocket_to.send(raw_bytes)
except OSError: #Buffer overflow usually from lack of connection.
pass
rawID,DLC,candata = struct.unpack(canformat,raw_bytes)
canID = rawID & 0x1FFFFFFF
candata_string = " ".join(["{:02X}".format(b) for b in candata])
print("{:08X} {}".format(canID, candata_string))
if __name__ == '__main__':
bridge = CanBridge('slcan1','slcan0')
bridge.run()
Likewise how to create a socket for ISOTP ?I used the following code to create a socket for ISOTP but it doesnt seem to work
SOL_CAN_ISOTP = 106 # These constants exist in the module header, not in Python.
CAN_ISOTP_RECV_FC = 2
# Many more exists.
import socket
import struct
s = socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_ISOTP)
s2 = socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_ISOTP)
# Configuring the sockets with ugly struct.pack() that requires knowledge of the LKM
˓ → structure
s.setsockopt(SOL_CAN_ISOTP, CAN_ISOTP_RECV_FC, struct.pack("=BBB", 0x10, 3,0)) #bs,
˓ → stmin, wftmax
#s.setsockopt(SOL_CAN_ISOTP, CAN_ISOTP_OPTS, struct.pack(...))
#s.setsockopt(SOL_CAN_ISOTP, CAN_ISOTP_LL_OPTS, struct.pack(...))
s.bind(("slcan0", 0x123, 0x456)) #rxid, txid with confusing order.
s2.bind(("slcan0", 0x456, 0x123)) #rxid, txid
s2.send(b"Hello, this is a long payload sent in small chunks of 8 bytes.")
print(s.recv(4095))
OR
import isotp
s = isotp.socket()
s2 = isotp.socket()
# Configuring the sockets.
s.set_fc_opts(stmin=5, bs=10)
#s.set_general_opts(...)
#s.set_ll_opts(...)
s.bind("slcan0" isotp.Address(rxid=0x123 txid=0x456))
s2.bind("slcan0", isotp.Address(rxid=0x456, txid=0x123))
s2.send(b"Hello, this is a long payload sent in small chunks of 8 bytes.")
print(s.recv())
I'm not a Python specialist, but you may look at this project, which is dealing with iso-tp and python:
https://github.com/pylessard/python-can-isotp
E.g. see source code at
https://github.com/pylessard/python-can-isotp/tree/master/isotp/tpsock