Magnemite
Development

The wire protocol

What travels over the device socket, in both directions.

One WebSocket per box, opened by the box, authenticated with its device token. The message set is small on purpose — it is implemented twice, in packages/protocol and in Go under agent/.

Box → hub

MessageWhen
helloOn connect: serial, model, Android version, installed Pokémon GO version, free space
heartbeatPeriodically, carrying the same live facts
job_progressDownload percentage, install phase, log lines
job_resultSuccess or failure, with the verified version and whether data was wiped
agent_update_resultOnly on failure: the self-update did not happen, and why
log_bundle_resultOnly on failure: the log bundle was not collected or uploaded
log_linesA batch of live logcat lines, and how many were dropped keeping up
exec_resultWhat a one-off command printed, and whether it worked
pongAnswering a ping

Hub → box

MessageWhen
welcomeAccepting the socket
install_jobArtifact URL, sha256, target version, hooks, flags
cancel_jobYou cancelled it, or the scheduler re-queued it
rebootFrom the device page
agent_updateA newer agent build is available
collect_logsZip the logs and upload them to this URL
log_stream_startFollow logcat, or a file, for this many seconds
log_stream_stopNobody is watching any more
exec_commandRun this shell command as root and say what it printed
pingLiveness

Properties worth knowing

  • The box always dials out. Nothing initiates a connection towards a box, which is why no ports are open on the LAN and CGNAT is irrelevant.
  • Jobs are idempotent by version. A box already on the target version reports success without installing anything.
  • Progress is advisory, absence is not. JOB_STALL_TIMEOUT seconds with no job_progress is what makes the hub re-queue a job — a box unplugged mid-install never sends a failure.
  • Downloads do not use the socket. The bundle comes over plain HTTPS from the edge with a Range header, so an interrupted download resumes and the socket stays free for control messages.

Changing it

Change packages/protocol, mirror it in Go, and remember that a fleet updates its agents on its own schedule: a hub must keep understanding the previous message set until every box has taken an agent_update.

On this page