// 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;
}

// The types are from Table 11.2.10-1 in G.988
message GetOnuPonOpticalInfoResponse{
    int32 laserBiasCurrent = 1;
    int32 laserBiasCurrentTypeId = 2;
    int32 meanOpticalLaunchPower = 3;
    int32 meanOpticalLaunchPowerTypeId = 4;
    int32 powerFeedTypeId = 5;
    int32 powerFeedVoltage = 6;
    int32 receivedOpticalPower = 7;
    int32 receivedOpticalPowerTypeId = 8;
    int32 temperature = 9;
    int32 temperatureTypeId = 10;
}

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);
}
