J1939 CAN to DDS Gateway¶
The J1939 CAN to DDS Gateway service (gva-j1939-gateway) provides integration between J1939 automotive networks and the GVA DDS data bus. It reads J1939 CAN messages from a SocketCAN interface, decodes them according to the SAE J1939 standard, and publishes the parameters as DDS topics defined in the J1939 Automotive Platform Specific Model (PSM).
Overview¶
The gateway implements bidirectional communication:
- CAN to DDS: Reads J1939 CAN frames, decodes PGNs (Parameter Group Numbers) and SPNs (Suspect Parameter Numbers), and publishes them as
C_Parametermessages on DDS - DDS to CAN: Subscribes to J1939 command topics and transmits corresponding CAN frames (future enhancement)
Key Features¶
- ✅ SocketCAN interface support (hardware and virtual CAN)
- ✅ J1939 protocol decoding (29-bit CAN ID, PGN/SPN extraction)
- ✅ Configurable PGN/SPN mappings via JSON
- ✅ DDS publishing of J1939 parameters with status and metadata
- ✅ Systemd service integration
- ✅ Real-time monitoring via LDMX J1939 tab
Architecture¶
Components¶
- SocketCanReader: Qt thread that reads CAN frames from a SocketCAN interface
- J1939Decoder: Decodes J1939 protocol from CAN frames (PGN, SPN, source address, priority)
- J1939Gateway: Main service that coordinates CAN reading and DDS publishing
- J1939Config: Configuration manager for PGN/SPN definitions and scaling
Installation¶
Prerequisites¶
# Install can-utils for testing
sudo apt-get install can-utils
# Ensure kernel vcan module is available
sudo modprobe vcan
Build¶
The gateway is built as part of the LDM SDK:
The executable is installed to /usr/bin/gva-j1939-gateway.
Systemd Service¶
Install the systemd service:
sudo systemctl daemon-reload
sudo systemctl enable gva-j1939-gateway
sudo systemctl start gva-j1939-gateway
Check service status:
Configuration¶
Command-Line Options¶
gva-j1939-gateway [OPTIONS]
Options:
-d, --domain <id> DDS domain ID (default: 0)
-i, --interface <name> CAN interface name (default: vcan0)
-c, --config <path> Configuration file path (default: /etc/gva/j1939-config.json)
-h, --help Display help
-v, --version Display version
Configuration File¶
The gateway uses a JSON configuration file to define PGN and SPN mappings. Default location: /etc/gva/j1939-config.json
Example Configuration:
{
"gatewayResourceId": 6457,
"j1939Address": 249,
"pgns": [
{
"pgn": 61444,
"name": "Electronic Engine Controller 1",
"updateRateHz": 10.0,
"spns": [
{
"spn": 190,
"name": "Engine Speed",
"startBit": 24,
"lengthBits": 16,
"scale": 0.125,
"offset": 0,
"unit": "rpm"
}
]
},
{
"pgn": 65265,
"name": "Cruise Control/Vehicle Speed",
"updateRateHz": 10.0,
"spns": [
{
"spn": 84,
"name": "Wheel-Based Vehicle Speed",
"startBit": 8,
"lengthBits": 16,
"scale": 0.00390625,
"offset": 0,
"unit": "km/h"
}
]
}
],
"applicationAreas": [
{
"resourceId": 6464,
"descriptor": "Engine",
"pgns": [61444]
},
{
"resourceId": 6465,
"descriptor": "Vehicle",
"pgns": [65265]
}
]
}
Configuration Fields¶
| Field | Type | Description |
|---|---|---|
gatewayResourceId |
integer | DDS resource ID for the gateway |
j1939Address |
integer | J1939 source address (0-253, 249=NULL) |
pgns |
array | List of Parameter Group Number definitions |
pgns[].pgn |
integer | PGN number |
pgns[].name |
string | Human-readable PGN name |
pgns[].updateRateHz |
number | Expected update rate in Hz |
pgns[].spns |
array | List of SPNs in this PGN |
pgns[].spns[].spn |
integer | SPN number |
pgns[].spns[].name |
string | Parameter name |
pgns[].spns[].startBit |
integer | Start bit position (0-63) |
pgns[].spns[].lengthBits |
integer | Length in bits (1-64) |
pgns[].spns[].scale |
number | Scaling factor (value = raw * scale + offset) |
pgns[].spns[].offset |
number | Offset value |
pgns[].spns[].unit |
string | Unit of measurement |
applicationAreas |
array | Logical groupings of PGNs |
Testing with Virtual CAN¶
Setup vcan0 Interface¶
This creates a vcan0 virtual CAN interface for testing without hardware.
Send Test Frames¶
This script sends sample J1939 messages including: - Engine speed (PGN 61444) - Vehicle speed (PGN 65265) - Engine temperature (PGN 65262)
Monitor with LDMX¶
-
Start the gateway:
-
Start LDMX:
-
Navigate to the J1939 tab
-
Run the test script in another terminal:
-
Observe J1939 parameters appearing in the LDMX table with timestamps, PGN, SPN, values, and status
Manual Testing¶
Send individual CAN frames:
# Engine speed = 1500 RPM
cansend vcan0 18F00400#FFFFFFFFFFE02E00
# Vehicle speed = 60 km/h
cansend vcan0 18FEF100#FF003C0000FFFFFF
Monitor CAN traffic:
J1939 Protocol Details¶
CAN ID Format (29-bit)¶
| Bits | Field | Description |
|---|---|---|
| 28-26 | Priority | Message priority (0=highest, 7=lowest) |
| 25 | Reserved | Reserved bit |
| 24 | Data Page (DP) | Extended page select (0 or 1) |
| 23-16 | PDU Format (PF) | Protocol Data Unit Format |
| 15-8 | PDU Specific (PS) | Group extension or destination address |
| 7-0 | Source Address (SA) | Source controller address (0-253) |
PGN Calculation¶
if PF < 240:
PGN = DP << 16 | PF << 8 | 0x00 (PDU1 - destination specific)
else:
PGN = DP << 16 | PF << 8 | PS (PDU2 - broadcast)
Common PGNs¶
| PGN | Name | Update Rate |
|---|---|---|
| 61444 | Electronic Engine Controller 1 | 10 Hz |
| 65265 | Cruise Control/Vehicle Speed | 10 Hz |
| 65262 | Engine Temperature 1 | 1 Hz |
| 65263 | Engine Fluid Level/Pressure 1 | 1 Hz |
DDS Topics¶
The gateway publishes to the following DDS topics defined in J1939_Automotive_PSM.idl:
C_Parameter¶
Individual parameter values (SPNs).
Topic Name: J1939_Automotive__Parameter
Key Fields:
- A_sourceID.A_resourceID: Gateway resource ID
- A_sourceID.A_instanceID: SPN number
Data Fields:
- A_suspectParameterNumber: SPN
- A_value: Parameter value (GenericValueType)
- A_valueStatus: Available/Error/Not_Available
- A_metadata: Timestamp and validity period
C_Parameter_Group_Definition¶
PGN definitions.
Topic Name: J1939_Automotive__Parameter_Group_Definition
Fields:
- A_parameterGroupNumber: PGN
- A_transmitSupported: Whether transmit is supported
- A_frequency: Update rate in Hz
C_Data_Source¶
Gateway status.
Topic Name: J1939_Automotive__Data_Source
Fields:
- A_onStatus: Operational/Standby/Off/Failed
- A_specification_sourceID: Link to specification
Troubleshooting¶
CAN Interface Not Found¶
Error: Failed to get interface index for vcan0
Solution:
# Check if interface exists
ip link show vcan0
# If not, create it
sudo ./scripts/test/j1939/setup-vcan.sh
Permission Denied¶
Error: Failed to create CAN socket: Operation not permitted
Solution: Run with sudo or add user to relevant groups:
No Messages in LDMX¶
-
Check gateway is running:
-
Check DDS domain matches:
-
Verify CAN traffic:
-
Check gateway logs:
LDMX J1939 Tab¶
The LDMX monitoring tool includes a dedicated J1939 tab for real-time visualization of J1939 parameters.
Features¶
- Table View: Displays all received J1939 parameters with columns:
- Timestamp
- PGN (Parameter Group Number)
- PGN Name
- SPN (Suspect Parameter Number)
- SPN Name
- Value
- Unit
-
Status (Available/Error/Not Available)
-
Controls:
- Clear: Clear all messages from the table
- Pause/Resume: Pause or resume message updates
-
Filter: Filter messages by PGN or SPN number
-
Status Bar: Shows total message count
Usage¶
- Start LDMX:
ldmx - Click on the J1939 tab
- Start the gateway (if not already running)
- Messages will appear in real-time as they are received
References¶
Future Enhancements¶
- [ ] DDS to CAN transmission (command support)
- [ ] Multi-frame transport protocol support (TP)
- [ ] DM1 diagnostic message support
- [ ] Address claiming support
- [ ] Configuration GUI
- [ ] CAN frame timestamping from hardware
- [ ] Statistics and diagnostics dashboard