This repository has been archived on 2019-06-21. You can view files and clone it, but cannot push or open issues or pull requests.
PixelHub/PixelHub Protocol.md

209 lines
11 KiB
Markdown
Raw Permalink Normal View History

2017-02-12 21:32:33 +00:00
# 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.
2017-02-13 20:52:30 +00:00
2017-02-12 21:32:33 +00:00
## 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`.
2017-02-13 20:52:30 +00:00
2017-02-12 21:32:33 +00:00
## Conversation Flow
- [ Hub -> Bot ]: Send instruction
- [ Bot -> Hub ]: Acknowledge instruction
- [ Bot ]: Execute command
- [ Bot -> Hub ]: Notify about instruction completion
2017-02-13 20:52:30 +00:00
2017-02-12 21:32:33 +00:00
## Message Struture
2017-02-13 20:52:30 +00:00
### 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
Error messages are in direct response to a message that the sending party recieved that it didn't like. The body is optional, but if specified, should contain the following:
```
+------------+------------+------------+------------+
| Byte 1 | Byte 2 | Byte 3 | Byte 4 |
+------------+------------+------------+------------+
| uint Error Code |
+---------------------------------------------------+
| char* Error Message |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
```
- `uint` Error Code - The code attached to the error message. Error codes are a positive integer. Numbers 1-10000 are reserved for the server. See the error code section at the end of this document.
- `char*` Error Message - Additional human-readable details about the error in question that has occurred. May be empty, especially if the server is complaining to the client, as the client probably won't have anything to do with it unless it's being debugged.
2017-02-13 20:52:30 +00:00
### 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`
2017-02-12 21:32:33 +00:00
```
2017-02-13 20:52:30 +00:00
+------------+------------+------------+------------+
| Byte 1 | Byte 2 | Byte 3 | Byte 4 |
+------------+------------+------------+------------+
| byte | |
| Movement | ushort Tick Count |
| Type | |
+------------+-------------------------+
2017-02-12 21:32:33 +00:00
```
2017-02-13 20:52:30 +00:00
- `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.
2017-02-14 20:44:28 +00:00
2017-02-13 20:52:30 +00:00
### 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
2017-02-14 20:44:28 +00:00
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.
2017-02-13 20:52:30 +00:00
## 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.
2017-02-26 19:56:43 +00:00
5 | HandshakeRequest | Sent by a PixelBot upon connection.
6 | HandshakeResponse | Sent by the server in response to a `HandshakeRequest`.
2017-02-13 20:52:30 +00:00
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'.
2017-02-12 21:32:33 +00:00
## Error Codes
It's highly likely that an error will occur sooner or later. In the PixelHub protocol, all errors have their own number, where no number is ever thrown in the same place in the code base twice, allowing for errors to be reliably traced back ot their source without a usable stack trace. The following caregories of error have been assigned:
- 0 - A general error. Please try not to use this if at all possible.
- 1-9,999 - Server errors.
- 10,00-19,999 - PixelBot errors.