syntax = "proto2";


/**
 * Mapping between Trezor wire identifier (uint) and a protobuf message
 */
enum MessageType {
    MessageType_Initialize = 0;
    MessageType_Ping = 1;
    MessageType_Success = 2;
    MessageType_Failure = 3;
    MessageType_WipeDevice = 5;
    MessageType_FirmwareErase = 6;
    MessageType_FirmwareUpload = 7;
    MessageType_FirmwareRequest = 8;
    MessageType_Features = 17;
    MessageType_ButtonRequest = 26;
    MessageType_ButtonAck = 27;
    MessageType_GetFeatures = 55;
    MessageType_UnlockBootloader = 96;
}

/**
 * Request: Reset device to default state and ask for device details
 * @start
 * @next Features
 */
message Initialize {
}

/**
 * Request: Ask for device details (no device reset)
 * @start
 * @next Features
 */
message GetFeatures {
}

/**
 * Response: Reports various information about the device
 * @end
 */
message Features {
    optional string vendor = 1;                 // name of the manufacturer, e.g. "trezor.io"
    required uint32 major_version = 2;          // major version of the firmware/bootloader, e.g. 1
    required uint32 minor_version = 3;          // minor version of the firmware/bootloader, e.g. 0
    required uint32 patch_version = 4;          // patch version of the firmware/bootloader, e.g. 0
    optional bool bootloader_mode = 5;          // is device in bootloader mode?
    optional string device_id = 6;              // device's unique identifier
    optional string language = 9;               // device language
    optional string label = 10;                 // device description label
    optional bool initialized = 12;             // does device contain seed?
    optional bytes revision = 13;               // SCM revision of firmware
    optional bool firmware_present = 18;        // is valid firmware loaded?
    optional string model = 21;                 // device hardware model
    optional uint32 fw_major = 22;              // reported firmware version if in bootloader mode
    optional uint32 fw_minor = 23;              // reported firmware version if in bootloader mode
    optional uint32 fw_patch = 24;              // reported firmware version if in bootloader mode
    optional string fw_vendor = 25;             // reported firmware vendor if in bootloader mode
    // optional bytes fw_vendor_keys = 26;      // obsoleted, use fw_vendor
    optional string internal_model = 44;        // internal model name
    optional uint32 unit_color = 45;          // color of the unit/device
    optional bool unit_btconly = 46;          // unit/device is intended as bitcoin only
    optional bool bootloader_locked = 49;       // bootloader is locked
    optional uint32 unit_packaging = 51;      // unit/device packaging version
}

/**
 * Request: Test if the device is alive, device sends back the message in Success response
 * @start
 * @next Success
 */
message Ping {
    optional string message = 1 [default=""];   // message to send back in Success message
}

/**
 * Response: Success of the previous request
 * @end
 */
message Success {
    optional string message = 1 [default=""]; // human readable description of action or request-specific payload
}

/**
 * Response: Failure of the previous request
 * @end
 */
message Failure {
    optional FailureType code = 1;  // computer-readable definition of the error state
    optional string message = 2;    // human-readable message of the error state
    enum FailureType {
        Failure_UnexpectedMessage = 1;
        Failure_DataError = 3;
        Failure_ActionCancelled = 4;
        Failure_ProcessError = 9;
    }
}

/**
 * Response: Device is waiting for HW button press.
 * @auxstart
 * @next ButtonAck
 */
message ButtonRequest {
    optional ButtonRequestType code = 1;
    /**
    * Type of button request
    */
    enum ButtonRequestType {
        ButtonRequest_Other = 1;
    }
}

/**
 * Request: Computer agrees to wait for HW button press
 * @auxend
 */
message ButtonAck {
}

/**
 * Request: Ask device to erase its firmware (so it can be replaced via FirmwareUpload)
 * @start
 * @next FirmwareRequest
 */
message FirmwareErase {
    optional uint32 length = 1; // length of new firmware
}

/**
 * Response: Ask for firmware chunk
 * @next FirmwareUpload
 */
message FirmwareRequest {
    required uint32 offset = 1; // offset of requested firmware chunk
    required uint32 length = 2; // length of requested firmware chunk
}

/**
 * Request: Send firmware in binary form to the device
 * @next FirmwareRequest
 * @next Success
 * @next Failure
 */
message FirmwareUpload {
    required bytes payload = 1; // firmware to be loaded into device
    optional bytes hash = 2;    // hash of the payload
}

/**
 * Request: Unlock bootloader, !irreversible!
 * @start
 * @next Success
 * @next Failure
 */
message UnlockBootloader {
}