To explain the Uli SDK, the following notions are descripted in detail:
Service is the behavior that provides well-defined functions. It can be described as a state machine that responds to messages or events in the context of the current state.
Message is to be sent between client and server. Server receives messages and then performs tasks, transitions its state, or raises events.
1.3 Internal Event
Internal event is raised by a service to notify other services in the same component that something significant has happened.
1.4 State Machine
State Machine is to describe the behavior of the Service. State Machine defines the input and output messages and internal events, and state transitions caused by messages and internal events.
1.5 Component (Comp)
Component, Comp in short hand, is a software unit that implements a set of related services. A component is identified by Component ID. There are following types of the component: 0) UNKNOWN, 1) REGULAR – nothing special, and 2) SAFETY_CRITICAL – comp that could raise emergency condition when it is not functioning proper.
Node is a computing module that hosts a set of related components. Node is identified by Node ID.
Subsystem consists of one or more nodes. One of the nodes is designated as Subsystem Node, which has the Node ID=1 and responsible for assigning ID to other nodes. For example, in Figure 1 Network Topologies shows an example of 4 subsystems and their nodes. Note that a subsystem node have external network interfaces (Orange Line) to other subsystems and internal network interfaces (thin black line) to the nodes within the same subsystem.
1.8 Comp Address
Comp Address is a tuple of 3 fields: (Subsystem ID, Node ID, Comp ID). Here is the scheme of the Address:
|Subsystem ID||4 byte unsigned integer||
0x00000000 – unknown
0xFFFFFFFF – wild card
|Node ID||2 byte unsigned short||
0x0001 – 0xFFFE
0x0000 – unknown
0xFFFF – wild card
|Comp ID||1 byte unsigned short||
0x01 – 0xFE
0x00 – unknown
0xFF – wild card
Fields in the Address can have wild card values of 0xFFFFFFFF or 0xFFFF. The wild card value in a field matches any number of that field. For example, Subsystem ID = 0xFFFFFFFF matches all the subsystems. By the same token, Node ID = 0xFFFF matches all the nodes and Component ID = 0xFF matches all the components. The wild card is useful to broadcast messages to all the subsystems, nodes, and components.
The graph below shows the relationships between subsystems, nodes, components, services, state machine, messages, and internal events. The component address (254, 1, 33) implements a client service of the mobility driver. The component accesses the mobility drive service implemented in the component address (10, 2, 33).
A service may have resources accessible by other means than Uli SDK’s messaging. For example: A video service provides rtsp streams that clients may access the streams using video playbacks.
Services can register resources to the Subsystem Manager, where clients are able to discovery them.
1.11 Subsystem Manager
A component in the Subsystem Node is designated as Subsystem Manager, which has a registry that keeps records of 1) services and 2) resources of components in all nodes of this subsystem. The Subsystem Manager component also includes Status Monitor service, that monitors the status from all the components in the subsystem.
The Subsystem Manager is responsible for assign ID to the nodes that does not have a static ID. The Node Manager service requests ID once received Subsystem Manager Ready messages.
The Node that hosts Subsystem Manager always has static Node ID=1.
1.12 Node Manager
A component in a node is designated as Node Manager, which is assigned with component ID=1. The Node Manager is responsible for routing messages on the behalf of the components in the node.
The Node Manager uses UDP to communicate with other nodes and subsystems. Internally, the Node Manager uses Local Socket for communicating with the components in the node.
1.13 Message Format
A message consists of two field: Header and Payload:
Uli SDK uses Cap’n Proto, https://capnproto.org/, to encode/decode messages.
|1||Uuid||8 byte||Message identifier|
|2||Partition||string||Partition where the message belongs to|
|3||Acknak||1 byte, unsigned integer||0 = no ack, 1=ack needed, 2=ack message|
|4||Priority||1 byte, unsigned integer|
|5||Message ID||8 byte, unsigned integer||Identifier of the schema of the message|
|6||Sender ID||8 byte, Comp Address|
|7||Receiver ID||8 byte, Comp Address|
|8||Acquire Time||8 byte, unsigned integer||Count in nano second since Epoch|
|9||Publish Time||8 byte, unsigned integer||Count in nano second since Epoch|
The universal identifier of this message.
Identifier of the partition the message should be processed. Components that belong to a partition, only process messages for the partition.
This feature allows reconfiguration of nodes and components without reconfiguring the network.
Indication whether ack message is requested.
Currently, only one level.
Identifies the schema of the message encoded in the payload.
The component address where message is sent. The address can be all 0’s that indicates the component address of the sender is not yet assigned.
Payload is the structure of the message. When a message is received, Message ID from header is decoded and the schema of the message is identified. The payload then decoded.
A message is sent to receiver components specified by the receiver address tuple in the message header. Using wild-card, the message can be sent to more than one receivers. Here are different options:
No wild-card in the receiver address. The message is sent to the component whose address is specified by the receiver ID field of the message.
The receiver ID in message header has specific Subsystem ID and Node ID, but component ID is wild-card. For example: (3, 2, 0xFFFF) that the message is sent to all components in the Node ID=2 and Subsystem ID=3.
The receiver ID in message header has specific Subsystem ID, but Node ID is wild-card. For example: (3, 0xFFFF, 0xFF) to all the nodes and components in the subsystem ID=3, and the address (3, 0xFFFF, 1) is destinated to the Node Manager of all the nodes in the subsystem ID=3.
The receiver ID in the message header has wild-card Subsystem ID. For example: (0xFFFFFFFF, 1, 1) to Subsystem Managers of all the Subsystems.
1.15 Dynamic ID Assignment
1.15.1 Subsystem ID assignment
The subsystem ID can be assigned statically that the Subsystem Manager is configured with a pre-determined subsystem ID.
The subsystem ID can be also assigned dynamically that Subsystem Manager globally broadcasts ID Request messages to ID Allocator. The ID Request messages contains unique identifier (UUID) for the request.
The ID Allocator responses by global-broadcasting ID Granted messages that contains valid subsystem ID for that Subsystem and the unique identifier of the request from the Subsystem Manager.
Once having resolved the ID, regardless static or dynamic, Subsystem Manager periodically subsystem-broadcasts Subsystem Ready with valid subsystem ID to all the nodes of the subsystem.
In the case that Subsystem Manager dynamically obtained its ID, it needs to periodically Query Allocated ID to the ID Allocator. The Subsystem Manager checks if its ID is valid on the Report Allocated ID from the ID Allocator.
Refer to Uli SDK Users’ Guide for details of the activities.
1.15.2 Node ID assignment
The node ID can be assigned statically that the Node Manager is configure with a pre-determined node ID.
The node ID can be also assigned dynamically that Node Manager sends Node ID Request messages to the Subsystem Manager after received Subsystem Manager Ready. Subsystem Manager responses by subsystem-broadcasting Node ID Allocate messages that contains valid node ID for that Node Manager.
Node Manager periodically node-broadcasts Node Manager Ready with valid node ID to the components in its node once it obtained valid node ID.
Similarly, in the case that a Node Manager, that obtains its ID dynamically, stops receiving Subsystem Manager Ready for the period of ID Allocator Timeout, it should forget the obtained Node ID and begins the process of requesting for Node ID again. Also, since the Node Manager does not have valid ID, it should stop broadcasting Node Manager Ready messages.
Without receiving Node Manager Ready, Component Transport service of a component should not send or process received messages.
Refer to Uli SDK Users’ Guide for details of the activities.