UDS SecurityAccess/SessionControl timing out in Python (udsoncan/isotp) when ECU simulation is in CANoe (CAPL)
09:43 08 Sep 2025

I am implementing a UDS flashing tool in Python using udsoncan and python-can-isotp.
The setup is:

  • Python client → sends UDS requests via Kvaser CAN interface.

  • CANoe CAPL script → acts as ECU, responds to diagnostic services.


The issue

Some services (e.g., ECUReset 0x11) work fine:

Python log:

Tx: <7E4> 0211010000000000
Rx: <7EC> 0251010000000000
Received positive response for ECUReset (0x11)

But other services like DiagnosticSessionControl (0x10) or SecurityAccess (0x27) timeout:

Python log:

Tx: <7E4> 0210020000000000
RAW CAN: ID=0x7EC, Data=065002003201f400
TimeoutException – Did not receive IsoTP frame in time

CANoe trace:

ID=7EC  Data=06 50 02 00 32 01 F4 00

So Python clearly sees the CAN frame, but isotp/udsoncan discards it → timeout.


My CAPL code (simplified)

case 0x10: // DiagnosticSessionControl
{
    byte resp[8];
    resp[0] = 0x50;
    resp[1] = data[1];
    resp[2] = 0x00;
    resp[3] = 0x32;
    resp[4] = 0x01;
    resp[5] = 0xF4;
    CanTpSendData(gHandle, resp, 6);
    write(">> Session Control 0x%02X", data[1]);
}
break;

case 0x27: // SecurityAccess
{
    byte resp[8];
    resp[0] = 0x67;
    resp[1] = data[1];
    resp[2] = 0x12;
    resp[3] = 0x34;
    resp[4] = 0x56;
    resp[5] = 0x78;
    CanTpSendData(gHandle, resp, 6);   // send seed
    write(">> Sent seed.");
}
break;

What I expect

For SessionControl (0x10) the response should be:

50 02 00 32 01 F4

(6 bytes total).

For SecurityAccess (0x27, sub 0x01) the response should be:

67 01 12 34 56 78

(6 bytes total).


What actually happens

CANoe sends 8-byte frames with trailing 00 padding, e.g.:

06 50 02 00 32 01 F4 00
06 67 01 12 34 56 78 00

Python isotp expects exactly 6 payload bytes, so it rejects the message → timeout.


My question

  • Why does CanTpSendData(gHandle, resp, 6) still result in an 8-byte CAN frame?

  • How can I make CANoe’s CAPL simulation send exactly the number of UDS bytes I specify (without padding), so udsoncan/isotp accepts it?

  • Is there a better practice for handling padding between Python isotp and CANoe CAPL?


Things I tried

  • CanTpSetPadding(gHandle, 0x00); (still sends 8-byte frames with extra zeros).

  • Initializing the array with zeros (byte resp[8] = {0};) before filling.

  • Different values for len in CanTpSendData.

python python-can uds