AUTOSAR CLASSIC · C O M M U N I C AT I O N S TA C K
Header Mode — Multiplexing PDUs on
one SoCon
Module 3 · 8-byte SoAd header · Tx framing, Rx demux, multi-PDU datagrams
AUTOSAR SoAd Course · Module 3
MODULE 3
Header Mode — when one socket carries
many PDU types
MODULE 3 · WHY
Why a header is needed
• Without a header: one UDP socket = one PDU type. Every new PDU needs a new port,
which doesn't scale.
• With a header: SoAd can pack many PDU types onto one socket — and onto one datagram
if you want.
• The header carries a HeaderId (4 bytes) and a Length (4 bytes). The receiver uses HeaderId
to demux to the right upper-layer PDU.
• This is the default mux mechanism for SOME/IP, DoIP, and almost any real Ethernet
AUTOSAR traffic.
• Header mode is a per-SoConGroup setting in ARXML — "SoAdSocketProtocolHeaderMode"
— affects Tx and Rx symmetrically.
MODULE 3 · W I R E F O R M AT
The 8-byte SoAd header
HeaderId is configured statically per route. Length excludes the 8-byte header itself.
MODULE 3 · RX DEMUX
Rx demux — multiple SocketRoutes per SoCon
One SoCon, two SocketRoutes, picked by HeaderId. Each dispatches to its own upper PduId.
MODULE 3 · TX CODE
Tx with header: prepend 8 bytes (soad.c, M3 path)
if (sc->headerMode) {
uint8 buf[8 + 1024];
uint32 hid = route->headerId;
uint32 len = (uint32)PduInfoPtr->SduLength;
/* Big-endian by spec */
buf[0] = (uint8)(hid >> 24); buf[1] = (uint8)(hid >> 16);
buf[2] = (uint8)(hid >> 8); buf[3] = (uint8)(hid);
buf[4] = (uint8)(len >> 24); buf[5] = (uint8)(len >> 16);
buf[6] = (uint8)(len >> 8); buf[7] = (uint8)(len);
memcpy(buf + 8, PduInfoPtr->SduDataPtr, len);
rv = TcpIp_UdpTransmit(socketId, buf, &remote, (uint16)(8u + len));
}
Real SoAd uses scatter-gather to avoid the copy. Same logic — header bytes pushed in front of the payload.
MODULE 3 · RX CODE
Rx with header: loop, parse, demux (soad.c, M3 path)
uint16 off = 0;
while ((Length - off) >= 8u) {
uint32 hid = (BufPtr[off ]<<24)|(BufPtr[off+1]<<16)
|(BufPtr[off+2]<< 8)|(BufPtr[off+3]);
uint32 plen = (BufPtr[off+4]<<24)|(BufPtr[off+5]<<16)
|(BufPtr[off+6]<< 8)|(BufPtr[off+7]);
off += 8;
if (plen > Length - off) { /* truncated */ return; }
const SocketRoute* sr = findSocketRoute(soConId, /*withHeader*/TRUE, hid);
if (sr) {
PduInfoType info = { .SduDataPtr = &BufPtr[off], .SduLength = plen };
App_RxIndication(sr->upperPduId, &info);
}
off += plen; /* advance and parse the next header */
}
The loop handles multi-PDU datagrams naturally. One datagram in this M3 demo, but the code is identical either way.
MODULE 3 · ARXML
ARXML: header-mode group with two PduRoutes
<ECUC-CONTAINER-VALUE>
<SHORT-NAME>SoConGrp_Link</SHORT-NAME>
<PARAMETER-VALUES>
<PARAM name="SoAdProtocol">UDP</PARAM>
<PARAM name="SoAdSocketLocalPort">30101</PARAM>
<PARAM name="SoAdSocketProtocolHeaderMode">true</PARAM>
</PARAMETER-VALUES>
<SUB-CONTAINERS>
<ECUC-CONTAINER-VALUE>
<SHORT-NAME>SoCon_EcuB</SHORT-NAME>
<PARAMETER-VALUES>
<PARAM name="SoAdSocketRemoteAddress">[Link]</PARAM>
<PARAM name="SoAdSocketRemotePort">30102</PARAM>
</PARAMETER-VALUES>
</ECUC-CONTAINER-VALUE>
</SUB-CONTAINERS>
</ECUC-CONTAINER-VALUE>
Full file: tools/arxml_gen/ecu_a_m3.arxml — plus two PduRoutes with different SoAdTxPduHeaderId values.
MODULE 3 · G E N E R AT E D C O D E
Generated SoCon + Routes with header fields
static const MiniSoAd_SoConCfgType SOCONS[] = {
{ .localPort = 30101, .localAddr = {0,0,0,0},
.remotePort = 30102, .remoteAddr = {127,0,0,1},
.protocol = TCPIP_IPPROTO_UDP,
.headerMode = TRUE,
.name = "SoConGrp_Link/SoCon_EcuB" }, };
static const MiniSoAd_PduRouteCfgType PDU_ROUTES[] = {
{ .upperPduId = PDU_ID_DIAG_REQ, .destSoConId = 0,
.headerId = 0x000000A1u, .name = "PduRoute_TxDiag" },
{ .upperPduId = PDU_ID_TELEM, .destSoConId = 0,
.headerId = 0x000000A2u, .name = "PduRoute_TxTelem" }, };
Two PduRoutes share destSoConId=0 — same socket, different HeaderId. That is the header-mode pattern.
MODULE 3 · DEMO OUTPUT
Sample run — ecu_b_m3 receiving both PDU types
====== ECU B (M3) starting — header mode ======
[SoAd] SoCon 'SoConGrp_Link/SoCon_EcuA' (id=0) ONLINE — local [Link]:30102
[SoAd] Init complete. 1 SoCon(s), 1 PduRoute(s), 2 SocketRoute(s).
[SoAd] RxIndication: SoCon '...' HDR id=0x000000A1 len=11 -> deliver as PduId 16
[App-B] <-- DIAG_REQ (11 bytes): "DIAG req #0"
[App-B] --> IfTransmit PDU_ID_DIAG_RESP ("ACK #0")
[SoAd] IfTransmit: PduId=18 via SoCon '...' (HDR id=0x000000B1 len=6)
[SoAd] RxIndication: SoCon '...' HDR id=0x000000A2 len=14 -> deliver as PduId 17
[App-B] <-- TELEM (14 bytes): "TELEM sample=0"
Same SoCon, two RxIndication paths — selected purely by HeaderId.
MODULE 3 · GOTCHAS
Common header-mode mistakes (worth memorising)
• Both sides must agree on header mode. Mixing modes on the same wire produces silent
garbage.
• HeaderId is configuration, not protocol-defined. Tx and Rx must use the same value — it is
your responsibility.
• Length field is BIG-ENDIAN, four bytes. "Just memcpy the int" works on a big-endian MCU
and fails on x86 / ARM.
• On Rx, a truncated header (datagram < 8 bytes, or claimed length > remaining bytes)
means dropping the whole datagram. SoAd does not piece datagrams together.
• PDU id and HeaderId are different things. PDU id is the upper layer's contract; HeaderId is
the on-the-wire byte field.
MODULE 3 · TA K EAWAYS
Takeaways
• Header mode is what makes Ethernet AUTOSAR's PDU multiplexing actually work.
• The cost is 8 bytes per PDU and the discipline of agreeing on HeaderId values across ECUs.
• Tx prepends, Rx parses + loops + demuxes. Both are short routines once the model is clear.
• ARXML carries one new SoConGroup flag (HeaderMode) and one new field per route
(HeaderId).
• Multi-PDU per datagram falls out of the Rx loop for free — no separate code path needed.
REFERENCES
Resources for further study
• AUTOSAR_SWS_SocketAdapter.pdf — section 7.3 (PDU header). Required reading for
production work.
• AUTOSAR_PRS_SOMEIPProtocol.pdf — SOME/IP also defines a header; SoAd's header is
the lower layer below it.
• ISO 13400-2 — DoIP. Defines its OWN header on top of SoAd's. Module 8 example.
• Wireshark dissectors for SOME/IP and DoIP — useful for cross-checking what is actually on
the wire.
• Vector "Ethernet for AUTOSAR" white paper (free) — surveys the full Ethernet upper-layer
landscape.
END OF MODULE 3
Next: Reception Path Deep Dive
Module 4 will cover Rx path details: buffer ownership, copy semantics, error propagation.
AUTOSAR SoAd Course · Module 3