// Copyright (c) 2018 Open Networking Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

option go_package = "github.com/opencord/voltha-protos/v4/go/extension";
option java_package = "org.opencord.voltha.extension";

package extension;

import public "voltha_protos/ext_config.proto";
import "google/protobuf/empty.proto";

message GetDistanceRequest {
    string onuDeviceId = 1;
}

message GetDistanceResponse {
    uint32 distance = 1; // distance in meters
}

message GetOnuUniInfoRequest {
    uint32 uniIndex = 1; // Index of the uni starting from 0
}

message GetOnuUniInfoResponse {
    enum ConfigurationInd {
        UNKOWN = 0;
        TEN_BASE_T_FDX = 1;
        HUNDRED_BASE_T_FDX = 2;
        GIGABIT_ETHERNET_FDX = 3;
        TEN_G_ETHERNET_FDX = 4;
        TEN_BASE_T_HDX = 5;
        HUNDRED_BASE_T_HDX = 6;
        GIGABIT_ETHERNET_HDX = 7;
    }

    enum AdministrativeState {
        ADMSTATE_UNDEFINED = 0;
        LOCKED = 1;
        UNLOCKED = 2;
    }

    enum OperationalState {
        OPERSTATE_UNDEFINED = 0;
        ENABLED = 1;
        DISABLED = 2;
    }

    AdministrativeState admState = 1;
    OperationalState operState = 2;
    ConfigurationInd configInd = 3;
}

message GetOltPortCounters {
    enum PortType {
        Port_UNKNOWN = 0;
        Port_ETHERNET_NNI = 1;
        Port_PON_OLT = 2;
    }
    uint32 portNo = 1;  // Device-unique port number
    PortType portType = 2;
}

message GetOltPortCountersResponse {
    uint64 txBytes = 1;
    uint64 rxBytes = 2;
    uint64 txPackets = 3;
    uint64 rxPackets = 4;
    uint64 txErrorPackets = 5;
    uint64 rxErrorPackets = 6;
    uint64 txBcastPackets = 7;
    uint64 rxBcastPackets = 8;
    uint64 txUcastPackets = 9;
    uint64 rxUcastPackets = 10;
    uint64 txMcastPackets = 11;
    uint64 rxMcastPackets = 12;
}

message GetOnuPonOpticalInfo {
    google.protobuf.Empty empty = 1;
}

// These values correspond to the Optical Line Supervision Test results
// described in section A3.39.5 of ITU-T G.988 (11/2017) specification.
message GetOnuPonOpticalInfoResponse{
    float powerFeedVoltage = 1; // unit of value is voltage
    float receivedOpticalPower = 2; // unit of value is dBm
    float meanOpticalLaunchPower = 3; // unit of value is dBm
    float laserBiasCurrent = 4; // unit of value is amphere
    float temperature = 5; // unit of value is degree celsius
}

message GetOnuEthernetBridgePortHistory {
    enum Direction {
        UNDEFINED = 0;
        UPSTREAM = 1;
        DOWNSTREAM = 2;
    }
    Direction direction = 1;
}

message GetOnuEthernetBridgePortHistoryResponse {
     uint32 dropEvents = 1;
     uint32 octets = 2;
     uint32 packets= 3;
     uint32 broadcastPackets = 4;
     uint32 multicastPackets = 5;
     uint32 crcErroredPackets = 6;
     uint32 undersizePackets = 7;
     uint32 oversizePackets = 8;
     uint32 packets64octets = 9;
     uint32 packets65To127octets = 10;
     uint32 packets128To255Octets = 11;
     uint32 packets256To511octets = 12;
     uint32 packets512To1023octets = 13;
     uint32 packets1024To1518octets = 14;
}

message GetOnuFecHistory {
    google.protobuf.Empty empty = 1;
}

message GetOnuFecHistoryResponse {
    uint32 correctedBytes = 1;
    uint32 correctedCodeWords = 2;
    uint32 fecSeconds = 3;
    uint32 totalCodeWords = 4;
    uint32 uncorrectableCodeWords = 5;
}

message GetValueRequest {
    oneof request {
        GetDistanceRequest distance = 1;
        GetOnuUniInfoRequest uniInfo = 2;
        // Corresponds to PmMetricId.PON_PORT_COUNTERS, PmMetricId.NNI_PORT_COUNTERS 
        GetOltPortCounters oltPortInfo = 3;
        // Corresponds to PmMetricId.PON_OPTICAL
        GetOnuPonOpticalInfo onuOpticalInfo = 4;
        // Corresponds to PmMetricId.ETHERNET_BRIDGE_PORT_HISTORY
        GetOnuEthernetBridgePortHistory ethBridgePort = 5;
        // Corresponds to PmMetricId.FEC_HISTORY
        GetOnuFecHistory fecHistory= 6;
    }
}

message GetValueResponse {
    enum Status {
        STATUS_UNDEFINED = 0;
        OK = 1;
        ERROR = 2;
    }

    enum ErrorReason {
        REASON_UNDEFINED = 0;
        UNSUPPORTED = 1;
        INVALID_DEVICE_ID = 2;
        INVALID_PORT_TYPE = 3;
        TIMEOUT = 4;
        INVALID_REQ_TYPE = 5;
	INTERNAL_ERROR = 6;
    }
    Status status = 1;
    ErrorReason errReason = 2;

    oneof response {
        GetDistanceResponse distance = 3;
        GetOnuUniInfoResponse uniInfo = 4;
        GetOltPortCountersResponse portCoutners = 5;
        GetOnuPonOpticalInfoResponse onuOpticalInfo = 6;
        GetOnuEthernetBridgePortHistoryResponse ethBridgePortInfo = 7;
        GetOnuFecHistoryResponse fecHistory = 8;
    }
}

message SetValueRequest {
    oneof request {
        config.AlarmConfig alarm_config = 1;
    }
}

message SetValueResponse {
    enum Status {
        STATUS_UNDEFINED = 0;
        OK = 1;
        ERROR = 2;
    }

    enum ErrorReason {
        REASON_UNDEFINED = 0;
        UNSUPPORTED = 1;
    }
    Status status = 1;
    ErrorReason errReason = 2;

    // As of now we don't have any explicit response for the supported SetValueRequests
    // to be used later
    //oneof response {
    //
    //}
}

message SingleGetValueRequest {
    string targetId = 1;
    GetValueRequest request = 2;
}

message SingleGetValueResponse{
    GetValueResponse response = 1;
}

message SingleSetValueRequest {
    string targetId = 1;
    SetValueRequest request = 2;
}
message SingleSetValueResponse {
    SetValueResponse response = 1;
}

// Extension is a service to get and set specific attributes
service Extension {
    // Get a single attribute
    rpc GetExtValue(SingleGetValueRequest) returns (SingleGetValueResponse);
    // Set a single attribute
    rpc SetExtValue(SingleSetValueRequest) returns (SingleSetValueResponse);
}
