This project aims to provide a UDS mocking system based on a Raspberry Pi (+ CAN shield) driven by Lua scrips.
Tool / Library | Version |
---|---|
Lua | >= 5.2 |
C++ compiler | >= ISO C++14 |
can-isotp | >= git 2017/04/22 |
can-utils (optional) | >= git 2015/09/02 |
CppUnit (optional) | >= 1.10 |
Doxygen (optional) | >= 1.8 |
graphviz (optional) | >= 2.38 |
For instructions to set up all necessary installations, read the HACKME.
To simulate a ECU (Electronic Control Unit), the Lua file hold various tables describing the data and behavior. Therefore a single ECU has to provide at least a RequesId
and a ResponseId
to be able to communicate via the CAN ISO-TP protocol. Note: A single Lua file could contain various ECUs.
PCM = { -- ECU name
RequestId = 0x100,
ResponseId = 0x200,
BroadcastId = 0x300, -- Optional, 0x7DF on default
}
To provide a set of response data, there are two possibilities. The first option is to do this via a ReadDataByIdentifier
-table, which holds a set of receiving requests and the corresponding answers. The response answer could be a string or a numerical type. The second option is to provide a Raw
-table which does basically the same, with the slightly difference, that the entire data is provided as a literal hexadecimal string. This makes it possible to harness data sets from previous scans or logs. However, white-spaces in-between the string bytes are ignored to allow a easier way to separate the data sections.
PCM = {
RequestId = 0x100,
ResponseId = 0x200,
ReadDataByIdentifier = {
["F1 90"] = "SALGA2EV9HA298784",
["F1 24"] = "HPLA-12345-AB",
["1E 23"] = "231132",
},
Raw = {
["10 02"] = "50 02 00 19 01 F4",
["22 FA BC"] = "10 33 11",
}
}
Since it could be a little inconvenient to provide the entire data set in a static, Look-Up-Table styled way, there are also functions to allow a more advanced behavior.
The following functions are available:
ascii(string)
– Converts a UTF-8 string into a lexical hexadecimal byte stringtoByteResponse(number, number)
– Converts a int number into a hexadecimal byte stringgetCurrentSession()
– Returns the current sessionswitchToSession(number)
– Sets ECU in the given sessionsleep(number)
– Sleeps the amount in milliseconds before proceeding any furthersendRaw(string)
– Sends the given raw-string immediately
All these functions could be used in self defined functions to build a more advanced behavior structure.
Example:
...
Raw = {
["22 F1 91"] = "62 F1 91" .. ascii("SALGA2EV9HA298784"),
["19 02 B1"] = function (request)
myNumber = 21550
return "59 02 FF E3" .. toByteResponse(myNumber, 3) -- "59 02 FF E3 00 54 2E"
end,
["19 02 B2"] = function (request)
session = getCurrentSession()
return "47 11" .. toByteResponse(session, 1) -- "47 11 01"
end,
["19 02 B3"] = function (request)
switchToSession(3) -- extended session
session = getCurrentSession()
return "47 11" .. toByteResponse(session, 1) -- "47 11 03"
end,
["19 02 AF"] = function (request)
sendRaw("7F 19 78") -- send this data section
sleep(5000) -- wait 5 seconds
return "59 02 FF E3 00 54 2F" -- send the rest
end
},
...