{
  "description": "The host bridge protocol of 8.2, version 1: frame fields, frame types, control commands, events, update methods, and error codes. tools/ctrl_usb.py injects the tables of 8.2.",
  "version": 1,
  "max_payload": 1024,
  "framing": "Each frame is COBS-encoded and ends with one 0x00 byte; multi-byte fields are little-endian",
  "crc": "CRC-16/CCITT-FALSE (poly 0x1021, init 0xFFFF, no reflection, no final XOR) over every field before it",
  "fields": [
    {
      "name": "ver",
      "bytes": 1,
      "meaning": "Protocol version, 1"
    },
    {
      "name": "chan",
      "bytes": 1,
      "meaning": "0 is the control channel; 1 to 255 are assigned by open or update"
    },
    {
      "name": "type",
      "bytes": 1,
      "meaning": "Frame type, below"
    },
    {
      "name": "seq",
      "bytes": 2,
      "meaning": "Per channel; a reply echoes the request's seq"
    },
    {
      "name": "len",
      "bytes": 2,
      "meaning": "Payload length, at most max_payload"
    },
    {
      "name": "payload",
      "bytes": "len",
      "meaning": "JSON for CTRL and EVENT; bytes for DATA; a u32 byte count for CREDIT"
    },
    {
      "name": "crc",
      "bytes": 2,
      "meaning": "CRC over the fields above"
    }
  ],
  "types": [
    {
      "code": 1,
      "name": "CTRL",
      "meaning": "A request, or the reply to one"
    },
    {
      "code": 2,
      "name": "EVENT",
      "meaning": "Something changed; no reply"
    },
    {
      "code": 3,
      "name": "DATA",
      "meaning": "Bytes for a tunnel or an update"
    },
    {
      "code": 4,
      "name": "CREDIT",
      "meaning": "The receiver grants more bytes on the channel"
    },
    {
      "code": 5,
      "name": "CLOSE",
      "meaning": "The channel ends; on channel 0, bridge mode ends"
    }
  ],
  "commands": [
    {
      "cmd": "hello",
      "fields": [
        "proto"
      ],
      "reply": [
        "proto",
        "host (fw, serial)",
        "ports",
        "maxPayload"
      ],
      "meaning": "The first frame of a session; versions and limits"
    },
    {
      "cmd": "ports",
      "fields": [],
      "reply": [
        "for each port: port, power, mode (app, update, empty), usb (vid, pid, manufacturer, product, serial, classes), last"
      ],
      "meaning": "Each downstream port; last is the product that was on it before it entered update mode"
    },
    {
      "cmd": "open",
      "fields": [
        "port"
      ],
      "reply": [
        "chan"
      ],
      "meaning": "A tunnel: a byte pipe to the product's console interface"
    },
    {
      "cmd": "close",
      "fields": [
        "chan"
      ],
      "reply": [],
      "meaning": "Ends a tunnel or an update"
    },
    {
      "cmd": "update",
      "fields": [
        "port",
        "method",
        "size",
        "sha256",
        "product",
        "and the method's own"
      ],
      "reply": [
        "chan",
        "credit"
      ],
      "meaning": "Streams a firmware image on DATA frames; the method names how the host writes it"
    },
    {
      "cmd": "power_cycle",
      "fields": [
        "port"
      ],
      "reply": [],
      "meaning": "Switches the port's power off and on (USB-013)"
    }
  ],
  "events": [
    {
      "name": "attach",
      "payload": [
        "the port's ports entry"
      ],
      "meaning": "A product appeared on a port"
    },
    {
      "name": "detach",
      "payload": [
        "port"
      ],
      "meaning": "A product left a port"
    },
    {
      "name": "state",
      "payload": [
        "port",
        "mode"
      ],
      "meaning": "A port's mode changed"
    },
    {
      "name": "update",
      "payload": [
        "chan",
        "stage",
        "pct; or stage error with code and message"
      ],
      "meaning": "Progress of an update"
    }
  ],
  "update_methods": [
    {
      "id": "uf2-msc",
      "for": "Any product whose boot loader presents a UF2 mass-storage volume",
      "stages": [
        "PREFLIGHT",
        "ENTER",
        "WAIT_LOADER",
        "CHECK",
        "WRITE",
        "WAIT_APP",
        "VERIFY",
        "DONE"
      ],
      "extra_fields": {
        "family": "UF2 family ID, such as 0xE48BFF59"
      },
      "meaning": "The host asks the product to enter its boot loader, waits for the mass-storage volume on the same port, checks the first UF2 block's family and size, writes each 512-byte block as it arrives, and waits for the product to return with the same iSerial"
    }
  ],
  "errors": [
    {
      "code": "no_module",
      "meaning": "Nothing in app mode on the port"
    },
    {
      "code": "product_mismatch",
      "meaning": "The port's iProduct is not the update's product"
    },
    {
      "code": "no_loader",
      "meaning": "The product did not enter its boot loader"
    },
    {
      "code": "loader_timeout",
      "meaning": "No boot loader appeared on the port"
    },
    {
      "code": "bad_image",
      "meaning": "The image's format, family, or size is wrong"
    },
    {
      "code": "write_failed",
      "meaning": "The host could not write a block"
    },
    {
      "code": "hash_mismatch",
      "meaning": "The streamed image's SHA-256 is not the one announced"
    },
    {
      "code": "no_app",
      "meaning": "The product did not return after the write; the port stays in update mode, recoverable"
    }
  ]
}
