Automated Analysis of SOME/IP Communication
Overview
The SOME/IP middleware solution has been present for years in automotive applications. It enables vehicle manufacturers to build service-oriented architectures and provides features like serialization, remote procedure calls, service discovery, publish/subscribe, and UDP message segmentation.
Today's modern vehicles usually contain over a hundred electronic controller units. Much communication happens over SOME/IP, like dashboard notifications, infotainment updates, and delivering information related to ADAS functions.
As vehicles become more intelligent, these functions grow, resulting in higher complexity. Increasing complexity also makes the following more difficult:
Validating network build-up
Validating contracts and delays
Statistical analysis
Functional analysis
Approach
To automate the analysis process, we need to consider the following steps:
- Collecting metadata and definitions about the vehicles
- Collecting trace files
- Parsing trace files
- Analyze SOME/IP messages
- Visualize Results
IP Camp provides tooling or solutions for all these steps above.
Collecting Metadata
Metadata defines the following information related to a vehicle and an analysis process:
- ECUs in the vehicle communicating with each other
- Routing information and gateways
- Message payloads, the structure of data
- Information to dissect binary data saved to a trace file
OEMs usually have their data model described in an AUTOSAR model. The ARXML files are usually large, and the format is quite complex. Therefore, tooling is needed to process the ARXML files and extract the necessary data. IP Camp develops RED to understand such ARXML files. RED can extract all data needed to dissect the signals and any other required metadata for higher-level analysis, like routing information. These extracts are inputs of the analysis process.
Collecting Trace Files
IP Camp or IP Camp products do not necessarily do this step. RED and Mercury assume there is accessible storage where they can read the trace files. Mercury can read various trace files formats, like BLF, TTL, PCAP, and ASC, generated by various logger devices or tools like CANoe, Wireshark, and CANalyzer. The modular design of the tool makes it easy to add support for other formats, and real-time signal processing over the air is also possible (for example, over MQTT). Mercury needs to know which trace file belongs to which vehicle platform.
Parsing and Analyzing Trace Files
Mercury can parse and dissect trace files and execute analysis in multiple ways:
- Loads all the dissected data into a (time-series) database for visualization purposes
- Filter data based on protocol, trigger conditions, data type, or signal value, and load it into a database or output the results to a use-case-specific format
- Execute test scripts on the trace file to evaluate conditions like trace file recognition, categorization, regression testing, or validating logger configuration.
Mercury can process multiple trace files in parallel.
Automated Analysis
Mercury allows the execution of Mercury Scripts written in Groovy. Mercury can execute these scripts on multiple trace files in parallel and provide an output simultaneously. The scripts accept input data generated from AUTOSAR models, enabling the users to detect issues early and regressively automatically. Such cases can be like:
- Problems with service initialization, offers, subscription
- Problems with routing
- Missing data, signals
SOME/IP Topology
We use the AUTOSAR model of the vehicle platform to build up a network topology that contains all participants in the communication. We group configurations based on function or ECU. The following sample demonstrates an extract from the AUTOSAR model generated by RED. The following snippet contains the definition of an ECU offering a service and subscribing to one.
{
"name": "EnvironmnetalRecongnitionFunction",
"ecu": "ENV_2",
"offers": [
{
"service": {
"name": "ActiveEnvMonitoring",
"id": "00001"
},
"vlan": {
"name": "VLAN_VISUAL",
"id": "1"
},
"ip": "F493:06E4:D6FF:C891:BCA6:70DA:89E5:2C04",
"port": "33355",
"protocol": "UdpTp"
}
],
"subscribes": [
{
"service": {
"name": "MasterTime",
"id": "3"
},
"vlan": {
"name": "VLAN_Main",
"id": "2"
},
"ip": "F493:06E4:D6FF:C891:BCA6:70DA:89E5:2C05",
"port": "44321",
"protocol": "UdpTp",
"eventGroups": [
{
"name": "clockTicks",
"id": "167"
}
]
}
]
}
Mercury provides a SOME/IP Foundation Framework, a collection of Groovy scripts implemented on top of the core Mercury API. The Foundation Framework is open source.
The framework implements a state machine that collects all service discovery messages and SOME/IP messages. Based on this information, it generates statistics and provides events for custom application logic. Such events are:
- Handshake: when an offer -> subscribe -> ack cycle completes successfully, per service
- Connection reset: reset flag evaluation
- Missing service discovery
- Missing connection: if a subscription specified by AUTOSAR does not happen
- Custom timing events: a subscription arrives too late, or the first message on a channel arrives too late
Statistical Analysis
The SOME/IP Foundation Framework provides a statistics module to aggregate the results. Using that, we can generate a report about the SOME/IP communication happening in a trace file with the following records:
- Server ECU (address, port, VLAN)
- Client ECU (address, port, VLAN) - multicast is also recognized
- Number of offers, subscribes, acks
- Times between consecutive offers, subscribe, acks, average, minimum, and maximum delays.
- The delay between offer, subscribe, or ack and the first data received on the channel
- Number of REQUEST/RESPONSE data or NOTIFICATION data sent
- Thresholds can be defined to check for timeouts or functional constraints
Routing
Some tests validate how a CAN message travels from a classic ECU to a gateway that translates it to a SOME/IP message and reaches a target ECU running some adaptive service. RED can collect the routing and gateway information from the AUTOSAR model and produce a configuration file for the SOME/IP Foundation Framework.
An example configuration looks like the following:
{"gateways" : [ {
"name" : "Gateway1",
"ecu" : "ECU1",
"frameMappings" : [ {
"source" : "/mappedElements/Frame1",
"target" : "/mappedElements/Frame2" }, { "source" : "/mappedElements/Frame1",
"target" : "/mappedElements/Frame3"
} ],
"pduMappings" : [ {
"source" : "/mappedElements/Pdu1", "target" : "/mappedElements/Pdu2"
} ],
"signalMappings" : [ {
"sources" : [ "/mappedElements/Signal1" ],
"targets" : [ "/mappedElements/Signal2" ]
}, {
"sources" : [ "/mappedElements/Signal1" ],
"targets" : [ "/mappedElements/Signal2" ]
} ] }, {
"name" : "Gateway2", "ecu" : "ECU2",
"frameMappings" : [ ], "pduMappings" : [ {
"source" : "/mappedElements/Pdu2",
"target" : "/mappedElements/Pdu3"
} ],
"signalMappings" : [ ] } ] }
Using this configuration, tests can validate whether all the packets reach the necessary target ECU within a configured time limit. Data comparison is based on CRC and index value; if identical packets are sent cyclically with identical CRC and index, a running time window can match the packets. Otherwise, consecutive identical packages are not distinguishable.
Visualization
Mercury can write the results into a time series database and visualize the results on a chart, and provides customizable dashboards out of the box to visualize SOME/IP-related data points.
Using Test Cases to Validate SOME/IP Communication
Mercury offers the possibility to execute Test Cases. Each test case is a Groovy script built on the open-source Groovy Framework. Test Cases consume a stream of frames as input, or with the help of the SOME/IP Foundation Framework, they can consume SOME/IP events that contain additional information, for example, if a Notification data message was successfully subscribed to or if a service was offered before a subscription request.
The SOME/IP Foundation Framework provides an ever-growing number of tests that can validate the proper build-up of a SOME/IP network. These tests can be part of a regression test framework to ensure that consecutive software updates to the ECU components go in the right direction. Usually, test cases are related to functional requirements, and they check if the vehicle produces the proper flow of events and signals that occur in the appropriate order with the correct values.
The following code snippet shows the basic event handling of the Foundation Framework regarding service discovery messages.
class SampleSOMEIPTest extends AbstractSDSomeIpTest {
@Override
boolean isRelevant(MetaFrame metaFrame) {
if (metaFrame.someipHeader().messageId() != (int) 0xFFFF8100) {
return false
}
for (sd in metaFrame.someipSd()) {
for (entry in sd.entries()) {
return entry.type.value() == (byte) 0x07
}
}
return false
}
@Override
SomeIpTestResult test(MetaFrame metaFrame) {
for (sd in metaFrame.someipSd()) {
for (option in sd.options()) {
return option.totalLength() == (int) 0x0015 ? SomeIpTestResult.ok() : SomeIpTestResult.failed(option.totalLength())
}
}
return SomeIpTestResult.failed("No option array found")
}
@Override
String errorDescription(MetaFrame metaFrame, Object result) {
return String.format("Frame: %d, timestamp: %s. ErrorMessage: %s\n", metaFrame.index(), metaFrame.absoluteTime().toString(), result)
}
}
The core Mercury API offers a stream of processed SOME/IP Service Discovery (SD type, service ID, etc.) and SOME/IP data frames with header information (service ID, method group ID, etc.) and a dissected data payload where signal/property names and values are made readily available.