// Code generated by protoc-gen-go. DO NOT EDIT.
// source: tls/wiring.proto

package tls

import (
	context "context"
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	xmlrpc "go.chromium.org/chromiumos/infra/proto/go/xmlrpc"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type SetDutPowerSupplyRequest_State int32

const (
	SetDutPowerSupplyRequest_STATE_UNKNOWN SetDutPowerSupplyRequest_State = 0
	SetDutPowerSupplyRequest_STATE_ON      SetDutPowerSupplyRequest_State = 1
	SetDutPowerSupplyRequest_STATE_OFF     SetDutPowerSupplyRequest_State = 2
)

var SetDutPowerSupplyRequest_State_name = map[int32]string{
	0: "STATE_UNKNOWN",
	1: "STATE_ON",
	2: "STATE_OFF",
}

var SetDutPowerSupplyRequest_State_value = map[string]int32{
	"STATE_UNKNOWN": 0,
	"STATE_ON":      1,
	"STATE_OFF":     2,
}

func (x SetDutPowerSupplyRequest_State) String() string {
	return proto.EnumName(SetDutPowerSupplyRequest_State_name, int32(x))
}

func (SetDutPowerSupplyRequest_State) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{2, 0}
}

type SetDutPowerSupplyResponse_Status int32

const (
	SetDutPowerSupplyResponse_STATUS_UNKNOWN SetDutPowerSupplyResponse_Status = 0
	SetDutPowerSupplyResponse_STATUS_OK      SetDutPowerSupplyResponse_Status = 1
	// STATUS_BAD_DUT indicates that the DUT is not known,
	// or the caller does not have access to it.
	SetDutPowerSupplyResponse_STATUS_BAD_DUT SetDutPowerSupplyResponse_Status = 2
	// STATUS_BAD_REQUEST indicates that the request was invalid,
	// e.g., passing an invalid state.
	SetDutPowerSupplyResponse_STATUS_BAD_REQUEST SetDutPowerSupplyResponse_Status = 3
	SetDutPowerSupplyResponse_STATUS_NO_RPM      SetDutPowerSupplyResponse_Status = 4
	SetDutPowerSupplyResponse_STATUS_RPM_ERROR   SetDutPowerSupplyResponse_Status = 5
)

var SetDutPowerSupplyResponse_Status_name = map[int32]string{
	0: "STATUS_UNKNOWN",
	1: "STATUS_OK",
	2: "STATUS_BAD_DUT",
	3: "STATUS_BAD_REQUEST",
	4: "STATUS_NO_RPM",
	5: "STATUS_RPM_ERROR",
}

var SetDutPowerSupplyResponse_Status_value = map[string]int32{
	"STATUS_UNKNOWN":     0,
	"STATUS_OK":          1,
	"STATUS_BAD_DUT":     2,
	"STATUS_BAD_REQUEST": 3,
	"STATUS_NO_RPM":      4,
	"STATUS_RPM_ERROR":   5,
}

func (x SetDutPowerSupplyResponse_Status) String() string {
	return proto.EnumName(SetDutPowerSupplyResponse_Status_name, int32(x))
}

func (SetDutPowerSupplyResponse_Status) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{3, 0}
}

type CacheForDutResponse_Status int32

const (
	CacheForDutResponse_STATUS_UNKNOWN   CacheForDutResponse_Status = 0
	CacheForDutResponse_STATUS_OK        CacheForDutResponse_Status = 1
	CacheForDutResponse_STATUS_CONTINUE  CacheForDutResponse_Status = 2
	CacheForDutResponse_STATUS_NOT_FOUND CacheForDutResponse_Status = 3
	CacheForDutResponse_STATUS_TIMEOUT   CacheForDutResponse_Status = 4
)

var CacheForDutResponse_Status_name = map[int32]string{
	0: "STATUS_UNKNOWN",
	1: "STATUS_OK",
	2: "STATUS_CONTINUE",
	3: "STATUS_NOT_FOUND",
	4: "STATUS_TIMEOUT",
}

var CacheForDutResponse_Status_value = map[string]int32{
	"STATUS_UNKNOWN":   0,
	"STATUS_OK":        1,
	"STATUS_CONTINUE":  2,
	"STATUS_NOT_FOUND": 3,
	"STATUS_TIMEOUT":   4,
}

func (x CacheForDutResponse_Status) String() string {
	return proto.EnumName(CacheForDutResponse_Status_name, int32(x))
}

func (CacheForDutResponse_Status) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{5, 0}
}

type CallServoXmlRpcResponse_Status int32

const (
	CallServoXmlRpcResponse_STATUS_UNKNOWN CallServoXmlRpcResponse_Status = 0
	CallServoXmlRpcResponse_STATUS_OK      CallServoXmlRpcResponse_Status = 1
	// STATUS_BAD_DUT indicates that the DUT is not known,
	// or the caller does not have access to it.
	CallServoXmlRpcResponse_STATUS_BAD_DUT CallServoXmlRpcResponse_Status = 2
	// STATUS_NO_METHOD indicates that the requested method does not
	// exist.
	CallServoXmlRpcResponse_STATUS_NO_METHOD   CallServoXmlRpcResponse_Status = 3
	CallServoXmlRpcResponse_STATUS_NO_SERVO    CallServoXmlRpcResponse_Status = 4
	CallServoXmlRpcResponse_STATUS_SERVO_ERROR CallServoXmlRpcResponse_Status = 5
)

var CallServoXmlRpcResponse_Status_name = map[int32]string{
	0: "STATUS_UNKNOWN",
	1: "STATUS_OK",
	2: "STATUS_BAD_DUT",
	3: "STATUS_NO_METHOD",
	4: "STATUS_NO_SERVO",
	5: "STATUS_SERVO_ERROR",
}

var CallServoXmlRpcResponse_Status_value = map[string]int32{
	"STATUS_UNKNOWN":     0,
	"STATUS_OK":          1,
	"STATUS_BAD_DUT":     2,
	"STATUS_NO_METHOD":   3,
	"STATUS_NO_SERVO":    4,
	"STATUS_SERVO_ERROR": 5,
}

func (x CallServoXmlRpcResponse_Status) String() string {
	return proto.EnumName(CallServoXmlRpcResponse_Status_name, int32(x))
}

func (CallServoXmlRpcResponse_Status) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{7, 0}
}

type OpenDutPortRequest struct {
	// name is the resource name for the DUT.
	// The DUT name is passed to the RTD when the RTD is started.
	// It is not specified whether the name is the DUT hostname.
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// port is the port to open on the DUT.
	Port                 int32    `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *OpenDutPortRequest) Reset()         { *m = OpenDutPortRequest{} }
func (m *OpenDutPortRequest) String() string { return proto.CompactTextString(m) }
func (*OpenDutPortRequest) ProtoMessage()    {}
func (*OpenDutPortRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{0}
}

func (m *OpenDutPortRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_OpenDutPortRequest.Unmarshal(m, b)
}
func (m *OpenDutPortRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_OpenDutPortRequest.Marshal(b, m, deterministic)
}
func (m *OpenDutPortRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_OpenDutPortRequest.Merge(m, src)
}
func (m *OpenDutPortRequest) XXX_Size() int {
	return xxx_messageInfo_OpenDutPortRequest.Size(m)
}
func (m *OpenDutPortRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_OpenDutPortRequest.DiscardUnknown(m)
}

var xxx_messageInfo_OpenDutPortRequest proto.InternalMessageInfo

func (m *OpenDutPortRequest) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *OpenDutPortRequest) GetPort() int32 {
	if m != nil {
		return m.Port
	}
	return 0
}

type OpenDutPortResponse struct {
	// address for which a port is forwarded to the DUT.
	// TLEs SHOULD return an IPv4 or IPv6 address to avoid name
	// resolution issues.
	// IPv4 addresses MUST be in standard dotted decimal notation.
	// IPv6 addresses MUST be formatted according to RFC4291, Section
	// 2.2.  The mixed IPv4 and IPv6 form MUST NOT be used.
	// If TLEs return a hostname, they SHOULD ensure that the hostname
	// can be resolved by the RTD via standard name resolution
	// facilities.
	Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
	// port on the address which is forwarded to the DUT.
	Port                 int32    `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *OpenDutPortResponse) Reset()         { *m = OpenDutPortResponse{} }
func (m *OpenDutPortResponse) String() string { return proto.CompactTextString(m) }
func (*OpenDutPortResponse) ProtoMessage()    {}
func (*OpenDutPortResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{1}
}

func (m *OpenDutPortResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_OpenDutPortResponse.Unmarshal(m, b)
}
func (m *OpenDutPortResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_OpenDutPortResponse.Marshal(b, m, deterministic)
}
func (m *OpenDutPortResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_OpenDutPortResponse.Merge(m, src)
}
func (m *OpenDutPortResponse) XXX_Size() int {
	return xxx_messageInfo_OpenDutPortResponse.Size(m)
}
func (m *OpenDutPortResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_OpenDutPortResponse.DiscardUnknown(m)
}

var xxx_messageInfo_OpenDutPortResponse proto.InternalMessageInfo

func (m *OpenDutPortResponse) GetAddress() string {
	if m != nil {
		return m.Address
	}
	return ""
}

func (m *OpenDutPortResponse) GetPort() int32 {
	if m != nil {
		return m.Port
	}
	return 0
}

type SetDutPowerSupplyRequest struct {
	Dut                  string                         `protobuf:"bytes,1,opt,name=dut,proto3" json:"dut,omitempty"`
	State                SetDutPowerSupplyRequest_State `protobuf:"varint,2,opt,name=state,proto3,enum=tls.SetDutPowerSupplyRequest_State" json:"state,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                       `json:"-"`
	XXX_unrecognized     []byte                         `json:"-"`
	XXX_sizecache        int32                          `json:"-"`
}

func (m *SetDutPowerSupplyRequest) Reset()         { *m = SetDutPowerSupplyRequest{} }
func (m *SetDutPowerSupplyRequest) String() string { return proto.CompactTextString(m) }
func (*SetDutPowerSupplyRequest) ProtoMessage()    {}
func (*SetDutPowerSupplyRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{2}
}

func (m *SetDutPowerSupplyRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_SetDutPowerSupplyRequest.Unmarshal(m, b)
}
func (m *SetDutPowerSupplyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_SetDutPowerSupplyRequest.Marshal(b, m, deterministic)
}
func (m *SetDutPowerSupplyRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_SetDutPowerSupplyRequest.Merge(m, src)
}
func (m *SetDutPowerSupplyRequest) XXX_Size() int {
	return xxx_messageInfo_SetDutPowerSupplyRequest.Size(m)
}
func (m *SetDutPowerSupplyRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_SetDutPowerSupplyRequest.DiscardUnknown(m)
}

var xxx_messageInfo_SetDutPowerSupplyRequest proto.InternalMessageInfo

func (m *SetDutPowerSupplyRequest) GetDut() string {
	if m != nil {
		return m.Dut
	}
	return ""
}

func (m *SetDutPowerSupplyRequest) GetState() SetDutPowerSupplyRequest_State {
	if m != nil {
		return m.State
	}
	return SetDutPowerSupplyRequest_STATE_UNKNOWN
}

type SetDutPowerSupplyResponse struct {
	Status SetDutPowerSupplyResponse_Status `protobuf:"varint,1,opt,name=status,proto3,enum=tls.SetDutPowerSupplyResponse_Status" json:"status,omitempty"`
	// reason provides human friendly context for any error status.
	Reason               string   `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *SetDutPowerSupplyResponse) Reset()         { *m = SetDutPowerSupplyResponse{} }
func (m *SetDutPowerSupplyResponse) String() string { return proto.CompactTextString(m) }
func (*SetDutPowerSupplyResponse) ProtoMessage()    {}
func (*SetDutPowerSupplyResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{3}
}

func (m *SetDutPowerSupplyResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_SetDutPowerSupplyResponse.Unmarshal(m, b)
}
func (m *SetDutPowerSupplyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_SetDutPowerSupplyResponse.Marshal(b, m, deterministic)
}
func (m *SetDutPowerSupplyResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_SetDutPowerSupplyResponse.Merge(m, src)
}
func (m *SetDutPowerSupplyResponse) XXX_Size() int {
	return xxx_messageInfo_SetDutPowerSupplyResponse.Size(m)
}
func (m *SetDutPowerSupplyResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_SetDutPowerSupplyResponse.DiscardUnknown(m)
}

var xxx_messageInfo_SetDutPowerSupplyResponse proto.InternalMessageInfo

func (m *SetDutPowerSupplyResponse) GetStatus() SetDutPowerSupplyResponse_Status {
	if m != nil {
		return m.Status
	}
	return SetDutPowerSupplyResponse_STATUS_UNKNOWN
}

func (m *SetDutPowerSupplyResponse) GetReason() string {
	if m != nil {
		return m.Reason
	}
	return ""
}

type CacheForDutRequest struct {
	// url identifies the resource to cache.
	// Only http, https, and gs are supported.
	Url                  string   `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *CacheForDutRequest) Reset()         { *m = CacheForDutRequest{} }
func (m *CacheForDutRequest) String() string { return proto.CompactTextString(m) }
func (*CacheForDutRequest) ProtoMessage()    {}
func (*CacheForDutRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{4}
}

func (m *CacheForDutRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_CacheForDutRequest.Unmarshal(m, b)
}
func (m *CacheForDutRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_CacheForDutRequest.Marshal(b, m, deterministic)
}
func (m *CacheForDutRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_CacheForDutRequest.Merge(m, src)
}
func (m *CacheForDutRequest) XXX_Size() int {
	return xxx_messageInfo_CacheForDutRequest.Size(m)
}
func (m *CacheForDutRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_CacheForDutRequest.DiscardUnknown(m)
}

var xxx_messageInfo_CacheForDutRequest proto.InternalMessageInfo

func (m *CacheForDutRequest) GetUrl() string {
	if m != nil {
		return m.Url
	}
	return ""
}

type CacheForDutResponse struct {
	Status CacheForDutResponse_Status `protobuf:"varint,1,opt,name=status,proto3,enum=tls.CacheForDutResponse_Status" json:"status,omitempty"`
	// url is where the resource is cached at.
	// This should be accessible to the DUT.
	// If the host is a name, it should be resolveable by the DUT via
	// standard name resolution facilities.
	Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
	// reason provides human friendly context for any error status.
	Reason               string   `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *CacheForDutResponse) Reset()         { *m = CacheForDutResponse{} }
func (m *CacheForDutResponse) String() string { return proto.CompactTextString(m) }
func (*CacheForDutResponse) ProtoMessage()    {}
func (*CacheForDutResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{5}
}

func (m *CacheForDutResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_CacheForDutResponse.Unmarshal(m, b)
}
func (m *CacheForDutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_CacheForDutResponse.Marshal(b, m, deterministic)
}
func (m *CacheForDutResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_CacheForDutResponse.Merge(m, src)
}
func (m *CacheForDutResponse) XXX_Size() int {
	return xxx_messageInfo_CacheForDutResponse.Size(m)
}
func (m *CacheForDutResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_CacheForDutResponse.DiscardUnknown(m)
}

var xxx_messageInfo_CacheForDutResponse proto.InternalMessageInfo

func (m *CacheForDutResponse) GetStatus() CacheForDutResponse_Status {
	if m != nil {
		return m.Status
	}
	return CacheForDutResponse_STATUS_UNKNOWN
}

func (m *CacheForDutResponse) GetUrl() string {
	if m != nil {
		return m.Url
	}
	return ""
}

func (m *CacheForDutResponse) GetReason() string {
	if m != nil {
		return m.Reason
	}
	return ""
}

type CallServoXmlRpcRequest struct {
	Dut                  string          `protobuf:"bytes,1,opt,name=dut,proto3" json:"dut,omitempty"`
	Method               string          `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
	Args                 []*xmlrpc.Value `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"`
	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
	XXX_unrecognized     []byte          `json:"-"`
	XXX_sizecache        int32           `json:"-"`
}

func (m *CallServoXmlRpcRequest) Reset()         { *m = CallServoXmlRpcRequest{} }
func (m *CallServoXmlRpcRequest) String() string { return proto.CompactTextString(m) }
func (*CallServoXmlRpcRequest) ProtoMessage()    {}
func (*CallServoXmlRpcRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{6}
}

func (m *CallServoXmlRpcRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_CallServoXmlRpcRequest.Unmarshal(m, b)
}
func (m *CallServoXmlRpcRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_CallServoXmlRpcRequest.Marshal(b, m, deterministic)
}
func (m *CallServoXmlRpcRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_CallServoXmlRpcRequest.Merge(m, src)
}
func (m *CallServoXmlRpcRequest) XXX_Size() int {
	return xxx_messageInfo_CallServoXmlRpcRequest.Size(m)
}
func (m *CallServoXmlRpcRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_CallServoXmlRpcRequest.DiscardUnknown(m)
}

var xxx_messageInfo_CallServoXmlRpcRequest proto.InternalMessageInfo

func (m *CallServoXmlRpcRequest) GetDut() string {
	if m != nil {
		return m.Dut
	}
	return ""
}

func (m *CallServoXmlRpcRequest) GetMethod() string {
	if m != nil {
		return m.Method
	}
	return ""
}

func (m *CallServoXmlRpcRequest) GetArgs() []*xmlrpc.Value {
	if m != nil {
		return m.Args
	}
	return nil
}

type CallServoXmlRpcResponse struct {
	Status CallServoXmlRpcResponse_Status `protobuf:"varint,1,opt,name=status,proto3,enum=tls.CallServoXmlRpcResponse_Status" json:"status,omitempty"`
	Value  *xmlrpc.Value                  `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
	// fault indicates that the servo XML-RPC returned a fault.
	// The fault value is stored in the value field.
	Fault                bool     `protobuf:"varint,3,opt,name=fault,proto3" json:"fault,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *CallServoXmlRpcResponse) Reset()         { *m = CallServoXmlRpcResponse{} }
func (m *CallServoXmlRpcResponse) String() string { return proto.CompactTextString(m) }
func (*CallServoXmlRpcResponse) ProtoMessage()    {}
func (*CallServoXmlRpcResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_aaa1c187e104f1c4, []int{7}
}

func (m *CallServoXmlRpcResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_CallServoXmlRpcResponse.Unmarshal(m, b)
}
func (m *CallServoXmlRpcResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_CallServoXmlRpcResponse.Marshal(b, m, deterministic)
}
func (m *CallServoXmlRpcResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_CallServoXmlRpcResponse.Merge(m, src)
}
func (m *CallServoXmlRpcResponse) XXX_Size() int {
	return xxx_messageInfo_CallServoXmlRpcResponse.Size(m)
}
func (m *CallServoXmlRpcResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_CallServoXmlRpcResponse.DiscardUnknown(m)
}

var xxx_messageInfo_CallServoXmlRpcResponse proto.InternalMessageInfo

func (m *CallServoXmlRpcResponse) GetStatus() CallServoXmlRpcResponse_Status {
	if m != nil {
		return m.Status
	}
	return CallServoXmlRpcResponse_STATUS_UNKNOWN
}

func (m *CallServoXmlRpcResponse) GetValue() *xmlrpc.Value {
	if m != nil {
		return m.Value
	}
	return nil
}

func (m *CallServoXmlRpcResponse) GetFault() bool {
	if m != nil {
		return m.Fault
	}
	return false
}

func init() {
	proto.RegisterEnum("tls.SetDutPowerSupplyRequest_State", SetDutPowerSupplyRequest_State_name, SetDutPowerSupplyRequest_State_value)
	proto.RegisterEnum("tls.SetDutPowerSupplyResponse_Status", SetDutPowerSupplyResponse_Status_name, SetDutPowerSupplyResponse_Status_value)
	proto.RegisterEnum("tls.CacheForDutResponse_Status", CacheForDutResponse_Status_name, CacheForDutResponse_Status_value)
	proto.RegisterEnum("tls.CallServoXmlRpcResponse_Status", CallServoXmlRpcResponse_Status_name, CallServoXmlRpcResponse_Status_value)
	proto.RegisterType((*OpenDutPortRequest)(nil), "tls.OpenDutPortRequest")
	proto.RegisterType((*OpenDutPortResponse)(nil), "tls.OpenDutPortResponse")
	proto.RegisterType((*SetDutPowerSupplyRequest)(nil), "tls.SetDutPowerSupplyRequest")
	proto.RegisterType((*SetDutPowerSupplyResponse)(nil), "tls.SetDutPowerSupplyResponse")
	proto.RegisterType((*CacheForDutRequest)(nil), "tls.CacheForDutRequest")
	proto.RegisterType((*CacheForDutResponse)(nil), "tls.CacheForDutResponse")
	proto.RegisterType((*CallServoXmlRpcRequest)(nil), "tls.CallServoXmlRpcRequest")
	proto.RegisterType((*CallServoXmlRpcResponse)(nil), "tls.CallServoXmlRpcResponse")
}

func init() { proto.RegisterFile("tls/wiring.proto", fileDescriptor_aaa1c187e104f1c4) }

var fileDescriptor_aaa1c187e104f1c4 = []byte{
	// 699 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xdd, 0x6e, 0xd3, 0x4a,
	0x10, 0x3e, 0xce, 0xdf, 0x69, 0xa7, 0xa7, 0xed, 0x76, 0x53, 0xa5, 0x39, 0xe5, 0xaf, 0xb8, 0x02,
	0xf5, 0x86, 0x18, 0x85, 0x8b, 0x0a, 0x01, 0x12, 0x6d, 0xe2, 0x88, 0xaa, 0xc4, 0x2e, 0x6b, 0xbb,
	0x45, 0xdc, 0x58, 0x26, 0xd9, 0xa6, 0x41, 0x4e, 0x6c, 0x76, 0xd7, 0x2d, 0xdc, 0x21, 0x1e, 0x82,
	0x6b, 0x1e, 0x81, 0x87, 0xe2, 0x15, 0xb8, 0x47, 0x59, 0xaf, 0xc1, 0x4d, 0xd2, 0x4a, 0x88, 0xab,
	0xf8, 0x9b, 0x9d, 0x9d, 0xf9, 0xe6, 0x9b, 0x99, 0x0d, 0x20, 0x11, 0x72, 0xe3, 0x62, 0xc8, 0x86,
	0xe3, 0x41, 0x23, 0x66, 0x91, 0x88, 0x70, 0x51, 0x84, 0x7c, 0xb3, 0xfa, 0x61, 0x14, 0xb2, 0xb8,
	0x67, 0xa4, 0x3f, 0xe9, 0x89, 0xfe, 0x14, 0xb0, 0x1d, 0xd3, 0x71, 0x3b, 0x11, 0x47, 0x11, 0x13,
	0x84, 0xbe, 0x4f, 0x28, 0x17, 0x18, 0x43, 0x69, 0x1c, 0x8c, 0x68, 0x5d, 0xdb, 0xd2, 0x76, 0x16,
	0x89, 0xfc, 0x9e, 0xd8, 0xe2, 0x88, 0x89, 0x7a, 0x61, 0x4b, 0xdb, 0x29, 0x13, 0xf9, 0xad, 0xb7,
	0xa0, 0x7a, 0xe9, 0x36, 0x8f, 0xa3, 0x31, 0xa7, 0xb8, 0x0e, 0xff, 0x06, 0xfd, 0x3e, 0xa3, 0x9c,
	0xab, 0x08, 0x19, 0x9c, 0x1b, 0xe4, 0xab, 0x06, 0x75, 0x87, 0x0a, 0x19, 0xe4, 0x82, 0x32, 0x27,
	0x89, 0xe3, 0xf0, 0x63, 0xc6, 0x04, 0x41, 0xb1, 0x9f, 0x08, 0x15, 0x66, 0xf2, 0x89, 0x1f, 0x43,
	0x99, 0x8b, 0x40, 0x50, 0x19, 0x63, 0xa5, 0xb9, 0xdd, 0x10, 0x21, 0x6f, 0x5c, 0x75, 0xbf, 0xe1,
	0x4c, 0x5c, 0x49, 0x7a, 0x43, 0xdf, 0x85, 0xb2, 0xc4, 0x78, 0x0d, 0x96, 0x1d, 0x77, 0xcf, 0x35,
	0x7d, 0xcf, 0x3a, 0xb4, 0xec, 0x13, 0x0b, 0xfd, 0x83, 0xff, 0x83, 0x85, 0xd4, 0x64, 0x5b, 0x48,
	0xc3, 0xcb, 0xb0, 0xa8, 0x50, 0xa7, 0x83, 0x0a, 0xfa, 0x0f, 0x0d, 0xfe, 0x9f, 0x93, 0x42, 0x95,
	0xfb, 0x0c, 0x2a, 0x93, 0xf8, 0x49, 0x5a, 0xed, 0x4a, 0xf3, 0xde, 0x55, 0x94, 0x52, 0x7f, 0xc9,
	0x29, 0xe1, 0x44, 0x5d, 0xc2, 0x35, 0xa8, 0x30, 0x1a, 0xf0, 0x68, 0x2c, 0x2b, 0x5a, 0x24, 0x0a,
	0xe9, 0x9f, 0x34, 0xa8, 0xa4, 0xae, 0x18, 0xc3, 0xca, 0x84, 0x8e, 0xe7, 0xe4, 0x08, 0x2b, 0x8a,
	0x9e, 0xe3, 0xdb, 0x87, 0x48, 0xcb, 0xb9, 0xec, 0xef, 0xb5, 0xfd, 0xb6, 0xe7, 0xa2, 0x02, 0xae,
	0x01, 0xce, 0xd9, 0x88, 0xf9, 0xca, 0x33, 0x1d, 0x17, 0x15, 0xb3, 0xf2, 0x3d, 0xc7, 0xb7, 0x6c,
	0x9f, 0x1c, 0x75, 0x51, 0x09, 0xaf, 0x03, 0x52, 0x26, 0x72, 0xd4, 0xf5, 0x4d, 0x42, 0x6c, 0x82,
	0xca, 0xfa, 0x7d, 0xc0, 0xad, 0xa0, 0x77, 0x46, 0x3b, 0x11, 0x6b, 0x27, 0x22, 0xd7, 0x93, 0x84,
	0x85, 0x59, 0x4f, 0x12, 0x16, 0xea, 0xdf, 0x35, 0xa8, 0x5e, 0x72, 0x54, 0xca, 0xec, 0x4e, 0x29,
	0x73, 0x47, 0x2a, 0x33, 0xc7, 0x73, 0x5a, 0x13, 0x95, 0xa2, 0xf0, 0x2b, 0x45, 0x4e, 0xa5, 0xe2,
	0x25, 0x95, 0xde, 0xfd, 0x89, 0x48, 0x55, 0x58, 0x55, 0xb0, 0x65, 0x5b, 0xee, 0x81, 0xe5, 0x99,
	0xa8, 0x90, 0x2b, 0xdd, 0xb2, 0x5d, 0xbf, 0x63, 0x7b, 0x56, 0x1b, 0x15, 0x73, 0xd1, 0xdc, 0x83,
	0xae, 0x69, 0x7b, 0x2e, 0x2a, 0xe9, 0x14, 0x6a, 0xad, 0x20, 0x0c, 0x1d, 0xca, 0xce, 0xa3, 0xd7,
	0xa3, 0x90, 0xc4, 0xbd, 0xab, 0xc7, 0xb4, 0x06, 0x95, 0x11, 0x15, 0x67, 0x51, 0x3f, 0xeb, 0x6a,
	0x8a, 0xf0, 0x5d, 0x28, 0x05, 0x6c, 0xc0, 0xeb, 0xc5, 0xad, 0xe2, 0xce, 0x52, 0x73, 0xb9, 0xa1,
	0xb6, 0xf1, 0x38, 0x08, 0x13, 0x4a, 0xe4, 0x91, 0xfe, 0xa5, 0x00, 0x1b, 0x33, 0x79, 0x94, 0xa2,
	0x4f, 0xa6, 0x14, 0xdd, 0x56, 0x8a, 0xce, 0xf5, 0x9e, 0x56, 0x75, 0x1b, 0xca, 0xe7, 0x93, 0x3c,
	0x92, 0xd2, 0x4c, 0xf2, 0xf4, 0x0c, 0xaf, 0x43, 0xf9, 0x34, 0x48, 0x42, 0x21, 0x75, 0x5e, 0x20,
	0x29, 0xd0, 0x3f, 0xff, 0xf5, 0x30, 0xe6, 0x65, 0xf6, 0xbb, 0xa6, 0xfb, 0xc2, 0x9e, 0xc8, 0xfc,
	0xbb, 0x23, 0x96, 0xed, 0x3b, 0x26, 0x39, 0xb6, 0x51, 0x29, 0x37, 0xb7, 0xd2, 0x92, 0x8d, 0x63,
	0xf3, 0x5b, 0x01, 0x2a, 0x27, 0xf2, 0x5d, 0xc3, 0xcf, 0x61, 0x29, 0xf7, 0xf2, 0xe0, 0x0d, 0x29,
	0xc3, 0xec, 0x4b, 0xb6, 0x59, 0x9f, 0x3d, 0x50, 0x4a, 0x12, 0x58, 0x9b, 0x59, 0x51, 0x7c, 0xeb,
	0xda, 0xd7, 0x64, 0xf3, 0xf6, 0xf5, 0x9b, 0x8d, 0xf7, 0x61, 0x29, 0x37, 0xdc, 0x8a, 0xd5, 0xec,
	0x06, 0x29, 0x56, 0x73, 0xf6, 0xe0, 0xa1, 0x86, 0x5f, 0xc2, 0xea, 0x54, 0x3b, 0xf1, 0x8d, 0xf9,
	0x4d, 0x4e, 0x63, 0xdd, 0xbc, 0x6e, 0x02, 0xf6, 0x8d, 0x37, 0x0f, 0x06, 0x51, 0xa3, 0x77, 0xc6,
	0xa2, 0xd1, 0x30, 0x19, 0x35, 0x22, 0x36, 0x30, 0x32, 0x10, 0x71, 0x63, 0x38, 0x3e, 0x65, 0x81,
	0x21, 0xff, 0x09, 0x8c, 0x41, 0x64, 0x88, 0x90, 0xbf, 0xad, 0x48, 0xf4, 0xe8, 0x67, 0x00, 0x00,
	0x00, 0xff, 0xff, 0x3e, 0x89, 0x6e, 0x31, 0x45, 0x06, 0x00, 0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4

// WiringClient is the client API for Wiring service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type WiringClient interface {
	// Open a port on the DUT and return an address which the client can
	// use to connect to the port on the DUT.
	// The TLE SHOULD attempt to keep this address-to-port connection open for
	// the duration of the RTD's runtime.
	// The connection is not restarted if it is interrupted.
	//
	// If the connection from a previous call with the same arguments is
	// still open, this RPC SHOULD do nothing and return the same
	// response.
	// If the previous connection was closed, the implementation SHOULD
	// attempt to rebind and return the same address.
	// If the implementation lost and cannot reobtain the previous
	// address, it MAY return a new address.
	//
	// This RPC does NOT ensure that there is a service running on the
	// DUT for the given port.
	// A service running on the given port MUST NOT required for this RPC
	// to succeed.
	// It is not specified whether this RPC will open the given port in
	// the DUT's firewall, if the DUT has a firewall.
	OpenDutPort(ctx context.Context, in *OpenDutPortRequest, opts ...grpc.CallOption) (*OpenDutPortResponse, error)
	// SetDutPowerSupply sets the connected power state for the DUT.  It is
	// the caller's responsibility to wait for the effects of the call
	// to propagate, e.g. waiting in between calls to set the power OFF
	// and ON.
	//
	// EXPERIMENTAL
	SetDutPowerSupply(ctx context.Context, in *SetDutPowerSupplyRequest, opts ...grpc.CallOption) (*SetDutPowerSupplyResponse, error)
	// CacheForDut caches some data to be accesible for the DUT.
	// This will be made available to the DUT via a returned URL.
	// The service will periodically return STATUS_CONTINUE messages to keep the stream alive.
	// Implementations should use a reasonable interval (e.g., one minute)
	// to ensure the stream does not time out.
	// The client should continue streaming replies until getting success or failure.
	//
	// EXPERIMENTAL
	CacheForDut(ctx context.Context, in *CacheForDutRequest, opts ...grpc.CallOption) (Wiring_CacheForDutClient, error)
	// CallServoXmlRpc performs an XML-RPC call against the servo connected to a DUT.
	//
	// This RPC mirrors the XML-RPC specification (http://xmlrpc.com/spec.md).
	//
	// EXPERIMENTAL
	CallServoXmlRpc(ctx context.Context, in *CallServoXmlRpcRequest, opts ...grpc.CallOption) (*CallServoXmlRpcResponse, error)
}

type wiringClient struct {
	cc *grpc.ClientConn
}

func NewWiringClient(cc *grpc.ClientConn) WiringClient {
	return &wiringClient{cc}
}

func (c *wiringClient) OpenDutPort(ctx context.Context, in *OpenDutPortRequest, opts ...grpc.CallOption) (*OpenDutPortResponse, error) {
	out := new(OpenDutPortResponse)
	err := c.cc.Invoke(ctx, "/tls.Wiring/OpenDutPort", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *wiringClient) SetDutPowerSupply(ctx context.Context, in *SetDutPowerSupplyRequest, opts ...grpc.CallOption) (*SetDutPowerSupplyResponse, error) {
	out := new(SetDutPowerSupplyResponse)
	err := c.cc.Invoke(ctx, "/tls.Wiring/SetDutPowerSupply", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *wiringClient) CacheForDut(ctx context.Context, in *CacheForDutRequest, opts ...grpc.CallOption) (Wiring_CacheForDutClient, error) {
	stream, err := c.cc.NewStream(ctx, &_Wiring_serviceDesc.Streams[0], "/tls.Wiring/CacheForDut", opts...)
	if err != nil {
		return nil, err
	}
	x := &wiringCacheForDutClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type Wiring_CacheForDutClient interface {
	Recv() (*CacheForDutResponse, error)
	grpc.ClientStream
}

type wiringCacheForDutClient struct {
	grpc.ClientStream
}

func (x *wiringCacheForDutClient) Recv() (*CacheForDutResponse, error) {
	m := new(CacheForDutResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *wiringClient) CallServoXmlRpc(ctx context.Context, in *CallServoXmlRpcRequest, opts ...grpc.CallOption) (*CallServoXmlRpcResponse, error) {
	out := new(CallServoXmlRpcResponse)
	err := c.cc.Invoke(ctx, "/tls.Wiring/CallServoXmlRpc", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// WiringServer is the server API for Wiring service.
type WiringServer interface {
	// Open a port on the DUT and return an address which the client can
	// use to connect to the port on the DUT.
	// The TLE SHOULD attempt to keep this address-to-port connection open for
	// the duration of the RTD's runtime.
	// The connection is not restarted if it is interrupted.
	//
	// If the connection from a previous call with the same arguments is
	// still open, this RPC SHOULD do nothing and return the same
	// response.
	// If the previous connection was closed, the implementation SHOULD
	// attempt to rebind and return the same address.
	// If the implementation lost and cannot reobtain the previous
	// address, it MAY return a new address.
	//
	// This RPC does NOT ensure that there is a service running on the
	// DUT for the given port.
	// A service running on the given port MUST NOT required for this RPC
	// to succeed.
	// It is not specified whether this RPC will open the given port in
	// the DUT's firewall, if the DUT has a firewall.
	OpenDutPort(context.Context, *OpenDutPortRequest) (*OpenDutPortResponse, error)
	// SetDutPowerSupply sets the connected power state for the DUT.  It is
	// the caller's responsibility to wait for the effects of the call
	// to propagate, e.g. waiting in between calls to set the power OFF
	// and ON.
	//
	// EXPERIMENTAL
	SetDutPowerSupply(context.Context, *SetDutPowerSupplyRequest) (*SetDutPowerSupplyResponse, error)
	// CacheForDut caches some data to be accesible for the DUT.
	// This will be made available to the DUT via a returned URL.
	// The service will periodically return STATUS_CONTINUE messages to keep the stream alive.
	// Implementations should use a reasonable interval (e.g., one minute)
	// to ensure the stream does not time out.
	// The client should continue streaming replies until getting success or failure.
	//
	// EXPERIMENTAL
	CacheForDut(*CacheForDutRequest, Wiring_CacheForDutServer) error
	// CallServoXmlRpc performs an XML-RPC call against the servo connected to a DUT.
	//
	// This RPC mirrors the XML-RPC specification (http://xmlrpc.com/spec.md).
	//
	// EXPERIMENTAL
	CallServoXmlRpc(context.Context, *CallServoXmlRpcRequest) (*CallServoXmlRpcResponse, error)
}

// UnimplementedWiringServer can be embedded to have forward compatible implementations.
type UnimplementedWiringServer struct {
}

func (*UnimplementedWiringServer) OpenDutPort(ctx context.Context, req *OpenDutPortRequest) (*OpenDutPortResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method OpenDutPort not implemented")
}
func (*UnimplementedWiringServer) SetDutPowerSupply(ctx context.Context, req *SetDutPowerSupplyRequest) (*SetDutPowerSupplyResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method SetDutPowerSupply not implemented")
}
func (*UnimplementedWiringServer) CacheForDut(req *CacheForDutRequest, srv Wiring_CacheForDutServer) error {
	return status.Errorf(codes.Unimplemented, "method CacheForDut not implemented")
}
func (*UnimplementedWiringServer) CallServoXmlRpc(ctx context.Context, req *CallServoXmlRpcRequest) (*CallServoXmlRpcResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method CallServoXmlRpc not implemented")
}

func RegisterWiringServer(s *grpc.Server, srv WiringServer) {
	s.RegisterService(&_Wiring_serviceDesc, srv)
}

func _Wiring_OpenDutPort_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(OpenDutPortRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(WiringServer).OpenDutPort(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/tls.Wiring/OpenDutPort",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(WiringServer).OpenDutPort(ctx, req.(*OpenDutPortRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _Wiring_SetDutPowerSupply_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SetDutPowerSupplyRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(WiringServer).SetDutPowerSupply(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/tls.Wiring/SetDutPowerSupply",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(WiringServer).SetDutPowerSupply(ctx, req.(*SetDutPowerSupplyRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _Wiring_CacheForDut_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(CacheForDutRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(WiringServer).CacheForDut(m, &wiringCacheForDutServer{stream})
}

type Wiring_CacheForDutServer interface {
	Send(*CacheForDutResponse) error
	grpc.ServerStream
}

type wiringCacheForDutServer struct {
	grpc.ServerStream
}

func (x *wiringCacheForDutServer) Send(m *CacheForDutResponse) error {
	return x.ServerStream.SendMsg(m)
}

func _Wiring_CallServoXmlRpc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(CallServoXmlRpcRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(WiringServer).CallServoXmlRpc(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/tls.Wiring/CallServoXmlRpc",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(WiringServer).CallServoXmlRpc(ctx, req.(*CallServoXmlRpcRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _Wiring_serviceDesc = grpc.ServiceDesc{
	ServiceName: "tls.Wiring",
	HandlerType: (*WiringServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "OpenDutPort",
			Handler:    _Wiring_OpenDutPort_Handler,
		},
		{
			MethodName: "SetDutPowerSupply",
			Handler:    _Wiring_SetDutPowerSupply_Handler,
		},
		{
			MethodName: "CallServoXmlRpc",
			Handler:    _Wiring_CallServoXmlRpc_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "CacheForDut",
			Handler:       _Wiring_CacheForDut_Handler,
			ServerStreams: true,
		},
	},
	Metadata: "tls/wiring.proto",
}
