# JPO Operational Data Environment User Guide
**Submitted to**\
U.S. Department of Transportation (USDOT)\
Federal Highway Administration ITS JPO
**Prepared by**\
Booz Allen Hamilton\
8283 Greensboro Drive\
McLean, VA 22102
_Last updated February 7, 2019_
# Table of Contents
- [Version History](#version-history)
- [1 - Introduction](#introduction)
- [2 - Project Overview](#project-overview)
- [3 - System Overview](#system-overview)
- [4 - Audience](#audience)
- [5 - Glossary](#glossary)
- [6 - ODE DEVELOPMENT ENVIRONMENT](#ode-development-environment)
- [6.1 - Java Development Tools](#java-development-tools)
- [6.2 - Java](#java)
- [6.3 - Eclipse IDE](#eclipse-ide)
- [6.4 - Maven](#maven)
- [6.5 - Git Version Control](#git-version-control)
- [6.6 - Building ODE Software Artifacts](#building-ode-software-artifacts)
- [6.6.1 - Open-Source Repository](#open-source-repository)
- [6.6.2 - ASN.1 Java API](#asn-1-java-api)
- [6.6.3 - Build and Deploy Procedure](#build-and-deploy-procedure)
- [6.6.4 - ODE Application Properties](#ode-application-properties)
- [6.6.5 - ODE Logging Properties](#ode-logging-properties)
- [7 - ODE Features](#ode-features)
- [7.1 - Managing SNMP Devices](#managing-snmp-devices)
- [7.1.1 - Query Parameters](#query-parameters)
- [7.1.2 - API Details](#api-details)
- [7.1.3 - Web Based View](#web-based-view)
- [7.1.4 - Additional Features/ Discussion Points](#additional-features-discussion-points)
- [7.2 - Logging Events](#logging-events)
- [7.2.1 - Log Levels](#log-levels)
- [7.2.2 - Logging Setup](#logging-setup)
- [7.2.3 - Steps to turn on/off logging during application runtime](#steps-to-turn-on-off-logging-during-application-runtime)
- [7.3 - Inbound Data Distribution](#inbound-data-distribution)
- [7.3.1 - Inbound BSM Log File Processing and Distribution](#inbound-bsm-log-file-processing-and-distribution)
- [7.3.2 - Inbound TIM Log File Processing and Distribution](#inbound-tim-log-file-processing-and-distribution)
- [7.3.3 - Inbound Other Log File Processing and Distribution](#inbound-other-log-file-processing-and-distribution)
- [7.3.4 - Inbound BSM - Test File Processing (HEX and JSON)](#inbound-bsm---test-file-processing-hex-and-json)
- [7.4 - Probe Data Management](#probe-data-management)
- [7.4.1 - PDM Broadcast Request Quick Start Guide](#pdm-broadcast-request-quick-start-guide)
- [7.5 - Outbound TIM Broadcast](#outbound-tim-broadcast)
- [7.5.1 - Outbound TIM to SDW Websocket Setup](#outbound-tim-to-sdw-websocket-setup)
- [7.5.2 - Outbound TIM to S3 Bucket Setup](#outbound-tim-to-s3-bucket-setup)
- [7.5.3 - TIM Broadcast Request Quick Start Guide](#tim-broadcast-request-quick-start-guide)
- [7.6 - Privacy Protection Module (PPM)](#privacy-protection-module-ppm)
- [7.7 - Data validation](#data-validation)
- [7.8 - String S3 Depositor](#string-s3-depositor)
- [7.9 - Security Services Module](#security-services-module)
- [8 - Appendix A: ODE Interface Specification](#appendix-a-ode-interface-specification)
- [8.1 - File Copy Data Deposit](#file-copy-data-deposit)
- [8.1.1 - Messages and Alerts](#messages-and-alerts)
- [8.2 - ODE REST API](#ode-rest-api)
- [8.2.1 - Upload BSM File](#upload-bsm-file)
- [8.2.2 - Traveler Information Message (TIM) Interface](#traveler-information-message-tim-interface)
- [8.2.3 - Probe Data Management Messages (PDM) Interface](#probe-data-management-messages-pdm-interface)
- [8.3 - ODE Streaming API](#ode-streaming-api)
- [8.3.1 - Direct Kafka Interface](#direct-kafka-interface)
- [8.3.2 - ODE Output Schema Reference](#ode-output-schema-reference)
- [9 - References](#references)
# Version History
| Version # | Implemented By | Revision Date | What Changed? |
| --------- | -------------- | ------------- | ---------------------------------------------------------------------------------------------------------------- |
| 0.1 | Hamid Musavi | | Initial draft |
| 0.2 | Hamid Musavi | 3/6/2017 | Updated document for ODE-146 |
| 0.3 | ODE Team | 3/14/2017 | Added outbound TIM documentation |
| 0.4 | ODE Team | 3/28/2017 | Added PDM documentation |
| 0.5 | Hamid Musavi | 5/9/207 | Added support for System Design Documentation |
| 0.6 | ODE Team | 5/23/2017 | Added PPM Documentation |
| 0.7 | ODE Team | 5/30/2017 | Added VSD documentation |
| 0.8 | ODE Team | 6/02/2017 | Added BSM documentation |
| 0.9 | ODE Team | 8/28/2017 | Updated properties table. TIM/PDM REST details moved to Swagger document. |
| 0.10 | ODE Team | 9/1/2017 | Added BSM log file handling |
| 0.11 | ODE Team | 10/31/2017 | Updated for open-ode |
| 0.12 | ODE Team | 1/10/2018 | Updated SDC/SDW WebSockets end-point |
| 0.13 | ODE Team | 1/23/2018 | Documented changes related to schemaVersion 4 |
| 0.14 | ODE Team | 2/14/2018 | Added GZIP documentation |
| 0.15 | ODE Team | 12/18/2018 | Added rsuUsername and rsuPassword properties |
| 0.16 | ODE Team | 2/4/2019 | Removed deprecated properties. Added ode.kafkaDisabledTopics |
| 0.17 | ODE Team | 2/6/2019 | Added SDW depositor submodule instructions. Removed deprecated properties and capabilities (VSD deposit to SDC). |
# 1 - Introduction
The JPO Operational Data Environment (ODE) product is being developed
under Agile Development Methodologies, using an open architecture
approach, in an open source environment. This document describes the
preliminary architectural design of the JPO ODE and its interfaces with
external systems including the TMC applications, field devices and
center services.
Note: This is a living document and will be updated throughout the life
of the JPO ODE project to reflect the most recent changes in the ODE
design and stakeholder feedback. All stakeholders are invited to provide
input to this document. Stakeholders may direct all input to the JPO
Product Owner at DOT, FHWA, JPO. To provide feedback, we recommend that
you create an "[issue](https://github.com/usdot-jpo-ode/jpo-ode/issues)"
in the project's GitHub repository
(). You will need a
GitHub account to create an issue. If you don't have an account, a
dialog will be presented to you to create one at no cost.
# 2 - Project Overview
An Operational Data Environment is a real-time data acquisition and
distribution software system that processes and routes data from
Connected-X devices -- including connected vehicles (CV), personal
mobile devices, infrastructure components, and sensors -- to subscribing
applications to support the operation, maintenance, and use of the
transportation system, as well as related research and development
efforts.
The ODE is intended to complement a connected vehicle infrastructure by
brokering, processing and routing data from various data sources,
including connected vehicles, field devices, Transportation Management
Center (TMC) applications and a variety of other data users. Data users
include but not limited to transportation software applications,
Research Data Exchange (RDE), US DOT Situation Data Warehouse.
As a data provisioning service, the ODE can provision data from
disparate data sources to software applications that have placed data
subscription requests to the ODE. On the other direction, the ODE can
accept data from CV applications and broadcast them to field devices
through Road Side Units (RSU) and US DOT Situation Data Warehouse which
in turn will transmit the data to Sirius XM satellites for delivery to
the connected vehicles in the field.
While provisioning data from data sources to data users, the ODE also
will perform necessary security / credential checks and, as needed, data
validation and sanitization.
- Data validation is the process of making a judgment about the
quality of the data and handling invalid data as prescribed by the
system owners.
- Data sanitization is the modification of data as originally received
to reduce or eliminate the possibility that the data can be used to
compromise the privacy of the individual(s) that might be linked to
the data.
# 3 - System Overview
JPO ODE is an open-sourced software application that will enable the
transfer of data between field devices and backend TMC systems for
operational, monitoring, and research purposes. The system will enable
applications to submit data through a variety standard interfaces as
illustrated in the figure below.
The mechanisms chosen for a specific deployment will depend on the
infrastructure, technical resources, and applications available to an
ODE environment.
The JPO-ODE will be designed to support the producers and consumers of
CV data as illustrated in Figure 1 below. _The implementation timeline
for the identified interfaces will depend on the needs of the JPO ODE
customers (Wyoming CV Pilot site, initially) and the priority of these
capabilities to the JPO-ODE product owner._
![](images/userguide/figure1.png)
Figure 1 - ODE System Data Producers and Consumers
# 4 - Audience
This document is intended for use by the ODE client applications.
# 5 - Glossary
| Term | Description |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API | Application Program Interface |
| ASN.1 | Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking |
| Git | Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. |
| JDK | Java Development Kit |
| JPO | Joint Program Office |
| JRE | Java Runtime Environment |
| JVM | Java Virtual Machine |
| Kafka | Apache Kafka is publish-subscribe messaging rethought as a distributed commit log. |
| POJO | Plain Old Java Object |
| SAE | SAE International is a global association of more than 128,000 engineers and related technical experts in the aerospace, automotive and commercial-vehicle industries. |
| J2735 | This SAE Standard specifies a message set, and its data frames and data elements specifically for use by applications intended to utilize the 5.9 GHz Dedicated Short Range Communications for Wireless Access in Vehicular Environments (DSRC/WAVE, referenced in this document simply as “DSRC”), communications systems. (SAE International 2016) |
| SCP | Secure Copy |
| SDW | Situation Data Warehouse |
| TIM | Traveler Information Message |
| US DOT | Unites States Department of Transportation |
| WebSocket | WebSocket is designed to be implemented in web browsers and web servers, but it can be used by any client or server application. The WebSocket Protocol is an independent TCP-based protocol. Its only relationship to HTTP is that its handshake is interpreted by HTTP servers as an Upgrade request. |
| ZooKeeper | Apache ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. |
# 6 - ODE Development Environment
### 6.1 - Java Development Tools
The ODE team uses Java as the primary programming language.
Tools:
- Java
- Eclipse IDE
- Git
- Maven
- GitHub:
### 6.2 - Java
Install Java Development Kit (JDK) 1.8
### 6.3 - Eclipse IDE
Download and install Eclipse.
Configure Eclipse to use Java 1.8 JDK. Local installation of Tomcat can
integrate with Eclipse and can help with prototyping or debugging the
application.
### 6.4 - Maven
Maven is a build and dependency management tool. It is recommended that
a Maven plug-in is installed with your IDE so that your IDE is Maven
"aware". Newer versions of eclipse (Luna and later versions) comes
pre-installed with a Maven plug-in.
Download and install Maven:
### 6.5 - Git Version Control
The ODE software is maintained and version controlled using GIT version
control system.
Recommend clients:
- Tortoise Git
- Source Tree
- GitHub Windows Desktop Application
- Git Extensions
It is recommended that GIT plug-ins are installed with your IDE so that
your IDE is Git "aware". Newer versions of eclipse (Luna and later
versions) comes pre-installed with a Git plug-in.
### 6.6 - Building ODE Software Artifacts
The ODE source code is maintained in several separate Git repositories.
Instructions for obtaining and installing the following repositories can
be found in the jpo-ode/README.md document:
| Repository | Visibility | Description | Source |
|----------------|------------|-------------------------|---------------------------------------------------|
| jpo-ode | public | Main repository | |
| jpo-s3-deposit | public | S3 depositor service | |
| jpo-cvdp | public | PII sanitization module | |
| asn1\_codec | public | ASN.1 encoder/decoder | |
#### 6.6.1 - Open-Source Repository
The ODE deployment artifact consists of one of more jar files that make
up the collection of software modules and service components. Initially,
there will be only one executable jar file (one micros service) but in
the future as the ODE functionality expands it is envisioned that
additional services be introduced in separate jar files. Each service
component jar file will be a standalone "uber-jar" that contains all
necessary dependent jar files. The jar file will be deployable to a
physical or virtual server as well as within a Docker container.
The following components make up the JPO ODE software:
- jpo-ode-common: this component contains all the common classes used
by other jpo-ode components. _This component is the lowest common
denominator and never depends on any other jpo-ode component._
- jpo-ode-core: this component contains the core functions carried out
by the jpo-ode.
- jpo-ode-plugins: this component contains the plug-in modules.
- jpo-ode-svcs: this component and similar future components are the
actual service components. This component is always a Spring
Framework application and implements a specific service.
- asn1_codec: this component is a standalone module able to
subscribing to encoded ASN.1 messages and publishing decoded data.
The component is also capable of encoding and publishing them to the
ODE and other applications. This module will replace the private
repository jpo-ode-private.
#### 6.6.2 - ASN.1 Java API
The data uploaded or deposited to the ODE from the connected vehicles
(CV) and the road-side units (RSU) is encoded in ASN.1 format. In order
for the ODE to utilize the data, it must be able to decode the data from
ASN.1 format into a more generic format, in this case Plain Old Java
Objects (POJOs). ODE utilizes an open-source ASN.1 codec library
provided on GitHub at . ODE team has
built a standalone C/C++ module that uses this library to perform all
required encoding and decoding needs of the application. The module is a
submodule of ODE, also provided on GitHub:
#### 6.6.3 - Build and Deploy Procedure
Follow the steps in jpo-ode/README.md Getting Started guide for building
and deploying the JPO-ODE services.
#### 6.6.4 - ODE Application Properties
JPO ODE configuration can be modified in a number of ways.
1. You can specify the configuration parameters in a file named
_application.properties_ located in the same directory from which
the application is launched.
2. You may specify properties as command line options in the form of
```bash
--ode.propertyName=propertyValue
```
For example, add
```bash
--ode.uploadLocation=myUploadFolder
```
3. _You may_ specify properties as system environment variables in the
form of _ode.DdsCasUsername=fred.flintstone\@stone.age._
Other properties not specific to the ODE can also be defined in a
similar way but without the _ode_ prefix.
Current ODE properties and their default are defined in OdeProperties
class. The property name is the name of the OdeProperties class instance
parameter.
The following table describes all the ODE properties currently
available.
_Table 1 - ODE Application Properties_
| Name | Default Value | Required | Description |
|------------------------------------------|-----------------------------------------------------------------------------------------------|------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ode.kafkaBrokers | $DOCKER_HOST_IP:9092 | X | List of kafka brokers and ports |
| ode.uploadLocationRoot | ./uploads | | Location of the shared directory where ODE monitors for files to ingest. |
| ode.uploadLocationObuLog | ./uploads/bsmlog | | Specific location for OBU log files with header fields to specify direction, UTC timestamp, and other metadata |
| ode.pluginsLocations | ./plugins | | Location of the jar files for ODE plugins. |
| ode.kafkaProducerType | async | | Specifies whether publishing to Kafka will be synchronous (i.e. blocking until the data has been persisted) or asynchronous (i.e. publish and forget). Valid values are: sync or async. Sync will generally be slower but more reliable, async is faster with the risk of losing data if kafka crashes during the write operation. |
| ode.ddsCasUsername | null | X | Username to be used for authentication when interfacing with Situation Data Warehouse |
| ode.ddsCasPassword | null | X | Password to be used for authentication when interfacing with Situation Data Warehouse (SDW) |
| ode.ddsCasUrl | | | URL of the US DOT security server. |
| ode.ddsWebsocketUrl | wss://webapp.cvmvp.com/whtools/websocket | | URL of the US DOT SDW WebSockets API |
| ode.sdcIp | 104.130.170.234 | | IPv4 address of SDC |
| ode.sdcPort | 46753 | | Destination port of SDC |
| ode.bsmReceiverPort | 46800 | | The UDP port that ODE will use to listen to BSM messages. |
| ode.bsmBufferSize | 500 | | Size of the buffer allocated for receiving BSM messages through UDP interface |
| ode. kafkaTopicVsdPojo | AsnVsdPojo | | The topic that contains VSDs if ode.enabledVsdKafkaTopic is enabled. |
| ode.vsdBufferSize | 500 | | Size of the buffer allocated for receiving VSD messages through UDP interface |
| ode.vsdReceiverPort | 46753 | | The UDP port that ODE will use to listen to VSD messages. |
| ode.vsdDepositorPort | 5555 | | The UDP port that ODE will use to send VSD messages to SDC for deposit. |
| ode.vsdTrustport | 5556 | | The UDP port that ODE will use to establish trust with the SDC for VSD messages. |
| ode.caCertPath | | | |
| | null | X | path/to/CaCertFile or define env variable ${ODE_CA_CERT_PATH} |
| ode.selfCertPath | null | X | path/to/selfCertFile or define env variable ${ODE_SELF_CERT_PATH} |
| ode.selfPrivateKeyReconstructionFilePath | null | X | path/to/selfPrivateKeyReconstructionFile or define env variable ${ODE_SELF_PRIVATE_KEY_RECONSTRUCTION_FILE_PATH} |
| ode.selfSigningPrivateKeyFilePath | null | X | path/to/selfSigningPrivateKeyFile or define env variable ${ODE_SELF_SIGNING_PRIVATE_KEY_FILE_PATH} |
| ode.isdBufferSize | 500 | | Size of the buffer allocated for receiving ISD messages through UDP interface |
| ode.isdReceiverPort | 46801 | | The UDP port that ODE will use to listen to ISD messages. |
| ode.isdDepositorPort | 6666 | | The UDP port that ODE will use to send ISD messages to SDC for deposit. |
| ode.isdTrustPort | 6667 | | The UDP port that ODE will use to establish trust with the SDC for ISD messages. |
| ode.dataReceiptBufferSize | null | | Size of the buffer allocated for receiving ISD receipt messages through UDP interface |
| ode.depositSanitizedBsmToSdc | false | | Enable/disable packaging of BSMs into VSDs and depositing VSDs to SDC |
| ode.serviceRespExpirationSeconds | 10 | | Number of seconds the trust manager will wait to receive service request response before timing out. |
| Kafka Topics | See Section 8.3.1.1 | | See Section 8.3.1.1 |
| ode.securitySvcsSignatureUri | null | | The URI for signing data using the jpo-security-svcs module. Normally doesn't need to be set because ODE will calculate it based on DOCKER_HOST_IP. If the service is deployed outside Docker, it should be set to of the server it's running on. If you do not want to sign the data set this property to UNSECURED. |
| ode.rsuUsername | null | If not present in JSON | The SNMP username used to authenticate with an RSU when depositing, deleting, or querying TIMs. |
| ode.rsuPassword | null | If not present in JSON | The SNMP password used to authenticate with an RSU when depositing, deleting, or querying TIMs. |
| ode.kafkaTopicsDisabled | topic.OdeBsmRxPojo, topic.OdeBsmTxPojo, topic.OdeBsmDuringEventPojo,topic.OdeTimBroadcastPojo | | List of topics to be disabled from publishing. |
#### 6.6.5 - ODE Logging Properties
ODE produces two log files:
1. The application log file: for overall application health monitoring
2. Events log file: for tracking and monitoring major data events such
as the flow of data files through the system
The configuration of the loggers is done via _logback.xml_ file. The
default logback.xml is located in the _src/main/resources_ directory of
the source code as well as in the _BOOT-INF\\classes\\_ directory of the
executable jar file. To modify the default values, you can modify the
source _src/main/resources/logback.xml_ file before building the
software or place a different _logback.xml_ file with the modified
values in the working directory of the application.
# 7 - ODE Features
JPO ODE provides the following features and functions to TMC
applications:
1. Managing SNMP Devices
2. Logging Events
3. IEEE 1609.2 Compliance
4. SCMS Certificate Management
5. Inbound BSM Distribution
6. Inbound Probe Data Distribution
7. Outbound Probe Device Management
8. Outbound TIM Broadcast
9. Inbound TIM Distribution
10. Data Validation
11. Data Sanitization
### 7.1 - Managing SNMP Devices
Over SNMP Protocol, the ODE can ping and assess the health of an
existing Road Side Unit to ensure the system is up and running. To
trigger a specific heartbeat call, the ODE provides two separate
interfaces to deploy a message to an RSU.
##### 7.1.1 - Query Parameters
To make a heartbeat call, a user must provide two pieces of information
to identify the device and the information the user is attempting to
capture.
**IP Address:** The published ip address of the device.
**SNMP OID Value:** The numeric OID of the desired information.
_The OIDs for the RSUs are specified in the DSRC Roadside Unit (RSU)
Specifications Document v4.1. The units also respond to ISO standard
OIDs, as demonstrated in the screenshot below._
##### 7.1.2 - API Details
To get the results from the SNMP protocol, submit a RESTful GET request
to the route listed below.
/rsuHeartbeat?ip=\&oid=\
You should receive a detailed plain text response that looks like the
following example. If the device is off, a 4 second timeout will occur
and the ODE will indicate this with an \"\[ERROR\] Empty response\"
message. (This specific OID returns the amount of time since the device
was last powered on)
\[1.3.6.1.2.1.1.3.0 = 0:05:12.59\]
#### 7.1.3 - Web Based View
An additional method way to interact with the heartbeat service is
through the existing web interface located at the root of the
application. On it, a user will see a section for RSU SNMP Query and may
enter in the same IP and OID information as the API Endpoint.
#### 7.1.4 - Additional Features/ Discussion Points
- SNMP v3 discussion needed surrounding v2, v1 support
- V3 username/password
- Should the responses from the application be in a standard format?
(JSON)
### 7.2 - Logging Events
ODE uses Logback logging framework to log application and data events.
#### 7.2.1 - Log Levels
1. ALL - Logger reports to all levels below
2. DEBUG - Logger reports debug information
3. ERROR - Logger reports error events that may still allow the
application to continue running
4. FATAL - Logger reports fatal errors that will cause the application
to abort
5. INFO - Logger reports informational messages
6. OFF - Turns off the logger
7. TRACE - Logger reports more specific debug information
8. WARN - Logger reports application warnings
#### 7.2.2 - Logging setup
- As it stands, the current logging framework has two separate log
files. The first log file is for application output called ode.log.
Application debug information and backend service messages are
output to this file. The second log file, Events.log contains
informational messages pertaining to the services a message goes
through inside of the system.
- The current setup of the logging framework is very minimal. It
contains four loggers and two appenders for the respective files.
The logback framework has the ability to set time based file
deletion, and rolling archive file naming. For the full list of
features visit this URL:
#### 7.2.3 - Steps to turn on/off logging during application runtime.
1. Start ode, Kafka, and Zookeeper as normal.
2. In a new terminal window run \"jconsole\".
3. After the dialog box comes up asking for connection, click on the
remote access button at the bottom.
4. Input the ip address you set to be your DOCKER\_HOST\_IP:9090 (ex.
0.0.0.0:9090).
5. Click connect.
6. Select insecure connection.
7. Select the MBeans tab at the top.
8. Expand the folder ch.qos.logback.classic until you get to Attributes
and Operations.
9. Open the operations Tab.
10. Select the reloadbyfilename option.
11. In the dialog box input the name of your logging configuration file.
(Currently logback.xml)
12. Edit logback.xml inside of the docker container for ode and modifiy
the log level for whatever logger you wish to turn off to \"OFF\".
13. Save the file and go back to the jconsole and click the button
reloadbyfilename to submit changes.
### 7.3 Inbound Data Distribution
ODE accepts Inbound BSMs, TIMs and other data types via File Copy Data
Deposit mechanism as described in section 8.1. Note that after files are
processed by the ODE, they are moved to either the backup sub-directory
upon success, or the "failed" sub-directory upon error. The ODE is
capable of accepting log files in both raw data format as well as in
GZIP-compressed format. Compressed files are detected automatically and
processed in the same way as normal files, no special actions are needed
by the user.
The ODE propagates received data to applications via a subscription
service provided by Kafka messaging hub. The ODE offers two Kafka
subscription formats, JSON and serialized Java objects (also referred to
as POJO). ODE uses Kryo serializer for serializing POJOs before
publishing. See section 8.3.1 for the topic names to which applications
can subscribe.
#### 7.3.1 - Inbound BSM Log File Processing and Distribution
1. bsmLogDuringEvent
1. BSMs for event (10 seconds before, event, 10 seconds after all at 10 Hz) (purge first)
1. Driver alert
2. Received BSMs from remote vehicle(s), also record host vehicle BSMs
3. If event is longer than 1-minute drop to 1 Hz for host and remove vehicles
4. Add time to each record for all BSMs (from 1609.2 header)
2. bsmTx
1. BSM once every 30 seconds (purge second)
1. Add time to each record for all BSMs (from 1609.2 header)
3. rxMsg
1. Received messages (purge third)
1. Received BSMs from nearby OBUs are logged and deposited to the ODE via the file copy interface.
#### 7.3.2 - Inbound TIM Log File Processing and Distribution
1. rxMsg
1. Received messages (purge third)
1. TIMs from RSU and Satellite, message, location, method of reception (Sat/RSU) and time, only log messages within 20-mile radius and only log first time message is received
2. dnMsg
1. DNM (purge eight)
1. Location, time, DNM (log first unique DNM for Distressed vehicle and for each relay/received vehicle)
2. Top priority for sending this log
3. driverAlert
1. We have a log for driver's alerts, it will need to flag alerts that were not given because of a higher priority alert (purge ninth)
1. Location, time, alert (FCW, TIM, not DNM)
#### 7.3.3 Inbound Other Log File Processing and Distribution
**STATUS: These log messages have not yet been implemented.**
1. environmentMsg
1. Environmental Log (purge seventh)
1. Location, time, environmental log
1. Second priority for sending this log
2. scms
1. SCMS (purge fifth)
1. Log connections to SCMS
3. systemLog
1. System log (very PII sensitive, just for internal use and will have to be locked down and encrypted, may want to exclude collection of this once the pilot is working well) (purge sixth)
1. Boot and shutdown location/time
2. Application errors and re-starts
3. OBU unique identifier
4. upgrades
1. OBU upgrades (purge fourth)
1. Log success/fail of firmware updates
2. Log availability of firmware updates
#### 7.3.4 - Inbound BSM - Text File Processing (HEX and JSON)
HEX and JSON file processing is no longer supported
### 7.4 - Probe Data Management
ODE accepts PDM messages and other metadata parameters for broadcasting
PDM messages via the REST API interface. The ODE accepts data elements
in JSON which are then sent via SNMP to an array of Roadside Units
(RSUs) which are also specified in that same JSON string.
#### 7.4.1 - PDM Broadcast Request Quick Start Guide
To run a local test of the PDM message API, please follow these
instructions.
1. Start the ODE.
2. Reference the Swagger documentation located in the /docs folder of
the repo to view the specifications for the API call. If needed,
paste the YAML file into to see a rendered
webpage for the documentation.
3. Use a web based REST tool such as Postman to send the PDM broadcast
request to the ODE. Make sure the REST request body contains the
"snmp" and "rsus" elements with valid IP addresses of the RSUs that
you intend to send the message to.
4. The REST interface will return a response indicating the request was
executed successfully: {success: true}. If the request fails, you
will receive an error message such as:\
```json
{
"timestamp": 1489415494755,
"status": 400,
"error": "Bad Request",
"exception": "us.dot.its.jpo.ode.traveler.TimMessageException",
"message": "us.dot.its.jpo.ode.traveler.TimMessageException: Empty response from RSU 127.0 .0 .1",
"path": "/tim"
}
```
### 7.5 - Outbound TIM Broadcast
ODE accepts TIM messages and other metadata parameters for broadcasting
TIM messages via the REST API interface. The ODE accepts data elements
in JSON format from which a fully formed ASN.1 compliant J2735
TravelerInformation message will be constructed and sent to an array of
RSUs. The RSUs must be specified in the TIM broadcast message received
by the ODE. In addition to the RSU devices, the TIM message is also
deposited to the US DOT Situation Data Warehouse (SDW) from which the
SiriusXM satellites will pull from and broadcast to vehicles that are
not within range of RSUs. SDW parameters are also specified in the TIM
REST interface. Please refer to the Swagger file documentation for
details of a TIM REST interface.
#### 7.5.1 Outbound TIM to SDW Setup
Traveler Information Messages may be distributed to RSUs, the SDW, or both by including certain objects in the JSON message sent to the `/tim` endpoint:
- **RSU Distribution**: The /tim REST service will send the TIM messages to RSUs
if both "rsus" and "snmp" elements of the request body are defined
and valid. If either "rsus" or "snmp" are missing, the request will
not be sent to the RSUs.
- **SDW Enablement**: /tim REST service sends the TIM messages to SDW
if the "sdw" element of the request body is defined and valid. If
"sdw" element is missing, the request will not be sent to the SDW.
**Option 1: Websocket Interface**
ODE **Configuration**: Update the effective application.properties file
with username and password for Webapp2/sdw. Substitute your username and
password for `` and ``, respectively.
```bash
ode.ddsCasUsername=
ode.ddsCasPassword=
ode.depositSdwMessagesOverWebsocket=true
```
(OR)
Define the following command line arguments while launching the ODE through the jpo-ode-svcs JAR:
```bash
--ode.ddsCasUsername=,
--ode.ddsCasPassword=,
--ode.depositSdwMessagesOverWebsocket=true
```
(OR)
Define the following environment variables in the environment file:
```bash
SDW_USERNAME=
SDWPASSWORD=
ODE_DEPOSIT_SDW_MESSAGES_OVER_WEBSOCKET=true
```
**Note**: This option uses the ODE's built-in SDW depositor and does not
require a SDW service to be running. Therefore, jpo-sdw-depositor
service should be removed from docker-compose.yml.
**Option 2 (Recommended): SDW Depositor Submodule**
Depositing a TIM message to the Situation Data Warehouse can be done
using the pre-built jpo-sdw-depositor repository. To set this service
up:
1. Follow the steps in the ODE README.md to clone and compile the SDW
depositor service. If you used the `--recurse-submodules` option to clone, it will automatically be cloned.
2. Set the following environment variable to false OR comment it out using the \# symbol:
```
ode.depositSdwMessagesOverWebsocket=false
#ode.depositSdwMessagesOverWebsocket
```
3. Set the following environment variables in the _.env_ file:
```bash
SDW_USERNAME=myUsername
SDW_PASSWORD=myPassword
```
4. Follow the rest of the ODE setup steps. The SDW depositor service
containers will be automatically created by docker-compose.
5. Verify arrival of messages in SDW by verifying response status
messages in the logs.
#### 7.5.2 - Outbound TIM to S3 Bucket Setup
Depositing a TIM message to an S3 bucket can be done using the pre-built
jpo-s3-depositor repository. To set this service up:
1. Follow the steps in the ODE README.md to clone and compile the S3
depositor service.
2. Set the following environment variables (and/or use the RDE prefixed
variables, these prefixes are for guidance only and do not
necessarily need to be a CVPEP or RDE bucket):
- CVPEP\_TIM\_S3\_ACCESS\_KEY\_ID
- CVPEP\_TIM\_S3\_SECRET\_ACCESS\_KEY
- CVPEP\_TIM\_S3\_BUCKET\_NAME
- CVPEP\_TIM\_S3\_DEPOSIT\_KEY
- CVPEP\_TIM\_S3\_TOPIC
3. Follow the rest of the ODE setup steps. The S3 depositor service
containers will be automatically created by docker-compose.
4. Verify arrival of messages in S3 by visiting the AWS UI or an S3
client application.
#### 7.5.3 - TIM Broadcast Request Quick Start Guide
To run a local test of the TIM Message API, please follow these
instructions:
1. Start the ODE with valid ode.ddsCasUsername and ode.ddsCasPassword
in the effective application.properties file.
2. Reference the Swagger documentation located in the /docs folder of
the repo or at to view the
specifications for the API call.
3. Copy the curl command, run the python script, or use a web based
REST tool such as Postman to send the TIM broadcast request to the
ODE. Make sure the REST request body contains the "snmp" and "rsus"
elements with valid IP addresses of the RSUs that you intend to send
the message to as well as the required SDW parameters.
4. The REST interface will return a response indicating the deposit
success ("success":"true") or failure ("success":"false") for each
RSU and the SDW deposit:
```json
{
"rsu_responses": [{
"target": "192.168.1.100",
"success": "true",
"message": "Success."
}],
"dds_deposit": {
"success": "true"
}
}
```
### 7.6 Privacy Protection Module (PPM)
PPM is a separate repository within the GitHub
[usdot-jpo-ode](https://github.com/usdot-jpo-ode) organization. ODE
interfaces with the PPM module via Kafka messaging hub. Please refer to
the GitHub repository for
details. For instructions about configuration and integration of the PPM
with ODE, please refer to the ODE README file at the root of the GitHub
page .
### 7.7 - Data validation
TBD
### 7.8 - String S3 Depositor
The ODE has the capability to deposit any string messages to any S3
buckets using the application in the jpo-s3-depositor repository. To
obtain and build this service, follow the instructions in the ODE
README.md document. Once downloaded and compiled, all the user must do
is set the relevant environment variables, the rest is managed
automatically by docker-compose.
Four example S3 depositor configurations are provided in the
docker-compose.yml file in the root of the jpo-ode directory, a BSM and
TIM depositor for both CVPEP and RDE: cvpep\_bsm\_s3dep,
rde\_bsm\_s3dep, cvpep\_tim\_s3dep, and rde\_tim\_s3dep. These example
templates are provided for convenience and guidance but may be
removed/commented out by adding a \# symbol to the front of each line,
or copied to create new a new S3 depositor.
### 7.9 - Security Services Module
ODE integrates with the
[jpo-security-svcs](https://github.com/usdot-jpo-ode/jpo-security-svcs)
(JSS) module for performing message signing, verification, encryption
and decryption. ODE sends TIM messages to JSS module to be signed before
broadcasting the message to RSUs and SDW. No new configuration
properties need to be set if the module and ODE run in Docker containers
on the same server. However, if they are running o different host
machines the property _ode.securitySvcsSignatureUri_ must be set to
point to the JSS domain name or IP:Port number. The JSS module must,
however, be configured with the DNS name or IP:Port of the Green Hills
HSM security service URI. This property can be defined using the
environment variable _SEC\_CRYPTO\_SERVICE\_BASE\_URI_. It must be set
to [http://ip:port](http://ip:port) of the Green Hills appliance. If you
do not want to sign the data set
_SEC\_CRYPTO\_SERVICE\_BASE\_URI=UNSECURED_
# 8 - Appendix A: ODE Interface Specification
Field devices and TMC applications interface with the ODE for both
sending and receiving data to and from the ODE
Ode provides two methods of accepting data from field devices:
- File copy: described in section 7.1
- RESTful API: upload described in section 7.2
ODE provides several methods for the TMC applications (or any ODE client
application) to send and receive data to and from the ODE
- RESTful API: upload described in section 7.2
- Streaming API: described in section 7.3.
All of the above interfaces can be secured using SSL encryption.
### 8.1 - File Copy Data Deposit
The File copy method is achieved by providing a configurable location on
a shared file system where field devices will be able to deposit their
data files and log files for processing. The upload location is
specified by the application properties
ode.uploadLocationRoot/ode.uploadLocationObuLog. If not specified,
default locations would be uploads/obulog sub-directory off of the
location where ODE is launched. ODE creates the specified directories if
they do not exist.
Once the ODE processes the received file, it moves it to the
"ode.uploadLocationRoot/backup" sub-directory. The backed-up file is
renamed with a timestamp in milliseconds. If the ODE fails to process a
file, it instead moves the file to the "ode.uploadLocationRoot/failed"
sub-directory.
The files copied to "ode.uploadLocationObuLog" are treated as binary
data of variable length records conforming to the specification in
"data/wydotLogRecords.h" file. No header information is expected to
precede each record. As mentioned in section 7.3, the ODE is also
capable of accepting individual files compressed with GZIP. Note that
while the ODE will automatically detect and process GZIP files, it is
not capable of importing GZIP-TAR archives containing multiple files.
| Field Name | Field Length (bytes) | Description |
|--------------------|----------------------|----------------------------------------------------------------------------------------|
| logRecordType | 1 | Represents the type of log record as defined below:
typedef enum _logRecordType {
DN_MSG = 0,
ENVIRONMENT_MSG = 1,
DRIVER_ALERT = 2,
UPGRADES = 3,
SYSTEM_LOG = 4,
RX_MSG = 5,
SCMS = 6,
BSM_TX = 7,
BSM_RX = 8
} logRecordType; |
| direction | 1 | Represents the source of the BSM. 0 for EV(Tx), 1 for RV(Rx) |
| utctimeInSec | 4 | UTC time in seconds from Epoc 1/1/1970 |
| mSec | 2 | milliseconds part of UTC time |
| verificationStatus | 1 | contains a SecurtyStatusCode as defined below:
typedef enum _securityResultCode { /* from dot3 */
success = 0,
inconsistentInputParameters = 2,
spduParsingInvalidInput = 3,
spduParsingUnsupportedCriticalInformationField = 4,
spduParsingCertificateNotFound = 5,
spduParsingGenerationTimeNotAvailable = 6,
spduParsingGenerationLocationNotAvailable = 7,
spduCertificateChainNotEnoughInformationToConstructChain = 8,
spduCertificateChainChainEndedAtUntrustedRoot = 9,
spduCertificateChainChainWasTooLongForImplementation = 10,
spduCertificateChainCertificateRevoked = 11,
spduCertificateChainOverdueCRL = 12,
spduCertificateChainInconsistentExpiryTimes = 13,
spduCertificateChainInconsistentStartTimes = 14,
spduCertificateChainInconsistentChainPermissions = 15,
spduCryptoVerificationFailure = 16,
spduConsistencyFutureCertificateAtGenerationTime = 17,
spduConsistencyExpiredCertificateAtGenerationTime = 18,
spduConsistencyExpiryDateTooEarly = 19,
spduConsistencyExpiryDateTooLate = 20,
spduConsistencyGenerationLocationOutsideValidityRegion = 21,
spduConsistencyNoGenerationLocation = 22,
spduConsistencyUnauthorizedPSID = 23,
spduInternalConsistencyExpiryTimeBeforeGenerationTime = 24,
spduInternalConsistencyextDataHashDoesntMatch = 25,
spduInternalConsistencynoExtDataHashProvided = 26,
spduInternalConsistencynoExtDataHashPresent = 27,
spduLocalConsistencyPSIDsDontMatch = 28,
spduLocalConsistencyChainWasTooLongForSDEE = 29,
spduRelevanceGenerationTimeTooFarInPast = 30,
spduRelevanceGenerationTimeTooFarInFuture = 31,
spduRelevanceExpiryTimeInPast = 32,
spduRelevanceGenerationLocationTooDistant = 33,
spduRelevanceReplayedSpdu = 34,
spduCertificateExpired = 35
} securityResultCode; |
| curLocation | location | The location and speed of the vehicle receiving and reporting the event. |
| | | /* below elements units are as per SAE-2735 */ typedef struct _location {
uint32_t latitude;
uint32_t longitude;
uint32_t elevation;
uint16_t speed;
uint16_t heading;
} __attribute__((__packed__)) location; |
| rxFrom | rxSource | The source of the message received: typedef enum _rxSource {
RSU = 0,
SAT, //XM satelite
RV, /* for BSM rx */
SNMP /* for SRM payload from backend/ODE*/
} rxSource; |
| latitude | 4 | The latitude of the vehicle receiving and reporting the event. |
| longitude | 4 | The longitude of the vehicle receiving and reporting the event. |
| elevation | 4 | The elevation of the vehicle receiving and reporting the event. |
| speed | 2 | The speed of the vehicle receiving and reporting the event. |
| heading | 2 | The heading of the vehicle receiving and reporting the event. |
| length | 2 | Length of data contained in the following payload |
| payload | 2302 | RAW encoded data in 1609.2 format containing a MessageFrame header plus BSM or raw BSM |
ODE will use utctimeInSec plus mSec fields to populate the generatedAt
field of the output messages if and only if the payload is not signed
with a valid signature. If the payload contains a valid 1609.2
signature, the generationTime from 1609.2 header will be used.
#### 8.1.1 - Messages and Alerts
This interface uses the file system to copy a file from source to
destination. As a result, the messages and alerts generated by the copy
command are platform dependent. The following table describes a sample
set of exit codes returned by scp command but they may differ from the
system on which ODE is deployed and running.
Table 1 - SCP Return Codes
| 0 | Operation was successful |
|----|------------------------------------------------|
| 1 | General error in file copy |
| 2 | Destination is not directory, but it should be |
| 3 | Maximum symlink level exceeded |
| 4 | Connecting to host failed. |
| 5 | Connection broken |
| 6 | File does not exist |
| 7 | No permission to access file. |
| 8 | General error in sftp protocol |
| 9 | File transfer protocol mismatch |
| 10 | No file matches a given criteria |
| 65 | Host not allowed to connect |
| 66 | General error in ssh protocol |
| 67 | Key exchange failed |
| 68 | Reserved |
| 69 | MAC error |
| 70 | Compression error |
| 71 | Service not available |
| 72 | Protocol version not supported |
| 73 | Host key not verifiable |
| 74 | Connection failed |
| 75 | Disconnected by application |
| 76 | Too many connections |
| 77 | Authentication cancelled by user |
| 78 | No more authentication methods available |
| 79 | Invalid user name |
Table 2 - File Copy Data Deposit Messages and Alerts
| Message or Alert | Communication Method | Description | Criteria |
|----------------------------------------------------------------------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| See Table 1 - SCP Return Codes for “copy” function Messages and Alerts | Command exit code | See Table 1 - SCP Return Codes for "copy" function Messages and Alerts | Platform Dependent |
| Post-copy: “IMPORTER - Failed to open or process file: {}” FileNotFoundException | Application log file | When a data file is copied into one of the ODE upload folders, ODE will try to open the file and process its content. This error message is logged when ODE fails to open the file due to file not being present. | If the file does not exist when ODE starts to process it or for some other reason cannot be opened for reading, this message is logged in the application log file. |
| “IMPORTER - Failed to open or process file: {}” SecurityException | Application log file | When a data file is copied into one of the ODE upload folders, ODE will try to open the file and process its content. This error message is logged when ODE fails to read the file due to lack of Java security privileges. | If a security manager exists and its checkRead method denies read access to the file, a message will be logged to the application log file.” |
| “IMPORTER - Failed to open or process file: {}” Error decoding data. | Application log file | When a data file is copied into one of the ODE upload folders, ODE will try to open the file and process its content. This error message is logged when ODE fails to decode the data from ASN.1 format. | If the message is not encoded to the expected ASN.1 encoding, ODE will raise this error to indicate failure to decode the data. |
### 8.2 - ODE REST API
ODE exposes a RESTful API for use by clients for security,
administrative and data functions. Standard HTTP/HTTPS verbs such as
GET, POST, PUT, DELETE, etc., will be deployed for various functions.
1. host: ip:port
2. root context path: ode/api/rest
3. protocols:
- http
- https
The REST API is documented using Swagger and can be found at
- this document is also located in
the repository at docs/ODESwagger.yml.
![](images/userguide/figure3.png)
Figure 3 - ODE REST API Editor Tool
#### 8.2.1 - Upload BSM File
ODE provides a REST API interface to upload a file to the ODE. Refer to
[ODE REST API](https://usdot-jpo-ode.github.io/) online documentation
() for details.
#### 8.2.2 - Traveler Information Message (TIM) Interface
Refer to the
[ODESwagger.yaml](https://github.com/usdot-jpo-ode/jpo-ode/blob/develop/docs/ODESwagger.yaml)
for details of the TIM interface.
#### 8.2.3 - Probe Data Management Messages (PDM) Interface
Refer to the
[ODESwagger.yaml](https://github.com/usdot-jpo-ode/jpo-ode/blob/develop/docs/ODESwagger.yaml)
for details of the PDM interface.
### 8.3 - ODE Streaming API
ODE client applications will be able to subscribe to data streams via
two distinct but dependent interfaces.
1. Clients may interface directly or through proxies with Kafka brokers
to subscribe to a well-known topics. See section 7.3.1 for details.
2. Clients may Interface directly with ODE through ODE provided
WebSocket interface as defined by RFC 6455
( ). See section 7.3.2 for
details.
#### 8.3.1 - Direct Kafka Interface
To interface with Kafka directly, the client needs to know the list of
available Kafka brokers and the name of the topic that will contain the
data. The client application may use any of the following methods to
access Kafka topics:
- Native Kafka API (C, Java, Python, etc.)
- Kafka API RESTful Proxy such as:
- Kafka API WebSocket Proxy such as:
A sample Java client will be available in the ODE source repository
under jpo-ode-consumer-example project.
**Kafka Publish/Subscribe Topics**
For a complete list and description of ODE publish/subscribe topics,
refer to [ODE Output Schema Reference Document](#references). (Booz
Allen Hamilton 2018)
#### 8.3.2 - ODE Output Schema Reference
Full details of ODE streaming interface schemas are provided in the [ODE
Output Schema Reference Document](#references). (Booz Allen Hamilton
2018)
# 9 - References
- Booz Allen Hamilton. 2018. "ODE Output Schema Reference."
- SAE International. 2016. 03 30.