preprintd 0.2.5

Printer swarm-worker daemon implementation for PreConnect.
preprintd-0.2.5 is not a library.

preprintd

Printer swarm-worker daemon implementation for PreConnect.

Overview

This tiny worker is just a TcpStream under the hood, constantly listening for jobs and claiming one if open. It works by constantly listening for incoming data from the api.preconnect.app endpoint (which uses Mercure under the hood for streaming real-time data), and then initiating the claiming procedure.

Compiling

Requires Rust (2024 edition or later) to be installed.

Run the traditional release command:

cargo build --release

[!NOTE] The release binary is optimized for the smallest-possible size, although you can change this behavior by disabling the optimizations specified in the [profile.release] section of Cargo.toml.

Prebuilt Binaries

See the GitHub Releases for a prebuilt binary for either Windows, Linux (built via CI workers running Ubuntu), or macOS.

Daemon Usage

Create a new systemd service which you can enable later:

sudo nano /etc/systemd/system/preprintd.service

Write the following INI configuration in your preprintd.service file. Make sure to replace the following things as well:

  1. Under Environment=:
  • WORKER_KEY: Your worker key credential (from the PreConnect API).
  • AGENT: Agent name to use for outbound requests.
  • DEF_HOST: The default printer host to use in case the API cannot provide one.
  • DEF_QUEUE: The default queue name to send printable data to.
  1. Under User, replace username with the username you're logged in with on your local machine.
[Unit]
Description=PreConnect Printer Worker Daemon
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/preprintd --debug
Restart=always
Environment="WORKER_KEY=yourworkerkeyhere" "AGENT=preprintd" "DEF_HOST=192.168.0.102" "DEF_QUEUE=queuename"
User=username

[Install]
WantedBy=multi-user.target

Enable and start it once you're done:

sudo systemctl daemon-reload
sudo systemctl enable preprintd.service
sudo systemctl start preprintd.service

# now check status:
systemctl status preprintd.service

To check the logs in real-time, run:

journalctl -u preprintd.service -f

Code Inspection

When you're going through the code, you'll see these:

  • Some decode_b64_string() calls - those are primarily for obfuscation needs but since the inner value is Base64-encoded, you can easily use a decoder to decouple the values underneath. One such tool that you can use is this.
  • The standard LPR/LPD sequence (except the code doing HTTP requests via reqwest's blocking API and every other code surrounding/using this logic).
  • LOTS of LazyLock usage. ALthough this is not optimal for a program that's supposed to be tiny, we've kept this pattern to reuse as much data as physically possible without hardcoding and messing up.

Mercure SSE Connection Protocol

preprintd streams real-time job notifications from the Mercure Hub (/.well-known/mercure).

  1. Endpoint: https://api.preconnect.app/.well-known/mercure?topic=https%3A%2F%2Fpreconnect.app%2Fprinter
  2. Authorization: Bearer <subscriber-jwt>
    • The subscriber JWT is created by signing {"mercure":{"subscribe":["https://preconnect.app/printer"]}} with HMAC-SHA256 using WORKER_KEY.
  3. Replay Support: On reconnect, pass the Last-Event-ID header containing the last id: value received from the stream to receive any missed jobs.

Reference Implementation

See: https://github.com/sabbirba/preconnect/blob/main/printer.py (courtesy: @sabbirba)

License

Licensed under the GNU General Public License v3.