The ITS Notification Service is a C++ V2X communication module implementing the Decentralized Environmental Notification Service (DENS) according to ETSI standards (ETSI TS 103 831). It is designed to generate and manage the lifecycle of Decentralized Environmental Notification Messages (DENM) that alert vehicles and infrastructure about road hazards, accidents, or roadworks.
- ETSI-compliant DENM generation
- Event lifecycle management (create, update, terminate)
- MQTT-based integration with external systems
- Thread-safe multi-event handling
- Automatic retransmission and expiration logic
- Designed for microservices architectures
If you find this code useful in your research, please consider citing:
@INPROCEEDINGS{Figueiredo2026,
author={Figueiredo, Andreia and Mendes, Tiago and Rito, Pedro and Luís, Miguel and Sargento, Susana},
booktitle={2026 IEEE Vehicular Networking Conference (VNC)},
title={Demo: A Modular ITS Notification Service for Lifecycle-Aware DENM Generation}
}
- Requirements
- Quick Start
- How it works
- Basic Usage Flow
- Event Lifecycle
- Development Status
- Documentation & Examples
- Authors
- Licence
The ITS Notification Service depends on external components:
-
MQTT Broker (mandatory)
Used for receiving events and publishing DENMs in JSON format. -
Docker (mandatory)
Used to run the ITS Notification Service. -
V2X Stack (Vanetza-NAP) (optional)
Required only for transmitting messages over a V2X network.
The ITS Notification Service can run without it for local testing (MQTT only).Note: The output of the ITS Notification Service is a JSON format of the DENM that matches exaclty what Vanetza-NAP receives as an input.
sudo apt install mosquitto mosquitto-clients
sudo systemctl start mosquittoFor NAP members the Mosquitto broker deployment should be done using the
playbook_mosquitto.ymlavailable in theindividual-playbookfolder here
Ensure Docker and Docker Compose are installed.
docker --version
docker compose versionFor NAP members the Docker deployment should be done using the
playbook_docker.ymlavailable in theindividual-playbookfolder here
Vanetza-NAP is available in https://github.com/nap-it/vanetza-nap
For NAP members the Vanetza-NAP deployment should be done using the
playbook_vanetza.ymlavailable in theindividual-playbookfolder here
- Clone the repository and enter the project folder
git clone https://github.com/nap-it/its-notification-service.git
cd its-notification-service- Start the ITS Notification Service
docker compose up -d- Send a test event
mosquitto_pub -h localhost -t "denm/events/test" -m '{
"event_id": "test_event_001",
"latitude": 40.4168,
"longitude": -3.7038,
"stationType": 5,
"informationQuality": 7,
"eventType": {
"trafficCondition1": 1
},
"validityDuration": 60
}'- Observe output
mosquitto_sub -h localhost -t "vanetza/in/denm" -vEvent-producing services interact with the system via MQTT by sending JSON-encoded events. The ITS Notification Service is responsible for validating these inputs, enforcing lifecycle constraints, and generating ETSI-compliant DENM messages. These messages can then be encoded and transmitted over the network by a V2X stack.
This design enables the integration of heterogeneous event sources while ensuring consistent, standard-compliant dissemination behavior.
The system is composed of three main components:
- Event Receiver
- DENM Sender
- Event Registry
- Type: Asynchronous (MQTT Callback)
- Function: Subscribes to the configured MQTT input topic.
- Logic:
- Parses incoming JSON events.
- Creates or updates DENM structures (Management + Situation containers)
- Manages event lifecycle (creation, updates, termination)
- Upserts data into the
SharedDenmDataEvent Registry usingevent_idas the key. - Immediately signals the Sender thread when new data arrives
- Type: Periodic / Event-Driven Loop
- Frequency: 10 Hz (Check Interval)
- Function: Publishes serialized DENMs to the output MQTT topic.
- Logic:
- Wakes up immediately if a new event arrives or an update occurs.
- Sends the new/updated event information
- Waits on a condition variable with a 100ms timeout (10 Hz).
- Scans all active events in shared memory.
- Transmission Rules:
- Immediate: If the event has been updated since the last transmission.
- Repetition: If
1000ms(1 second) has passed since the last transmission. - Termination: If the event is in
CANCELLINGstate, sends the final DENM and removes it from memory.
- Expiration: Checks
validityDurationagainst the creation timestamp and automatically marks expired events for cancellation.
- Wakes up immediately if a new event arrives or an update occurs.
- Structure: Thread-safe
std::unordered_map<std::string, DenmEventInfo>. - Synchronization: Protected by
pthread_mutex_tand synchronized viapthread_cond_t. - Data: Stores the full DENM in a
rapidjson::Documentstructure, timestamps (creation, last update, last sent), and lifecycle state (ACTIVE,CANCELLING) for every active event.
The ITS Notification Service operates entirely on JSON-based data using SI units, both for incoming events and outgoing DENM messages.
- Event-producing services must send JSON messages describing events
- Values must be provided using standard SI units (e.g., meters, degrees, seconds)
The complete specification of supported fields, data types, valid ranges, optional/mandatory fields
is defined in docs/containerReference.md
- The service produces a JSON representation of a DENM
- This output matches the format expected by Vanetza-NAP
- All values remain in SI units (no ETSI scaling applied)
- The ITS Notification Service does NOT perform ASN.1 encoding
- The service does NOT convert values to ETSI-specific units
- These responsibilities are delegated to the Vanetza-NAP V2X stack, which:
- Encodes the message (ASN.1 UPER)
- Applies ETSI unit scaling and formatting
- Handles transmission
Event-producing Services interface with the ITS Notification Service by sending JSON messages identifing the characterists of an event. Message can be divided into 3 types:
- The creation of a new event
- Updates to an existing event
- The termination of an event
The ITS Notification Service validates all incoming data and handles errors gracefully:
- Mandatory fields with invalid values use ETSI "unavailable" defaults
- Optional fields with invalid values are skipped
- Optional containers with invalid items skip only those items while retaining valid ones
For complete list of valid entries, validation rules, field ranges, and examples, see docs/containerReference.md.
Whenever a new event is received, the ITS Notification Service will:
- Create a JSON representantion of a DENM (see
docs/containerReference.md) - Set
detectionTime(immutable)- Uses the provided value if present
- Otherwise defaults to the current system time
- Transmit immediately
- Retransmit every 1 second
- Expire after
validityDurationseconds fromdetectionTime, or earlier in case of aterminationupdate is received
Event message:
{
"event_id": "accident_highway_km42",
"originatingStationId": 123456,
"detectionTime": 631152000,
"validityDuration": 300,
"latitude": 40.4168,
"longitude": -3.7038,
"stationType": 5,
"informationQuality": 7,
"eventType": {
"accident2": 1
}
}To update an event the same event_id must be sent along with the modified fields. Only provided fields are updated, others remain unchanged
{
"event_id": "accident_highway_km42",
"informationQuality": 5,
"validityDuration": 600
}Note: detectionTime cannot be changed after first message (immutable)
To terminate an event send a message with the event_id and the flag termination. This will cause the final DENM to be sent and remove the event from memory
{
"event_id": "accident_highway_km42",
"termination": 0
}t=0s → Event created with validityDuration=30
State: ACTIVE
Transmits immediately, then every 1 second
t=1s → Retransmission (periodic)
t=2s → Retransmission (periodic)
...
t=30s → validityDuration reached → State: CANCELLING
Sends final DENM → Removed from memory
t=0s → Event created with validityDuration=30
t=10s → Update received (new informationQuality)
Transmits immediately (updated fields)
Continues retransmitting every 1 second
t=30s → Expires normally
t=0s → Event created with validityDuration=300
t=45s → Termination request received (termination=0)
State: ACTIVE → CANCELLING
Immediately sends final DENM with termination flag
Removed from memory immediately
t=0s → Event created
detectionTime=1000, validityDuration=30
Will expire at: 1000 + 30 = 1030
t=20s → Update: validityDuration=60
detectionTime=1000 (unchanged - immutable)
New expiration: 1000 + 60 = 1060
Result: Event extended by 30 more seconds
t=0s → Event created at system time 1000
Input: { "event_id": "accident", ... } // No detectionTime
DEN Service sets:
detectionTime=1000 (current timestamp as fallback)
validityDuration=600 (default)
Will expire at: 1000 + 600 = 1600
t=100s → Malicious update tries to change detectionTime
Input: { "event_id": "accident", "detectionTime": 9999 }
Result: Ignored (detectionTime is locked)
Log: "detectionTime already set (1000s), IGNORING update attempt"
t=600s → Event expires normally (1600 seconds reached)
- Event creation, update, and termination
- Management Container (full support)
- Situation Container (full support)
- Event-driven transmission with condition variables
- Multi-event concurrent management
- Thread-safe shared memory with pthread synchronization
- ETSI-compliant time handling with immutable detectionTime
- Location Container - with advanced container support (roadWorks, stationaryVehicle, etc)
- Alacarte Container
- DCC (Decentralized Congestion Control) integration
For detailed information about DENM data structures and examples:
-
Container Reference: See docs/containerReference.md for the DENM container structure including Management and Situation field specifications ...see
docs/containerReference.md. -
Input Examples: Refer to docs/examples/incomingEvent0.json and docs/examples/incomingEvent1.json for incoming event formats
-
Output Examples: Check docs/examples/output/ for sample DENM outputs including:
outgoingEvent0.json- Expected output when using incomingEvent0.jsoncollisionRisk.json- Collision risk scenariosemergencyVehicleApproaching.json- Emergency vehicle alertshumanPresenceOnTheRoad.json- Pedestrian/human presence eventswrongWayDriving.json- Wrong-way driving detectionunavailable.json- Service unavailability
-
API Documentation (Doxygen):
This project provides automatically generated documentation using Doxygen.To generate the documentation locally:
doxygen Doxyfile
The generated HTML documentation will be available in the
docs/html/directory. Openindex.htmlin a browser to explore the data structures and function descriptions.
Development of NAP-Vanetza is part of ongoing research work at Instituto de Telecomunicações' Network Architectures and Protocols Group.
Questions and Bug Reports: andreiagf@av.it.pt
ITS Notification Service is licensed under LGPLv3, see license file for details.



