Skip to content

[go-CAN-03] J1939 BAM transport frames (TP.CM/TP.DT) address destination 0x00 instead of the required global 0xFF #75

Description

@SoundMatt

Location: j1939/tp.go:90 (bamID), j1939/tp.go:100 (dtBaseID)

Finding: TP.CM (PGN 0xEC00, PF=0xEC=236) and TP.DT (PGN 0xEB00, PF=0xEB=235) are both PDU1-format PGNs, meaning the PS byte of the CAN ID carries a destination address rather than being folded into the PGN. For a BAM broadcast, SAE J1939-21 requires that destination byte to be the global address 0xFF. SendTP builds both the TP.CM and TP.DT arbitration IDs via EncodeID(f.Priority, pgnTPCM/pgnTPDT, b.src), and EncodeID's PDU1 branch (pgn.go:96) deliberately does not write the PS byte at all for PF<240 — so the PS byte comes out as 0x00, not 0xFF. A frame transmitted this way asks for destination address 0x00 rather than announcing itself as a broadcast, which a real J1939 ECU is not obligated to accept. This is invisible in go-CAN's own tests because SubscribeTP's in-process reassembler decodes the PGN via DecodeID and never inspects the PS/destination byte, so sender and receiver agree with each other even though neither matches the wire protocol.

Recommendation: OR the global address (uint32(BroadcastAddr) << 8) into bamID/dtBaseID explicitly, or route BAM ID construction through a TP-aware encode helper that always sets the destination byte for PDU1 TP frames.

Filed from the 2026-07-29 ecosystem audit register; independently re-verified against current HEAD before filing.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions