doip - Diagnostics Over IP

Overview

Diagnostics over IP (DoIP) serves as a transport protocol for diagnostic services, e. g. for Unified Diagnostics Services (UDS). It is used to transport UDS messages over IP networks in a standardized way. DoIP is specified in ISO 13400-2. This abstracts the actual transport layer and allows the usage of logical diagnostic addresses instead to communicate with different entities. For security, DoIP can be used on top of TLS.

Features

The module currently provides a DoIP server implementing DoIP version 2 as per ISO 13400-2:2012.

Architecture

The module provides a DoIP server implementation for discovery and transport of UDS messages over IP networks. The server functionality can be found in the server subdirectory. Functionality that is common across the module is found in the common subdirectory.

The server implements DoIP discovery by offering classes to receive Vehicle Identification Requests and send Vehicle Identification Responses back to clients as well as broadcast Vehicle Announcement Messages. The class handling this is DoIpServerVehicleIdentificationService.

Complete class diagram (DoIP server, identification part):

@startuml

class DoIpServerSystem
class DoIpServerVehicleIdentificationService
interface IDoIpServerEntityStatusCallback
class DoIpServerVehicleIdentificationParameters
class DoIpServerVehicleIdentification
class DoIpConcreteOemMessageHandler

class DoIpServerVehicleIdentificationSocketHandler
class DoIpServerVehicleIdentificationRequest
class DoIpServerVehicleIdentificationConfig

interface IDoIpServerVehicleAnnouncementParameterProvider
interface IDoIpServerVehicleIdentificationCallback
interface IDoIpUdpOemMessageHandler

DoIpServerSystem o-- DoIpServerVehicleIdentificationService
DoIpServerSystem --|> IDoIpServerEntityStatusCallback
DoIpServerSystem o-- DoIpServerVehicleIdentificationParameters
DoIpServerSystem o-- DoIpServerVehicleIdentification
DoIpServerSystem o-- DoIpConcreteOemMessageHandler

DoIpServerVehicleIdentificationService o-- DoIpServerVehicleIdentificationSocketHandler
DoIpServerVehicleIdentificationService o-- DoIpServerVehicleIdentificationRequest
DoIpServerVehicleIdentificationService o-- DoIpServerVehicleIdentificationConfig

DoIpServerVehicleIdentificationSocketHandler o-  DoIpServerVehicleIdentificationRequest
DoIpServerVehicleIdentificationConfig        o- DoIpServerVehicleIdentificationRequest

DoIpServerVehicleIdentificationParameters       --|> IDoIpServerVehicleAnnouncementParameterProvider
DoIpServerVehicleIdentification                 --|> IDoIpServerVehicleIdentificationCallback
IDoIpServerEntityStatusCallback                 ..   DoIpServerVehicleIdentificationConfig
IDoIpServerVehicleAnnouncementParameterProvider ..   DoIpServerVehicleIdentificationConfig
IDoIpServerVehicleIdentificationCallback        ..   DoIpServerVehicleIdentificationConfig
DoIpServerVehicleIdentification                 ..   IDoIpUdpOemMessageHandler
DoIpConcreteOemMessageHandler                   --|> IDoIpUdpOemMessageHandler

DoIpServerVehicleIdentificationConfig .. DoIpServerVehicleIdentificationSocketHandler
IDoIpUdpOemMessageHandler             .. DoIpServerVehicleIdentificationSocketHandler

package "common" {

interface IDoIpConnectionHandler
interface IDoIpVehicleAnnouncementListener

DoIpServerVehicleIdentificationSocketHandler --|> IDoIpConnectionHandler
DoIpServerVehicleIdentificationSocketHandler ..   IDoIpVehicleAnnouncementListener

}

@enduml

Complete class diagram (DoIP server, transport part):

@startuml

class DoIpServerLogger

class DoIpServerTransportConnectionPool
class DoIpServerTransportConnection

interface IDoIpServerTransportConnectionCreator
interface IDoIpServerTransportConnectionPool
class DoIpServerTransportMessageHandler
class DoIpTcpConnection

class DoIpServerTransportConnectionProvider
class DoIpServerConnectionHandler
class DoIpServerTransportLayerParameters
class DoIpServerTransportConnectionConfig
class DoIpServerTransportLayer
interface IDoIpServerTransportConnectionProviderCallback
interface IDoIpServerConnectionHandlerCallback
interface IDoIpConnectionHandler
interface IDoIpSendJob
interface IDoIpServerConnection
interface IDoIpServerMessageHandler
interface IDoIpSendJobCallback
interface IDoIpTransportMessageProvidingListener

class DoIpTransportMessageProvidingListenerHelper
interface IDoIpServerTransportLayerCallback

interface IDoIpServerSocketHandler
interface IDoIpServerSocketHandlerListener
class DoIpServerSocketHandler
class Socket
class SocketHandler

class DoIpServerTransportMessageHandler

DoIpServerTransportConnectionPool ..   IDoIpServerTransportConnectionCreator
DoIpServerTransportConnectionPool --|> IDoIpServerTransportConnectionPool
DoIpServerTransportConnectionPool o--  DoIpServerTransportMessageHandler
DoIpServerTransportConnection o-- DoIpServerTransportMessageHandler
DoIpServerTransportConnection o-- DoIpTcpConnection

IDoIpServerTransportConnectionPool .. DoIpServerTransportConnectionProvider
DoIpServerTransportConnection      .. DoIpServerTransportConnectionProvider
DoIpServerTransportConnection    --|> DoIpServerConnectionHandler

IDoIpSendJob          .. DoIpServerTransportMessageHandler
IDoIpServerConnection .. DoIpServerTransportMessageHandler
DoIpServerTransportMessageHandler --|> IDoIpServerMessageHandler
DoIpServerTransportMessageHandler --|> IDoIpSendJobCallback

DoIpServerTransportConnectionProvider ..   IDoIpServerSocketHandler
DoIpServerTransportConnectionProvider --|> IDoIpServerSocketHandlerListener
IDoIpServerSocketHandlerListener .. DoIpServerSocketHandler
DoIpServerSocketHandler -|> IDoIpServerSocketHandler
DoIpServerSocketHandler o-- Socket
DoIpServerSocketHandler o-- SocketHandler

DoIpServerTransportConnectionProvider .. DoIpServerTransportConnectionConfig
DoIpServerTransportConnectionConfig   .. IDoIpTransportMessageProvidingListener
DoIpServerTransportConnectionConfig   .. DoIpServerTransportLayerParameters

DoIpServerTransportConnectionProvider .. IDoIpServerTransportConnectionProviderCallback
DoIpServerConnectionHandler ..   IDoIpServerConnectionHandlerCallback
DoIpServerConnectionHandler ..   IDoIpConnectionHandler
DoIpServerConnectionHandler ..   IDoIpSendJob
DoIpServerConnectionHandler --|>  IDoIpServerConnection
DoIpServerConnectionHandler ..   IDoIpServerMessageHandler
DoIpServerConnectionHandler ..   DoIpServerTransportLayerParameters

DoIpServerTransportLayer -|> IDoIpServerTransportConnectionProviderCallback
DoIpServerTransportLayer -|> IDoIpServerConnectionHandlerCallback
DoIpServerTransportLayer o-- DoIpServerTransportConnectionProvider
DoIpServerTransportLayer o-- DoIpServerTransportConnectionConfig
DoIpServerTransportLayer o- DoIpTransportMessageProvidingListenerHelper
IDoIpServerTransportLayerCallback .. DoIpServerTransportLayer


@enduml

Establishing a Server Connection

Details establishment of server connections as seen in the unit test DoIpServerTransportLayerTest.TestSendWithConnection.

@startuml DoIpServerTransportLayer.TestSendWithConnection.Sequence

participant App as App
participant DoIpServerTransportLayer as STL
participant DoIpServerTransportConnectionProvider as STConnProv
participant IDoIpServerSocketHandler as SSH
participant IDoIpServerTransportConnectionPool as STConnPool
participant DoIpServerTransportConnection as STConn

App -> STL ++ : init()
STL -> STConnProv ++ : start()
STConnProv -> SSH ++ : start()
SSH -> SSH : connectionAcceptanceProcess
SSH --> STConnProv -- :
STConnProv --> STL -- :
App <-- STL -- :
SSH -> STConnProv ++ : callback:connectionAccepted()
STConnProv -> STL ++ : getSocketGroupId()
STL --> STConnProv --:
STConnProv -> STConnPool ++ : createConnection(socketGroupId, socket)
STConnPool -> STConn ++ : DoIpServerTransportConnection()
STConnPool <-- STConn -- : instance:DoIpServerTransportConnection
STConnPool --> STConnProv -- : connection
STConnProv -> STL ++ : connectionAccepted()
STL -> STL : store connection
STL -> STConn ++ : start()
STConn -> STConn ++ : init()
STConn --
STConn -> STConn ++ : sendConnectionOpened()
STConn --
STConn -> STConn ++ : scheduleRoutingActivationRequest()
STConn --
STConn --> STL -- :
STL --> STConnProv -- :
STConnProv --
STConn --
STConn -> STConn ++ : routingActivationRequestReceived()
STConn -> STL ++ : checkRoutingActivation()
STL -> STL ++ : RoutingActivationCheckResult()
STL --
STL --> STConn -- : RoutingActivationCheckResult()
STConn -> STL ++ : handleRoutingActivationRequest()
STL -> STL ++ : startAliveCheck()
STL -> STConn ++ : routingActivationCompleted()
STConn -> STConn ++ : sendRoutingActivationResponse()
STConn --
STConn -> STL ++ : routingActive()
STL -> App ++ : routingActive()
STL <-- App -- :
STConn <-- STL -- :
STConn --
STConn --
STL --
STL --

App -> STL ++ : send()
STL -> STConn ++ : send()
STConn -> STConn ++ : sendMessage()
STConn --
STConn --> STL --
App <-- STL -- :

@enduml

Interface to the Transport Router

A DoIpServerTransportConnection inherits from DoIpServerConnectionHandler in order to process DoIP protocol messages and it owns one (or several) DoIpServerTransportMessageHandlers. A DoIpServerTransportMessageHandler is responsible for sending and receiving diagnostic messages, to and from a DoIP TCP connection and acts as an interface with a TransportRouter. It references an IDoIpTransportMessageProvidingListener as well as an ITransportMessageProcessedListener. The TransportRouter only implements the ITransportMessageProvidingListener. The class DoIpTransportMessageProvidingListenerHelper implements the IDoIpTransportMessageProvidingListener interface and helps connecting the DoIpServerTransportMessageHandler to the TransportRouter and translating between transport return values and DoIP ACK/NACK codes. Optionally, if there is a transport router available that can handle the doip specific IDoIpTransportMessageProvidingListener, this can also be registered in the Helper and then this class will be used directly without translation of return codes.

For sending, the DoIpTransportMessageHandler passes the data on to the DoIpTcpConnection. Once the data is consumed by the TCP stack, the ITransportMessageProcessedListener::transportMessageProcessed() callback is called to signal that the transport message is no longer accessed.

@startuml

participant DoIpTcpConnection as TcpC
participant DoIpServerConnectionHandler as SCH
participant DoIpServerTransportMessageHandler as STMH
participant DoIpTransportMessageProvidingListenerHelper as TMPLH
participant TransportRouter as TR
participant DoIpServerTransportLayer as TL

alt protocol message
TcpC -> SCH ++ : headerReceived()
SCH -> SCH ++ : (handle sending directly)
deactivate SCH
TcpC <-- SCH -- :
else diagnostic message
    TcpC -> SCH ++ : headerReceived()
    SCH -> STMH ++ : headerReceived()
    TcpC <- STMH ++ : [async] receivePayload()
    TcpC --> STMH -- :
    SCH <-- STMH -- :
    TcpC <-- SCH -- :
    TcpC -> STMH ++ : diagnosticMessageLogicalAddressInfoReceived()
    STMH -> TMPLH ++ : getTransportMessage()
    TMPLH -> TR ++ : getTransportMessage()
    TMPLH <-- TR -- :
    STMH <-- TMPLH -- :
    TcpC <- STMH ++ : [async] receivePayload()
    TcpC --> STMH -- :
    TcpC <-- STMH -- :
    TcpC -> STMH ++ : diagnosticMessageUserDataReceived()
    STMH -> TMPLH ++ : messageReceived()
    TMPLH -> TR ++ : messageReceived()
    TMPLH <-- TR -- :
    STMH <-- TMPLH -- :
    TcpC <-- STMH -- :
end

STMH <- TL ++ : send()
TcpC <- STMH ++ : [async] sendMessage()
TcpC --> STMH -- :
STMH --> TL -- :
TcpC -> TL ++ : ITransportMessageProcessedListener::transportMessageProcessed()
TcpC <-- TL -- :
@enduml