Skip to content
Snippets Groups Projects
Commit 4954c581 authored by Patrick Joos's avatar Patrick Joos
Browse files

Adding packet definition

parent 7c212037
Branches
No related tags found
No related merge requests found
Pipeline #247101 passed
......@@ -4,29 +4,7 @@
An axis is defined as a floating-point value in the range of $[-1, 1]$. This can be used to transmit data e.g. from a joystick, a pedal, a trigger and any other devices that has two distinct start- and endpoints. Meaning, the devices has to be bound by an upper and lower limit.
=== "C"
``` c
#include <stdio.h>
int main(void) {
printf("Hello world!\n");
return 0;
}
```
=== "C++"
``` c++
#include <iostream>
int main(void) {
std::cout << "Hello world!" << std::endl;
return 0;
}
```
Use a JSON boolean type to transfer these types of data values.
This interface is defined in [JSON Schema](https://json-schema.org/) as follows:
```json
{
......
......@@ -6,6 +6,56 @@ In order to accomplish this, devices and games announce their capabilitis/requir
## Capabilities and Requirements
A `Port` is defined as follows:
```json
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "Port",
"type": "object",
"properties": {
"id": {
"description": "Transmits a unique identifier for the port",
"type": "string",
"format": "uuid"
},
"type": {
"description": "Defines what type of port is transmitted",
"enum": ["requirement", "capability"]
},
"interface": {
"description": "Defines what type of interface(data) is transmitted through this port",
"enum": ["tap", "axis", "point", "power", "gesture", "stance", "ray"]
},
"version": {
"description": "Defines the interface version, as given by semantic versioning format",
"type": "string",
"pattern": "(0|[1-9])[0-9]*.(0|[1-9])[0-9]*.(0|[1-9])[0-9]*"
}
},
"required": ["id", "type", "interface", "version"]
}
```
### Example
```json
{
"id": "936DA01F-9ABD-4D9D-80C7-02AF85C822A8",
"type": "requirement",
"interface": "axis",
"version": "1.0.0"
}
```
This example defines a requirement, as in a data receiving port, that expects data of the type [Axis](../interfaces/axis.md).
## Matching Algorithm
Matching is performed either automatically or by a semi-manual process. This can be done on a server-by-server basis and changes by the needs of the developers implementing a server.
In general,
![Signal Matching](../images/RequirementsManagement.png)
If matches are found, the server performs a handshake protocol, announcing to each connected party how they need to send and receive data. Afterwards, the server handles all data traffic between the parties, serving as an intermediary. Because all data travels through the server, it can be captured and later be used to analyze the users performance in the last training session.
......@@ -2,11 +2,88 @@
To actually transmit the defined data, a websocket [@websocket] server is used, which handles both signal matching as well as serving as a proxy for the websocket connections between connected parties.
By definitions, websockets are only able to communicate with one party at a time (though in both directions). Therefore, to connect two unrelated parties, the server needs to receive all data sent by either party and pass them along to the other party.
By definitions, websockets are only able to communicate with one party at a time (though in both directions). Therefore, to connect two unrelated parties, the server needs to receive all data sent by either party and pass them along to the other parties.
For each party, exactly one Websocket-Connection is opened. All data sent over this Websocket has to satisfy the interface in [@fig:packetinterface].
For each party, exactly one Websocket-Connection is opened. All data sent over this Websocket has to satisfy the following [JSON Schema](https://json-schema.org/).
![Packet Interface](../images/packet_interface.png){#fig:packetinterface }
```json
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "packet",
"type": "object",
"properties": {
"meta": {
"description": "Transmits a unique identifier for the port",
"type": "object",
"properties": {
"channel": {
"description": "Identifies the channel on which the data should be transmitted",
"type": "string"
},
"timestamp": {
"description": "Notes the time when this packet was sent from the client",
"type": "integer"
},
"action": {
"description": "Defines what action the package is intended to perform",
"enum": ["emit", "broadcast", "join", "leave", "accept", "reject"]
}
},
"required": ["channel", "timestamp", "action"]
},
"data": {
"description": "Defines what type of port is transmitted",
"enum": ["requirement", "capability"]
}
},
"required": ["meta"]
}
```
This means, that each packet consist of at least a `meta` object. Sending a `data` object is not required (e.g. an administrative packet may not need any data).
The possible `actions` are as follows:
`emit`
: Emit sends the data to all clients that are subscribed to the channel defined in `meta.channel`, excluding the sending client.
`broadcast`
: Broadcast sends the data to all clients that are subscribed to the channel defined in `meta.channel, including the sending client.
`join`
: This action has two functions. When sent from the server to a client, it instructs the client to join the channel defined in `meta.channel`.
If sent from the client, it asks the server to subscribe the client to the channel defined in `meta.channel`. This action will be answered with a packet containing either the `accept` or `reject` action.
`leave`
: This action has two functions. When sent from the server to a client, it instructs the client to leave the channel defined in `meta.channel`.
If sent from the client, it asks the server to deregister the client from the channel defined in `meta.channel`. This action will be answered with a packet containing either the `accept` or `reject` action.
`accept`
: A packet with this action is sent from the server to the client if it was successfully subscribed to the channel defined in `meta.channel`
`reject`
: A packet with this action is sent from the server to the client if the clients request to join the channel defined in `meta.channel` was rejected for any reason. `data` may contain the reason for the rejection, but this is optional and clients may not rely on that information.
### Example
The following `packet` transmits data of type [`Axis`](../interfaces/axis.md) on channel `example-channel`.
```json
{
"meta": {
"channel": "example-channel",
"timestamp": 1676379241165,
"action": "emit"
},
"data": {
"data": "0.2456"
}
}
```
![Packet Interface](../images/packet_interface.png){align=center}
Of special note is the `channel` field in the `meta` object. By setting this parameter, a publisher can send data specifically for this channel. All publishers who have announced their interest in that specific channel will then be notified of the new data.
......
......@@ -4,7 +4,7 @@ site_dir: public
theme:
name: material
nav:
- Home: index.md
- 'Server infrastructure':
......@@ -15,7 +15,8 @@ nav:
- Tap: 'interfaces/tap.md'
- Axis: 'interfaces/axis.md'
markdown_extensions:
markdown_extensions:
- attr_list
- pymdownx.superfences
- pymdownx.tabbed:
alternate_style: true
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment