Class DsUploadReceiver

java.lang.Object
frc.spectrumLib.telemetry.DsUploadReceiver

public final class DsUploadReceiver extends Object
Receives files the Driver Station laptop pushes after a match: its DS log, and audio and video recorded at the driver station. They land in <log folder>/ds/, and the pit laptop pulls them with the match log.

Protocol v1 (the MatchReview helper's DS-laptop mode is the client), HTTP/1.1 on port 5806, header X-MatchReview-Token on every request:

  • PUT /upload/<kind>/<name>?offset=<n>&total=<N> appends one chunk.
  • HEAD /upload/<kind>/<name> returns X-Received (bytes so far, 0 for none) and X-Complete, so a push cut off by the robot powering down resumes at the next pit tether. A 404 here means robot code without this protocol.
  • PUT /dslog/<name> takes a whole NI DS log in one body (the helper's first version).

Extend (dslog and dswpilog only). The DS keeps appending to its session log, so after each match the file the robot finished last time is a prefix of the one to send. HEAD on a finished file of those kinds adds X-Sha256-Prefix-Supported: 1. The client may then send PUT /upload/<kind>/<name>?offset=<n>&total=<N>&extend=1 with X-Prefix-Sha256: <hex SHA-256 of its first n bytes>, where n is the finished file's length and N > n. If the robot's file hashes the same, it becomes the partial copy and the chunk is appended; later chunks are plain offset PUTs. Otherwise the reply is 409 with X-Extend: mismatch, and the client sends the whole file from offset 0.

The field gives each team about 7 Mbps, so a push only happens after the match, while the robot is disabled. Uploads are refused while it is enabled, and one under way when it enables stops at the next 64 KiB, keeps what arrived and closes, so the client resumes later. A small pool of threads serves connections, so one idle or slow client cannot hold up the rest. The threads only write files and never touch robot state, so replay is unaffected. Counters reach the log through periodic(boolean) on the main thread.

A 2027 DS log is stored as <name>.dswpilog: pit helpers from before this protocol take any .wpilog they find for a robot log and upload it to the public log site.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
     
    static final String
     
    static final String
     
  • Method Summary

    Modifier and Type
    Method
    Description
    static void
    main(String[] args)
    Runs a receiver on a laptop, for bench tests and the MatchReview client's tests: <folder> <token> <port> (port 0 picks one).
    static void
    periodic(boolean enabled)
    Passes the robot's enabled state to the receiver and logs its counters.
    static void
    start(String logFolder)
    Starts the receiver on a daemon thread, writing to <logFolder>/ds.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Method Details

    • main

      public static void main(String[] args) throws IOException
      Runs a receiver on a laptop, for bench tests and the MatchReview client's tests: <folder> <token> <port> (port 0 picks one). Prints listening <port>. Lines on stdin: enabled / disabled set the robot state (it starts disabled).
      Parameters:
      args - folder, token, port
      Throws:
      IOException - if the port cannot be opened
    • start

      public static void start(String logFolder)
      Starts the receiver on a daemon thread, writing to <logFolder>/ds. Does nothing (and raises an info alert) when the token file is missing. Call during robot init, before the main thread goes real-time: the accept thread and the connection pool are created here, at minimum priority, and never later.
      Parameters:
      logFolder - the folder the robot logs to
    • periodic

      public static void periodic(boolean enabled)
      Passes the robot's enabled state to the receiver and logs its counters. Call every loop.
      Parameters:
      enabled - whether the robot is enabled this loop