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/isotpaccepts it?Is there a better practice for handling padding between Python
isotpand 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
leninCanTpSendData.