syntax = "proto3";

option go_package = "github.com/opencord/voltha-go/protos/voltha";

package voltha;

import "meta.proto";
import "google/protobuf/any.proto";
import "common.proto";
import "openflow_13.proto";
import "yang_options.proto";


// A Device Type
message DeviceType {

    // Unique name for the device type
    string id = 1;

    // Unique venor id for the device type applicable to ONU
    // 4 bytes of vendor id from ONU serial number
    string vendor_id = 5;

    repeated string vendor_ids = 6;

    // Name of the adapter that handles device type
    string adapter = 2;

    // Capabilitities

    bool accepts_bulk_flow_update = 3;
    bool accepts_add_remove_flow_updates = 4;
    bool accepts_direct_logical_flows_update = 7;

}

// A plurality of device types
message DeviceTypes {
    repeated DeviceType items = 1;
}

message PmConfig {
    enum PmType {
        COUNTER = 0;
        GAUGE = 1;
        STATE = 2;
        CONTEXT = 3;
    }
    string name = 1;
    PmType type = 2;
    bool enabled = 3; // Whether or not this metric makes it to Kafka
    uint32 sample_freq = 4; // Sample rate in 10ths of a second
}

message PmGroupConfig {
    string group_name = 1;
    uint32 group_freq = 2; // Frequency applicable to the grop
    bool enabled = 3; // Enable/disable group level only
    repeated PmConfig metrics = 4;
}

message PmConfigs {
    string id = 1; // To work around a chameleon POST bug
    uint32 default_freq = 2; // Default sample rate
    // Forces group names and group semantics
    bool grouped = 3 [(access) = READ_ONLY];
    // Allows Pm to set an individual sample frequency
    bool freq_override = 4 [(access) = READ_ONLY];
    repeated PmGroupConfig groups = 5; // The groups if grouped is true
    repeated PmConfig metrics = 6; // The metrics themselves if grouped is false.
}

// Describes instance of software image on the device
message Image {
    string name = 1;                // software patch name
    string version = 2;             // version of software
    string hash = 3;                // md5 hash
    string install_datetime = 4;    // combined date and time expressed in UTC.
                                    // use ISO 8601 format for date and time

    // The active software image is one that is currently loaded and executing
    // in the ONU or circuit pack. Under normal operation, one software image
    // is always active while the other is inactive. Under no circumstances are
    // both software images allowed to be active at the same time
    bool is_active = 5;             // True if the image is active

    // The committed software image is loaded and executed upon reboot of the
    // ONU and/or circuit pack. During normal operation, one software image is
    // always committed, while the other is uncommitted.
    bool is_committed = 6;          // True if the image is committed

    // A software image is valid if it has been verified to be an executable
    // code image. The verification mechanism is not subject to standardization;
    // however, it should include at least a data integrity (e.g., CRC) check of
    // the entire code image.
    bool is_valid = 7;              // True if the image is valid
}

// List of software on the device
message Images {
    repeated Image image = 1;
}

message ImageDownload {
    option (yang_child_rule) = MOVE_TO_PARENT_LEVEL;

    enum ImageDownloadState {
        DOWNLOAD_UNKNOWN = 0;
        DOWNLOAD_SUCCEEDED = 1;
        DOWNLOAD_REQUESTED = 2;
        DOWNLOAD_STARTED = 3;
        DOWNLOAD_FAILED = 4;
        DOWNLOAD_UNSUPPORTED = 5;
        DOWNLOAD_CANCELLED = 6;
    }

    enum ImageDownloadFailureReason {
        NO_ERROR = 0;
        INVALID_URL = 1;
        DEVICE_BUSY = 2;
        INSUFFICIENT_SPACE = 3;
        UNKNOWN_ERROR = 4;
        CANCELLED = 5;
    }

    enum ImageActivateState {
        IMAGE_UNKNOWN = 0;
        IMAGE_INACTIVE = 1;
        IMAGE_ACTIVATE = 2;
        IMAGE_ACTIVE = 3;
        IMAGE_REVERT = 4;
    }

    // Device Identifier
    string id = 1;

    // Image unique identifier
    string name = 2;

    // URL where the image is available
    // should include username password
    string url = 3;

    // CRC of the image to be verified aginst
    uint32 crc = 4;

    // Download state
    ImageDownloadState download_state = 5;

    // Downloaded version
    string image_version = 6;

    // Bytes downloaded
    uint32 downloaded_bytes = 7;

    // Download failure reason
    ImageDownloadFailureReason reason= 8;

    // Additional info
    string additional_info = 9;

    // Save current configuration
    bool save_config = 10;

    // Image local location
    string local_dir = 11;

    // Image activation state
    ImageActivateState image_state = 12;
    
    // Image file size
    uint32 file_size = 13;
}

message ImageDownloads {
    repeated ImageDownload items = 2;
}

message Port {
    option (voltha.yang_child_rule) = MOVE_TO_PARENT_LEVEL;

    enum PortType {
        UNKNOWN = 0;
        ETHERNET_NNI = 1;
        ETHERNET_UNI = 2;
        PON_OLT = 3;
        PON_ONU = 4;
        VENET_OLT = 5;
        VENET_ONU = 6;
    }

    uint32 port_no = 1;  // Device-unique port number

    string label = 2;  // Arbitrary port label

    PortType type = 3;  //  Type of port

    AdminState.AdminState admin_state = 5;

    OperStatus.OperStatus oper_status = 6;

    string device_id = 7;  // Unique .id of device that owns this port

    message PeerPort {
        string device_id = 1;
        uint32 port_no = 2;
    }
    repeated PeerPort peers = 8;

    fixed64 rx_packets = 9;
    fixed64 rx_bytes = 10;
    fixed64 rx_errors = 11;
    fixed64 tx_packets = 12;
    fixed64 tx_bytes = 13;
    fixed64 tx_errors = 14;

}

message Ports {
    repeated Port items = 1;
}

// A Physical Device instance
message Device {
    option (voltha.yang_child_rule) = MOVE_TO_PARENT_LEVEL;

    // Voltha's device identifier
    string id = 1 [(access) = READ_ONLY];

    // Device type, refers to one of the registered device types
    string type = 2 [(access) = READ_ONLY];

    // Is this device a root device. Each logical switch has one root
    // device that is associated with the logical flow switch.
    bool root = 3 [(access) = READ_ONLY];

    // Parent device id, in the device tree (for a root device, the parent_id
    // is the logical_device.id)
    string parent_id = 4 [(access) = READ_ONLY];
    uint32 parent_port_no = 20 [(access) = READ_ONLY];

    // Vendor, version, serial number, etc.
    string vendor = 5 [(access) = READ_ONLY];
    string model = 6 [(access) = READ_ONLY];
    string hardware_version = 7 [(access) = READ_ONLY];
    string firmware_version = 8 [(access) = READ_ONLY];
    // List of software on the device
    Images images = 9 [(access) = READ_ONLY];
    string serial_number = 10 [(access) = READ_ONLY];
    string vendor_id = 24 [(access) = READ_ONLY];

    // Addapter that takes care of device
    string adapter = 11 [(access) = READ_ONLY];

    // Device contact on vlan (if 0, no vlan)
    uint32 vlan = 12;

    message ProxyAddress {
        string device_id = 1;  // Which device to use as proxy to this device
        string device_type = 2; // The device type of the proxy device to use as the adapter name
        uint32 channel_id = 3;  // Sub-address within proxy
        uint32 channel_group_id = 4; // Channel Group index
        string channel_termination = 5; // Channel Termination name
        uint32 onu_id = 6; // onu identifier; optional
        uint32 onu_session_id = 7; // session identifier for the ONU; optional
    };

    oneof address {
        // Device contact MAC address (format: "xx:xx:xx:xx:xx:xx")
        string mac_address = 13;

        // Device contact IPv4 address (format: "a.b.c.d" or can use hostname too)
        string ipv4_address = 14;

        // Device contact IPv6 address using the canonical string form
        // ("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")
        string ipv6_address = 15;

        string host_and_port = 21;

    };
    string extra_args = 23;  // Used to pass additional device specific arguments

    ProxyAddress proxy_address = 19;

    AdminState.AdminState admin_state = 16;

    OperStatus.OperStatus oper_status = 17 [(access) = READ_ONLY];

    string reason = 22 [(access) = READ_ONLY];  //  Used in FAILED state

    ConnectStatus.ConnectStatus connect_status = 18 [(access) = READ_ONLY];

    // TODO additional common attribute here

    // Device type specific attributes
    google.protobuf.Any custom = 64;

    repeated Port ports = 128  [(child_node) = {key: "port_no"}];
    openflow_13.Flows flows = 129 [(child_node) = {}];
    openflow_13.FlowGroups flow_groups = 130 [(child_node) = {}];
    // PmConfigs will eventually converted to a child node of the
    // device to falicitata callbacks and to simplify manipulation.
    PmConfigs pm_configs = 131 [(child_node) = {}];

    repeated ImageDownload image_downloads = 133 [(child_node) = {key: "name"}];
}

message Devices {
    repeated Device items = 1;
}

message SimulateAlarmRequest {
    enum OperationType {
        RAISE = 0;
        CLEAR = 1;
    }
    // Device Identifier
    string id = 1;
    string indicator = 2;
    string intf_id = 3;
    string port_type_name = 4;
    string onu_device_id = 5;
    int32 inverse_bit_error_rate = 6;
    int32 drift = 7;
    int32 new_eqd = 8;
    string onu_serial_number = 9;
    OperationType operation = 10;
}
