191 lines
10 KiB
Markdown
191 lines
10 KiB
Markdown
# PixelHub Protocol Documentation
|
|
> Version 0.1
|
|
|
|
The _PixelHub Protocol_ is a communication protocol for WiFi-capable [Hull PixelBots](http://hullpixelbot.com/hullpixelbot/2017/02/01/welcome-to-hullpixelbot.html) to communicate with and be controlled by a remote server. While the protocol is binary, it is designed to be fairly easy to parse and implement.
|
|
|
|
|
|
## Basic Information
|
|
The PixelHub Protocol is conducted over a single TCP connection. Obtaining these details can be done automatically by listening to the UDP multicast beacon set up by the server.
|
|
|
|
In this specification document, when referring to bytes, The C++ notation will be used. Examples: `0b00000000`, `0b01010101`.
|
|
|
|
Each PixelHub message is terminated by a null byte (`0b00000000`).
|
|
|
|
The current `Protocol Version` is `1`.
|
|
|
|
## Conversation Flow
|
|
|
|
- [ Hub -> Bot ]: Send instruction
|
|
- [ Bot -> Hub ]: Acknowledge instruction
|
|
- [ Bot ]: Execute command
|
|
- [ Bot -> Hub ]: Notify about instruction completion
|
|
|
|
|
|
## Message Struture
|
|
|
|
### Basic Message Structure
|
|
This is the basic structure of a PixelHub Protocol message. The labels are explained below:
|
|
|
|
```
|
|
+------------+------------+------------+------------+
|
|
| Byte 1 | Byte 2 | Byte 3 | Byte 4 |
|
|
+------------+------------+------------+------------+
|
|
| ushort Protocol Version | ushort Message Type |
|
|
+-------------------------+-------------------------+
|
|
| uint Message Id |
|
|
+---------------------------------------------------+
|
|
| uint Message Length |
|
|
+---------------------------------------------------+
|
|
| byte[] Message Contents |
|
|
+---------------------------------------------------+
|
|
| byte null |
|
|
+------------+
|
|
```
|
|
|
|
- `ushort` Protocol Version - The pixelhub protocol version, as an unsigned short, that is being spoken. Either the server _or_ the client reserve the right to kill any connections (and optionally send an incorrect protocol version packet) to any parties not speaking their protocol version.
|
|
- `ushort` Message Type - The type of message, as an unsigned short, of message that is being sent. The values for this may be mapped into an enum.
|
|
- `uint` Message Id - The message id, as an unsigned integer. Should be randomly generated. Message replies must contain instead the id to of the message they are replying to.
|
|
- `uint` Message Length - The length of the following message contents, in 8 bit bytes.
|
|
- `byte[]` Message Contents - The content of the message that has been sent. Once the message itself has been parsed, the body can be extracted and passedto the appropriate handler for parsing.
|
|
- `byte` null - A single null byte (`0b00000000`). This signifiest he end o the message. Even though it's technically not needed because of the _Message Length_ included above, it's been added anyway to simplify initial parsing and message end detection.
|
|
|
|
### Error: When bots complain
|
|
This message doesn't have a body, but is a direct response to a message that the sending party recieved that it didn't like.
|
|
|
|
|
|
### HandshakeRequest: Beginning a handshake
|
|
In the PixelHub protocol, handshakes are initiated by the client, and completed by the server. The server may close a connection if it hasn't received a handshake within a given length of time (the server can decide on this, but it shouldn't be less than 5 seconds).
|
|
|
|
```
|
|
+------------+------------+------------+------------+
|
|
| Byte 1 | Byte 2 | Byte 3 | Byte 4 |
|
|
+------------+------------+------------+------------+
|
|
| char* PixelBot Type |
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
|
|
```
|
|
|
|
- `char*` PixelBot Type - The type of pixelbot sending the handshake request. This should be an array of characters, terminated by a null character. It shouldn't be more than 32 characters in length.
|
|
|
|
|
|
### HandshakeResponse: Completing a handshake
|
|
The counterpart to the above is the `HandshakeResponse` message. It's a direct response to a `HandshakeRequest` message, and is documented below:
|
|
|
|
```
|
|
+------------+------------+------------+------------+
|
|
| Byte 1 | Byte 2 | Byte 3 | Byte 4 |
|
|
+------------+------------+------------+------------+
|
|
| uint Id |
|
|
+---------------------------------------------------+
|
|
```
|
|
|
|
- `uint` Id - The id that the PixelHub server is assigning to the PixelBot.
|
|
|
|
|
|
### Move: Asking a PixelBot to move
|
|
From here on only the _Message Content_ will be displayed in the diagrams. It must be wrapped in the [Basic Message](#Basic Message) structure described above.
|
|
|
|
Asking a PixelBot to move is done quite simply. A pixelbot can either move forward or backwards, or turn left or right on the spot. This is evident in the movement command syntax, shown below:
|
|
|
|
Message Type: `20`
|
|
|
|
```
|
|
+------------+------------+------------+------------+
|
|
| Byte 1 | Byte 2 | Byte 3 | Byte 4 |
|
|
+------------+------------+------------+------------+
|
|
| byte | |
|
|
| Movement | ushort Tick Count |
|
|
| Type | |
|
|
+------------+-------------------------+
|
|
```
|
|
|
|
- `byte` Movement Type - The type of movement that should be made. See the [Movement Types](#Movement Types) table below.
|
|
- `ushort` Tick Count - The number of ticks that the movement should be made for.
|
|
|
|
|
|
#### Movement Types
|
|
|
|
Type | Name | Description
|
|
-------:|-----------|-------------
|
|
0 | Stop | No movement at all.
|
|
1 | Forwards | Moving forwards.
|
|
2 | Backwards | Moving backwards.
|
|
3 | Left | Turning left.
|
|
4 | Right | Turning right.
|
|
|
|
|
|
### CommandOk: When the PixelBot is ok with a command
|
|
This message doesn't have a body, but it is sent by a PixelBot to say that it is going to perform the command that was sent previously.
|
|
|
|
This message is a direct response to a `Move` command.
|
|
|
|
|
|
### CommandComplete: When a PixelBot completes a command
|
|
This message doesn't have a body, but is sent by a PixelBot when it finished executing a `Move` command. It should be in direct response the `Move` command sent by the server.
|
|
|
|
|
|
### CommandFailed: PixelBot Complaints
|
|
This message doesn't have a body, but it's sent by PixelBots who can't complete an instruction they've been given. It should be in direct response to the `Move` command that it is complaining about.
|
|
|
|
|
|
### InfoRequest: Requesting information
|
|
An `InfoRequest` can be used by the server to request information from the client. Information held by a PixelBot is accessed by the server in a key / value format. All keys and values are formatted as a `char*` - the server needs to parse the result sent by the PixelBot into the appropriate type. It does have a body, and it is formatted like this:
|
|
|
|
```
|
|
+------------+------------+------------+------------+
|
|
| Byte 1 | Byte 2 | Byte 3 | Byte 4 |
|
|
+------------+------------+------------+------------+
|
|
| char* Key |
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
|
|
```
|
|
|
|
- `char*` Key - The key. Must not contain a null byte - there's one at the end of the message.
|
|
|
|
|
|
### InfoResponse: Responding with information
|
|
The response to an `InfoRequest`. Must be in direct reply to the `InfoRequest` that it is responding to. The possible keys and values are detailed in the [keys and values](#Information keys and values) section.
|
|
|
|
```
|
|
+------------+------------+------------+------------+
|
|
| Byte 1 | Byte 2 | Byte 3 | Byte 4 |
|
|
+------------+------------+------------+------------+
|
|
| char* Value |
|
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
|
|
```
|
|
|
|
- `char*` Value - The value that corresponds to the key requested in the `InfoRequest`. Numbers should be converted to their string representation - i.e. converted to ASCII / UTF8. Must not contain a null byte - there's one at the end of the message.
|
|
|
|
|
|
## Information keys and values
|
|
Information requests enable the server to request several different pieces of information from a PixelBot.
|
|
|
|
Key | Value description
|
|
------------------------|-------------------
|
|
`Id` | The PixelBot's unique id.
|
|
`TicksTravelled` | The number of ticks that the PixelBot has been moving for.
|
|
`LastMoveDirection` | The direction that the PixelBot last moved in. See the [Movement Types](#Movement Types) section.
|
|
`LastMoveDuration` | The duration that the PixelBot last moved for in ticks.
|
|
`PixelBotType` | The type of PixelBot that this bot is. SHould be the same character array from the `HandshakeRequest`.
|
|
`TicksPerRevolution` | The number of ticks that this PixelBot needs in order to do one ful revolution of it's wheels.
|
|
|
|
If a key is not found, then a blank `InfoResponse` must be returned.
|
|
|
|
|
|
## Message Types
|
|
Message types, as briefly described in the [Basic Message Structure](#Basic Message Structure), are represented as an unsigned short number. All the possible message types are documented below:
|
|
|
|
Type | Name | Description
|
|
-------:|-------------------|-------------
|
|
0 | Reset | Hard-resets the PixelBot. Useful if something has gone wrong, or to reset it's internal state.
|
|
1 | Error | May be sent by either party. Indicates that one or the other doesn't like a message that was sent by the other party.
|
|
5 | HandshakeRequest | Sent by a PixelBot upon connection.
|
|
6 | HandshakeResponse | Sent by the server in response to a `HandshakeRequest`.
|
|
11 | Move | Instructs a PixelBot to perform a movement.
|
|
12 | CommandOk | Sent by a pixelbot to indicate that the command sent by the server is ok, and that it will proceed to execute it.
|
|
13 | CommandComplete | Sent by a pixelbot to indicate that it has completed executing the command sent previously.
|
|
14 | CommandFailed | Sent by a pixelbot to indicate that it has failed to complete the execution of a command it received previously.
|
|
20 | InfoRequest | Sent by the server to request information from a PixelBot. This could be from sensors, configuration, statistics, etc.
|
|
21 | InfoResponse | Sent by a PixelBot in response to an `InfoRequest` message.
|
|
|
|
Note that a status message isn't actually contained in this protocol. This is becaue it is rather awkward to respond to network messages in the middle of a movement, so it will always be something along the lines of 'idle'.
|
|
|