Skip to content
This repository was archived by the owner on May 7, 2021. It is now read-only.
This repository was archived by the owner on May 7, 2021. It is now read-only.

Using ISO-TP Dispatcher functionality #42

@mattie47

Description

@mattie47

Hi,

I was hoping someone here might be able to help with an example of how to use the dispatcher in a loop and if a condition is met, send a relevant response.

Currently I've just been interacting with Pyvit in a simple while loop with dev.recv. However I'm not sure how to interact with the dispatcher given things are threaded.

Basically, I have a simple program using Pyvit acting as an ECU to send things such as RPM and Speed when requested by a connected device.

As an example:

#!/usr/bin/env python3

from pyvit import can
from pyvit.hw import socketcan

import os,sys,termios,tty,time

SupportedPIDsRequest = "0201000000000000"

RPMRequest = "02010C0000000000"
VINReq = "0209020000000000"

RPMResp = 'cansend vcan0 7E8#04410C1094000000'
VINResp = 'cansend vcan0 7E8#1014490201355445 && sleep 0.1 && ' \
          'cansend vcan0 7E8#214D5535324E3636 &&' \
          'cansend vcan0 7E8#225A323236373433'

def resp_function():
    resp = can.Frame(0x7E8)
    resp.data = frameData
    dev.send(resp)
    print(resp)
    return resp

dev = socketcan.SocketCanDev("vcan0")
dev.start()

while True:
    CanFrameRecv = dev.recv()

    if CanFrameRecv.arb_id == int(0x7DF):
        if (bytes(CanFrameRecv.data)) == bytes.fromhex(SupportedPIDsRequest):
            print('\nSupported PIDs Request  : ' + SupportedPIDsRequest)

            frameData = [0x06, 0x41, 0x00, 0x00, 0x18, 0x30, 0x01]
            response = resp_function()
            print('Supported PIDs Response : ' + str(resp_function().data))

        elif (bytes(CanFrameRecv.data)) == bytes.fromhex(RPMRequest):
            print('\nRPM Request Received    : ' + RPMRequest)
            print('RPM Response            : ' + RPMResp)
            os.system(RPMResp)    
        elif (bytes(CanFrameRecv.data)) == bytes.fromhex(VINReq):
            print('VIN Req          : ' + VINReq)
            print(VINResp)
            os.system(VINResp)

As you can see, I'm "cheating" with the VIN, and just sending the frames out without actually checking if a frame control message is received. I want to improve this, and actually use the ISO-TP functionality.

My issue is I've struggled to get ISO-TP messages working nicely.

Using the isotp_test I was able to get an idea on how to send an ISO-TP frame, provided you send a frame control message.

#!/usr/bin/env python3

import threading
from multiprocessing import Queue

from pyvit.hw import socketcan
from pyvit.dispatch import Dispatcher
from pyvit.proto.isotp import IsotpInterface

dev = socketcan.SocketCanDev("vcan0")
disp = Dispatcher(dev)
recv_queue = Queue()
disp.add_receiver(recv_queue)

# set up an isotp interface Sender/Receiver arb id
sender = IsotpInterface(disp, 0x7DF, 0x7E8)
receiver = IsotpInterface(disp, 0x7E8, 0x7DF)
disp.start()

""" ISOTP transmission and reception of a multi-frame message"""
print("payload creation")
payload = [0x49, 0x02, 0x01, 0x31, 0x41, 0x31, 0x4A, 0x43, 0x35, 0x34, 0x34, 0x34, 0x52, 0x37, 0x32, 0x35, 0x32, 0x33, 0x36, 0x37]

# we need to run this in a thread so that the flow control frame is
# sent and received, as IsotpInterfaces block
print("starting tx_thread")
tx_thread = threading.Thread(target=sender.send, args=(payload,))
tx_thread.start()

# we'll receive data in this thread
resp = receiver.recv()

# wait for the transmitting thread to finish, then verify the result
tx_thread.join()

## I'm really not too sure what the above " .join"actually does....

print("finished")

Example:

pi@rpi-hos:~/repos/pyvit $ python3 print_all_frames.py
payload creation
starting tx_thread
[16, 20, 73, 2, 1, 49, 65, 49] <SEND CONTROL FRAME>
[33, 74, 67, 53, 52, 52, 52, 82]
[34, 55, 50, 53, 50, 51, 54, 55]
finished

I'm just not sure how to interact with the Dispatcher send and receive methods/threads within a while loop.

I'm starting to get the impression my main loop should also be a thread but again not sure how to do this.

Sorry if this is an annoying question - I'm still pretty new to python.

Thanks,

Matt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions