# Host2Hub File Sync Protocol

### Packet Format

Each packet starts with a one byte long identifier followed by the arguments. The end of the packet is signalized by a **SUB** (0x1A) byte. (This is subject to change and will likely be replaced by a **NUL** (0x00) byte in the future. The different packets are listed below.

Generally, the host sends a packet to the hub and the hub responds. The only cases in which the hub actively sends a packet are if it reports an error or delivers a print message.

### Packet Types

The Host can send these Packets, the Hub must handle these packets:

<table border="1" id="bkmrk-identifier-type-mean" style="border-collapse: collapse; width: 100%; height: 417.2px;"><colgroup><col style="width: 9.41597%;"></col><col style="width: 11.9178%;"></col><col style="width: 45.2931%;"></col><col style="width: 33.3731%;"></col></colgroup><tbody><tr style="height: 29.8px;"><td style="height: 29.8px;">Identifier</td><td style="height: 29.8px;">Type</td><td style="height: 29.8px;">Meaning</td><td style="height: 29.8px;">Argmuent</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**Y** (0x59)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Start *SYNC Mode*</td><td style="height: 29.8px;">  
</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**D** (0x44)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Ensure Directory exists</td><td style="height: 29.8px;">/path/to/dir</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**F** (0x46)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Ensure File has same Hash</td><td style="height: 29.8px;">/path/to/file SHA256</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**C** (0x43)</td><td style="height: 29.8px;">Response</td><td style="height: 29.8px;">CHUNK</td><td style="height: 29.8px;">192 Bytes of the file data (base64-encoded compressed file)</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**E** (0x45)</td><td style="height: 29.8px;">Response</td><td style="height: 29.8px;">End Of File</td><td style="height: 29.8px;">  
</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**N** (0x4E)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">End *SYNC Mode*</td><td style="height: 29.8px;">  
</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**R** (0x52)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Remove File or Directory</td><td style="height: 29.8px;">/path/to/file/or/diretory</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**P** (0x50)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Start Program (loop() from /\_\_init\_\_.py)</td><td style="height: 29.8px;">  
</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**X** (0x58)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Stop Program</td><td style="height: 29.8px;">  
</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**&amp;** (0x26)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Reboot</td><td style="height: 29.8px;">  
</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**=** (0x3D)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Sync Communication</td><td style="height: 29.8px;">timestamp</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**&gt;** (0x3E)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Enter REPL</td><td style="height: 29.8px;">  
</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**$** (0x24)</td><td style="height: 29.8px;">Actively Sent</td><td style="height: 29.8px;">Reset State</td><td style="height: 29.8px;">  
</td></tr></tbody></table>

The Hub can send these Packets, the Host must handle these packets:

<table border="1" id="bkmrk-identifier-type-mean-1" style="border-collapse: collapse; width: 100%; height: 352.2px;"><colgroup><col style="width: 9.41597%;"></col><col style="width: 11.9188%;"></col><col style="width: 45.2922%;"></col><col style="width: 33.3731%;"></col></colgroup><tbody><tr style="height: 29.8px;"><td style="height: 29.8px;">Identifier</td><td style="height: 29.8px;">Type</td><td style="height: 29.8px;">Meaning</td><td style="height: 29.8px;">Argmuent</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**K** (0x4B)</td><td style="height: 29.8px;">Response</td><td style="height: 29.8px;">OK</td><td style="height: 29.8px;">  
</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**=** (0x3D)</td><td style="height: 29.8px;">Response</td><td style="height: 29.8px;">Sync Communication</td><td style="height: 29.8px;">given timestamp</td></tr><tr style="height: 29.8px;"><td style="height: 29.8px;">**U** (0x55)</td><td style="height: 29.8px;">Response</td><td style="height: 29.8px;">Request File Contents</td><td style="height: 29.8px;">  
</td></tr><tr style="height: 46.6px;"><td style="height: 46.6px;">**!** (0x21)</td><td style="height: 46.6px;">Actively Sent</td><td style="height: 46.6px;">*Internal Error*</td><td style="height: 46.6px;">traceback</td></tr><tr style="height: 46.6px;"><td style="height: 46.6px;">**E** (0x45)</td><td style="height: 46.6px;">Actively Sent</td><td style="height: 46.6px;">*User Error*</td><td style="height: 46.6px;">traceback</td></tr><tr style="height: 46.6px;"><td style="height: 46.6px;">**P** (0x50)</td><td style="height: 46.6px;">Actively Sent</td><td style="height: 46.6px;">*Print*</td><td style="height: 46.6px;">json-encoded args &amp; kwargs</td></tr></tbody></table>

Packets written in italics are not yet documented below.

### Examples

#### Sync all files

If a full tree needs to be synced to the hub, this is the right choice.

1. Host sends `Y` to start *SYNC Mode.*  
    Hub responds with `K`.
2. Here, Files and Directories are updated.  
    Refer to [Update an individual file](https://bookstack.gsg-robots.de/link/23#bkmrk-update-an-individual) and [Update an individual directory](https://bookstack.gsg-robots.de/link/23#bkmrk-update-an-individual-1).
3. Host sends `N` to stop *SYNC Mode*.  
    Hub responds with `K`.

##### Effect

Upon receiving `N`, the Hub deletes all files and directories that were not updated since `Y` was sent.

#### Update an individual file

1. Host sends `F`. The argument is the file's path and its SHA256 Hash, seperated by a space. The file path needs to start with `/`.  
    Hub responds with `K`, ***or*** with `U`.
2. If `U` was sent, Host repeatedly sends `C` with 192 bytes of the file as argmuent, ***or*** `E` if EOF is reached.  
    Hub responds to each of these packets with `K`. Hub can respond with `U` to `E` if the hash is still not matching.

##### Effect

The Hub checks whether the file exists and has the correct hash. If it is correct, it responds with **K**. Otherwise, it sends **U** and stores the file received in the following **C** packets under the given file path.

#### Update an individual directory

1. Host sends `D` with the file path as argument. The file path needs to start with `/`.  
    Hub responds with `K`.

##### Effect

The Hub ensures the directory exists.

#### Delete an individual file or directory

1. Host sends `R` with the file path as argument. The file path needs to start with `/`.  
    Hub responds with `K`.

##### Effect

The Hub deletes the file or directory found under the given file path if it exists. Non-empty directories are cleared.

#### Start the program

1. Host sends `P`.  
    Hub responds with `K`.

##### Effect

The Hub stops the task it created when it received `P` the last time, if it exists.  
The Hub starts the `loop()` function it found in the `/__init__.py` file by creating a new task using `asyncio`.

#### Stop the program

1. Host sends `X`.  
    Hub responds with `K`.

##### Effect

The Hub stops the task it created when it received `P` the last time, if it exists.

#### Sync connection

1. Host sends `=` with arbitrary data as argument.  
    Hub echos the packet.

##### Effect

Echo. Ping-Pong. Verify connection.

#### Open REPL

1. Host sends `>`.

##### Effect

The Hub stops all running tasks and returns control to the Micropython REPL.

\[OUTDATED: This is to be preferred in comparison to sending Ctrl-C (which also works), as it makes sure the `print()` function works as expected afterwards.\] -&gt; \[NOTE: Ctrl-C should not work\]

#### Reboot Hub

1. Host sends `&`.

##### Effect

The Hub reboots.

#### Cancel sync

1. Host sends `$`.  
    Hub responds with `K`.

##### Effect

The Hub resets its sync state. It is recommended to send this when a new connection is made.