// Code generated by protoc-gen-go. DO NOT EDIT.
// source: dmi/sw_management_service.proto

package dmi

import (
	context "context"
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	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 GetSoftwareVersionInformationResponse_Reason int32

const (
	GetSoftwareVersionInformationResponse_UNDEFINED_REASON   GetSoftwareVersionInformationResponse_Reason = 0
	GetSoftwareVersionInformationResponse_UNKNOWN_DEVICE     GetSoftwareVersionInformationResponse_Reason = 1
	GetSoftwareVersionInformationResponse_INTERNAL_ERROR     GetSoftwareVersionInformationResponse_Reason = 2
	GetSoftwareVersionInformationResponse_DEVICE_UNREACHABLE GetSoftwareVersionInformationResponse_Reason = 3
)

var GetSoftwareVersionInformationResponse_Reason_name = map[int32]string{
	0: "UNDEFINED_REASON",
	1: "UNKNOWN_DEVICE",
	2: "INTERNAL_ERROR",
	3: "DEVICE_UNREACHABLE",
}

var GetSoftwareVersionInformationResponse_Reason_value = map[string]int32{
	"UNDEFINED_REASON":   0,
	"UNKNOWN_DEVICE":     1,
	"INTERNAL_ERROR":     2,
	"DEVICE_UNREACHABLE": 3,
}

func (x GetSoftwareVersionInformationResponse_Reason) String() string {
	return proto.EnumName(GetSoftwareVersionInformationResponse_Reason_name, int32(x))
}

func (GetSoftwareVersionInformationResponse_Reason) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_000929e4bec891d7, []int{1, 0}
}

type ConfigResponse_Reason int32

const (
	ConfigResponse_UNDEFINED_REASON              ConfigResponse_Reason = 0
	ConfigResponse_UNKNOWN_DEVICE                ConfigResponse_Reason = 1
	ConfigResponse_INTERNAL_ERROR                ConfigResponse_Reason = 2
	ConfigResponse_ERROR_FETCHING_CONFIG         ConfigResponse_Reason = 3
	ConfigResponse_INVALID_CONFIG                ConfigResponse_Reason = 4
	ConfigResponse_OPERATION_ALREADY_IN_PROGRESS ConfigResponse_Reason = 5
	ConfigResponse_DEVICE_UNREACHABLE            ConfigResponse_Reason = 6
)

var ConfigResponse_Reason_name = map[int32]string{
	0: "UNDEFINED_REASON",
	1: "UNKNOWN_DEVICE",
	2: "INTERNAL_ERROR",
	3: "ERROR_FETCHING_CONFIG",
	4: "INVALID_CONFIG",
	5: "OPERATION_ALREADY_IN_PROGRESS",
	6: "DEVICE_UNREACHABLE",
}

var ConfigResponse_Reason_value = map[string]int32{
	"UNDEFINED_REASON":              0,
	"UNKNOWN_DEVICE":                1,
	"INTERNAL_ERROR":                2,
	"ERROR_FETCHING_CONFIG":         3,
	"INVALID_CONFIG":                4,
	"OPERATION_ALREADY_IN_PROGRESS": 5,
	"DEVICE_UNREACHABLE":            6,
}

func (x ConfigResponse_Reason) String() string {
	return proto.EnumName(ConfigResponse_Reason_name, int32(x))
}

func (ConfigResponse_Reason) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_000929e4bec891d7, []int{4, 0}
}

type StartupConfigInfoResponse_Reason int32

const (
	StartupConfigInfoResponse_UNDEFINED_REASON   StartupConfigInfoResponse_Reason = 0
	StartupConfigInfoResponse_UNKNOWN_DEVICE     StartupConfigInfoResponse_Reason = 1
	StartupConfigInfoResponse_INTERNAL_ERROR     StartupConfigInfoResponse_Reason = 2
	StartupConfigInfoResponse_DEVICE_UNREACHABLE StartupConfigInfoResponse_Reason = 3
)

var StartupConfigInfoResponse_Reason_name = map[int32]string{
	0: "UNDEFINED_REASON",
	1: "UNKNOWN_DEVICE",
	2: "INTERNAL_ERROR",
	3: "DEVICE_UNREACHABLE",
}

var StartupConfigInfoResponse_Reason_value = map[string]int32{
	"UNDEFINED_REASON":   0,
	"UNKNOWN_DEVICE":     1,
	"INTERNAL_ERROR":     2,
	"DEVICE_UNREACHABLE": 3,
}

func (x StartupConfigInfoResponse_Reason) String() string {
	return proto.EnumName(StartupConfigInfoResponse_Reason_name, int32(x))
}

func (StartupConfigInfoResponse_Reason) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_000929e4bec891d7, []int{6, 0}
}

type UploadDebugInfoStatus_UploadStatus int32

const (
	UploadDebugInfoStatus_UNDEFINED_UPLOAD_STATUS UploadDebugInfoStatus_UploadStatus = 0
	UploadDebugInfoStatus_COMPLETE                UploadDebugInfoStatus_UploadStatus = 1
	UploadDebugInfoStatus_IN_PROGRESS             UploadDebugInfoStatus_UploadStatus = 2
	UploadDebugInfoStatus_ERROR                   UploadDebugInfoStatus_UploadStatus = 3
)

var UploadDebugInfoStatus_UploadStatus_name = map[int32]string{
	0: "UNDEFINED_UPLOAD_STATUS",
	1: "COMPLETE",
	2: "IN_PROGRESS",
	3: "ERROR",
}

var UploadDebugInfoStatus_UploadStatus_value = map[string]int32{
	"UNDEFINED_UPLOAD_STATUS": 0,
	"COMPLETE":                1,
	"IN_PROGRESS":             2,
	"ERROR":                   3,
}

func (x UploadDebugInfoStatus_UploadStatus) String() string {
	return proto.EnumName(UploadDebugInfoStatus_UploadStatus_name, int32(x))
}

func (UploadDebugInfoStatus_UploadStatus) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_000929e4bec891d7, []int{8, 0}
}

type UploadDebugInfoStatus_Reason int32

const (
	UploadDebugInfoStatus_UNDEFINED_REASON UploadDebugInfoStatus_Reason = 0
	UploadDebugInfoStatus_UNKNOWN_DEVICE   UploadDebugInfoStatus_Reason = 1
	UploadDebugInfoStatus_INTERNAL_ERROR   UploadDebugInfoStatus_Reason = 2
	// The DM implementations should have retry mechanisms (timeout values dependant on specific implementations)
	// and even after those if the operation cannot be completed/reached then return error with reason as DEVICE_NOT_REACHABLE
	UploadDebugInfoStatus_DEVICE_NOT_REACHABLE              UploadDebugInfoStatus_Reason = 3
	UploadDebugInfoStatus_REMOTE_LOCATION_UNREACHABLE       UploadDebugInfoStatus_Reason = 4
	UploadDebugInfoStatus_REMOTE_LOCATION_PERMISSION_DENIED UploadDebugInfoStatus_Reason = 5
	UploadDebugInfoStatus_ERROR_DURING_UPLOAD               UploadDebugInfoStatus_Reason = 6
	UploadDebugInfoStatus_DEVICE_BUSY                       UploadDebugInfoStatus_Reason = 7
	// wrong location_url in the request
	UploadDebugInfoStatus_ERROR_IN_REQUEST              UploadDebugInfoStatus_Reason = 8
	UploadDebugInfoStatus_DEVICE_IN_WRONG_STATE         UploadDebugInfoStatus_Reason = 9
	UploadDebugInfoStatus_OPERATION_ALREADY_IN_PROGRESS UploadDebugInfoStatus_Reason = 10
)

var UploadDebugInfoStatus_Reason_name = map[int32]string{
	0:  "UNDEFINED_REASON",
	1:  "UNKNOWN_DEVICE",
	2:  "INTERNAL_ERROR",
	3:  "DEVICE_NOT_REACHABLE",
	4:  "REMOTE_LOCATION_UNREACHABLE",
	5:  "REMOTE_LOCATION_PERMISSION_DENIED",
	6:  "ERROR_DURING_UPLOAD",
	7:  "DEVICE_BUSY",
	8:  "ERROR_IN_REQUEST",
	9:  "DEVICE_IN_WRONG_STATE",
	10: "OPERATION_ALREADY_IN_PROGRESS",
}

var UploadDebugInfoStatus_Reason_value = map[string]int32{
	"UNDEFINED_REASON":                  0,
	"UNKNOWN_DEVICE":                    1,
	"INTERNAL_ERROR":                    2,
	"DEVICE_NOT_REACHABLE":              3,
	"REMOTE_LOCATION_UNREACHABLE":       4,
	"REMOTE_LOCATION_PERMISSION_DENIED": 5,
	"ERROR_DURING_UPLOAD":               6,
	"DEVICE_BUSY":                       7,
	"ERROR_IN_REQUEST":                  8,
	"DEVICE_IN_WRONG_STATE":             9,
	"OPERATION_ALREADY_IN_PROGRESS":     10,
}

func (x UploadDebugInfoStatus_Reason) String() string {
	return proto.EnumName(UploadDebugInfoStatus_Reason_name, int32(x))
}

func (UploadDebugInfoStatus_Reason) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_000929e4bec891d7, []int{8, 1}
}

type SoftwareVersionInformation struct {
	ActiveVersions       []*ImageVersion `protobuf:"bytes,1,rep,name=active_versions,json=activeVersions,proto3" json:"active_versions,omitempty"`
	StandbyVersions      []*ImageVersion `protobuf:"bytes,2,rep,name=standby_versions,json=standbyVersions,proto3" json:"standby_versions,omitempty"`
	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
	XXX_unrecognized     []byte          `json:"-"`
	XXX_sizecache        int32           `json:"-"`
}

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

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

var xxx_messageInfo_SoftwareVersionInformation proto.InternalMessageInfo

func (m *SoftwareVersionInformation) GetActiveVersions() []*ImageVersion {
	if m != nil {
		return m.ActiveVersions
	}
	return nil
}

func (m *SoftwareVersionInformation) GetStandbyVersions() []*ImageVersion {
	if m != nil {
		return m.StandbyVersions
	}
	return nil
}

type GetSoftwareVersionInformationResponse struct {
	Status               Status                                       `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason               GetSoftwareVersionInformationResponse_Reason `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.GetSoftwareVersionInformationResponse_Reason" json:"reason,omitempty"`
	Info                 *SoftwareVersionInformation                  `protobuf:"bytes,3,opt,name=info,proto3" json:"info,omitempty"`
	ReasonDetail         string                                       `protobuf:"bytes,4,opt,name=reason_detail,json=reasonDetail,proto3" json:"reason_detail,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                                     `json:"-"`
	XXX_unrecognized     []byte                                       `json:"-"`
	XXX_sizecache        int32                                        `json:"-"`
}

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

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

var xxx_messageInfo_GetSoftwareVersionInformationResponse proto.InternalMessageInfo

func (m *GetSoftwareVersionInformationResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *GetSoftwareVersionInformationResponse) GetReason() GetSoftwareVersionInformationResponse_Reason {
	if m != nil {
		return m.Reason
	}
	return GetSoftwareVersionInformationResponse_UNDEFINED_REASON
}

func (m *GetSoftwareVersionInformationResponse) GetInfo() *SoftwareVersionInformation {
	if m != nil {
		return m.Info
	}
	return nil
}

func (m *GetSoftwareVersionInformationResponse) GetReasonDetail() string {
	if m != nil {
		return m.ReasonDetail
	}
	return ""
}

type DownloadImageRequest struct {
	DeviceUuid           *Uuid             `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	ImageInfo            *ImageInformation `protobuf:"bytes,2,opt,name=image_info,json=imageInfo,proto3" json:"image_info,omitempty"`
	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
	XXX_unrecognized     []byte            `json:"-"`
	XXX_sizecache        int32             `json:"-"`
}

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

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

var xxx_messageInfo_DownloadImageRequest proto.InternalMessageInfo

func (m *DownloadImageRequest) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

func (m *DownloadImageRequest) GetImageInfo() *ImageInformation {
	if m != nil {
		return m.ImageInfo
	}
	return nil
}

type ConfigRequest struct {
	DeviceUuid *Uuid `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	// Location of the configuration file, authentication (user/pass) if any should be in the url string
	// The config_url would contain the protocol, credentials, the IP address/DNS of the server and the path of the file
	// e.g. sftp://download_user:download_pass@192.168.0.1:22/OLT-configs/config-v1.2.3.xml
	ConfigUrl            string   `protobuf:"bytes,2,opt,name=config_url,json=configUrl,proto3" json:"config_url,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_ConfigRequest proto.InternalMessageInfo

func (m *ConfigRequest) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

func (m *ConfigRequest) GetConfigUrl() string {
	if m != nil {
		return m.ConfigUrl
	}
	return ""
}

type ConfigResponse struct {
	Status               Status                `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason               ConfigResponse_Reason `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.ConfigResponse_Reason" json:"reason,omitempty"`
	ReasonDetail         string                `protobuf:"bytes,3,opt,name=reason_detail,json=reasonDetail,proto3" json:"reason_detail,omitempty"`
	XXX_NoUnkeyedLiteral struct{}              `json:"-"`
	XXX_unrecognized     []byte                `json:"-"`
	XXX_sizecache        int32                 `json:"-"`
}

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

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

var xxx_messageInfo_ConfigResponse proto.InternalMessageInfo

func (m *ConfigResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *ConfigResponse) GetReason() ConfigResponse_Reason {
	if m != nil {
		return m.Reason
	}
	return ConfigResponse_UNDEFINED_REASON
}

func (m *ConfigResponse) GetReasonDetail() string {
	if m != nil {
		return m.ReasonDetail
	}
	return ""
}

type StartupConfigInfoRequest struct {
	DeviceUuid           *Uuid    `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_StartupConfigInfoRequest proto.InternalMessageInfo

func (m *StartupConfigInfoRequest) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

type StartupConfigInfoResponse struct {
	Status Status                           `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason StartupConfigInfoResponse_Reason `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.StartupConfigInfoResponse_Reason" json:"reason,omitempty"`
	// The config_url is an optional attribute, the device manager could return the location from
	// where the config was downloaded. Also it would not be present/empty for a fresh device into which the
	// startup config would have been installed in the factory.
	ConfigUrl string `protobuf:"bytes,3,opt,name=config_url,json=configUrl,proto3" json:"config_url,omitempty"`
	// The version of the startup configuration. It is recommended to use semVer, but the DM implementations
	// and operators could choose any other format as well.
	Version              string   `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"`
	ReasonDetail         string   `protobuf:"bytes,5,opt,name=reason_detail,json=reasonDetail,proto3" json:"reason_detail,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_StartupConfigInfoResponse proto.InternalMessageInfo

func (m *StartupConfigInfoResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *StartupConfigInfoResponse) GetReason() StartupConfigInfoResponse_Reason {
	if m != nil {
		return m.Reason
	}
	return StartupConfigInfoResponse_UNDEFINED_REASON
}

func (m *StartupConfigInfoResponse) GetConfigUrl() string {
	if m != nil {
		return m.ConfigUrl
	}
	return ""
}

func (m *StartupConfigInfoResponse) GetVersion() string {
	if m != nil {
		return m.Version
	}
	return ""
}

func (m *StartupConfigInfoResponse) GetReasonDetail() string {
	if m != nil {
		return m.ReasonDetail
	}
	return ""
}

type UploadDebugInfoRequest struct {
	DeviceUuid *Uuid `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	// location_url is the remote location where the information needed for troubleshooting should be uploaded.
	// Authentication (user/pass) if any should be in the location_url string
	// The locaion_url would contain the protocol, credentials, the IP address/DNS of the server and the path of the directory
	// e.g. sftp://upload_user:upload_pass@192.168.0.1:22/hw_debug_info/
	LocationUrl          string   `protobuf:"bytes,3,opt,name=location_url,json=locationUrl,proto3" json:"location_url,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_UploadDebugInfoRequest proto.InternalMessageInfo

func (m *UploadDebugInfoRequest) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

func (m *UploadDebugInfoRequest) GetLocationUrl() string {
	if m != nil {
		return m.LocationUrl
	}
	return ""
}

// Implementations would be expected to stream multiple UploadDebugInfoStatus indicating the progress of the upload
type UploadDebugInfoStatus struct {
	DeviceUuid *Uuid                              `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	Status     UploadDebugInfoStatus_UploadStatus `protobuf:"varint,2,opt,name=status,proto3,enum=dmi.UploadDebugInfoStatus_UploadStatus" json:"status,omitempty"`
	// percent_uploaded is the percentage of the upload that is done
	// should be a value between 0 and 100 when status is IN_PROGRESS
	// should be 100 when status is COMPLETE
	// can be set to -1 if the device manager implementations cannot support
	// the progress percentage
	PercentUploaded int32                        `protobuf:"varint,3,opt,name=percent_uploaded,json=percentUploaded,proto3" json:"percent_uploaded,omitempty"`
	Reason          UploadDebugInfoStatus_Reason `protobuf:"varint,4,opt,name=reason,proto3,enum=dmi.UploadDebugInfoStatus_Reason" json:"reason,omitempty"`
	LocationUrl     string                       `protobuf:"bytes,5,opt,name=location_url,json=locationUrl,proto3" json:"location_url,omitempty"`
	// file_name is the file at location_url where the debug information was uploaded.
	// Implementations need to ensure that file_name is unique at the remote location.
	// file_name to be shared in the response stream when the upload begins.
	FileName             string   `protobuf:"bytes,6,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *UploadDebugInfoStatus) Reset()         { *m = UploadDebugInfoStatus{} }
func (m *UploadDebugInfoStatus) String() string { return proto.CompactTextString(m) }
func (*UploadDebugInfoStatus) ProtoMessage()    {}
func (*UploadDebugInfoStatus) Descriptor() ([]byte, []int) {
	return fileDescriptor_000929e4bec891d7, []int{8}
}

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

var xxx_messageInfo_UploadDebugInfoStatus proto.InternalMessageInfo

func (m *UploadDebugInfoStatus) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

func (m *UploadDebugInfoStatus) GetStatus() UploadDebugInfoStatus_UploadStatus {
	if m != nil {
		return m.Status
	}
	return UploadDebugInfoStatus_UNDEFINED_UPLOAD_STATUS
}

func (m *UploadDebugInfoStatus) GetPercentUploaded() int32 {
	if m != nil {
		return m.PercentUploaded
	}
	return 0
}

func (m *UploadDebugInfoStatus) GetReason() UploadDebugInfoStatus_Reason {
	if m != nil {
		return m.Reason
	}
	return UploadDebugInfoStatus_UNDEFINED_REASON
}

func (m *UploadDebugInfoStatus) GetLocationUrl() string {
	if m != nil {
		return m.LocationUrl
	}
	return ""
}

func (m *UploadDebugInfoStatus) GetFileName() string {
	if m != nil {
		return m.FileName
	}
	return ""
}

func init() {
	proto.RegisterEnum("dmi.GetSoftwareVersionInformationResponse_Reason", GetSoftwareVersionInformationResponse_Reason_name, GetSoftwareVersionInformationResponse_Reason_value)
	proto.RegisterEnum("dmi.ConfigResponse_Reason", ConfigResponse_Reason_name, ConfigResponse_Reason_value)
	proto.RegisterEnum("dmi.StartupConfigInfoResponse_Reason", StartupConfigInfoResponse_Reason_name, StartupConfigInfoResponse_Reason_value)
	proto.RegisterEnum("dmi.UploadDebugInfoStatus_UploadStatus", UploadDebugInfoStatus_UploadStatus_name, UploadDebugInfoStatus_UploadStatus_value)
	proto.RegisterEnum("dmi.UploadDebugInfoStatus_Reason", UploadDebugInfoStatus_Reason_name, UploadDebugInfoStatus_Reason_value)
	proto.RegisterType((*SoftwareVersionInformation)(nil), "dmi.SoftwareVersionInformation")
	proto.RegisterType((*GetSoftwareVersionInformationResponse)(nil), "dmi.GetSoftwareVersionInformationResponse")
	proto.RegisterType((*DownloadImageRequest)(nil), "dmi.DownloadImageRequest")
	proto.RegisterType((*ConfigRequest)(nil), "dmi.ConfigRequest")
	proto.RegisterType((*ConfigResponse)(nil), "dmi.ConfigResponse")
	proto.RegisterType((*StartupConfigInfoRequest)(nil), "dmi.StartupConfigInfoRequest")
	proto.RegisterType((*StartupConfigInfoResponse)(nil), "dmi.StartupConfigInfoResponse")
	proto.RegisterType((*UploadDebugInfoRequest)(nil), "dmi.UploadDebugInfoRequest")
	proto.RegisterType((*UploadDebugInfoStatus)(nil), "dmi.UploadDebugInfoStatus")
}

func init() { proto.RegisterFile("dmi/sw_management_service.proto", fileDescriptor_000929e4bec891d7) }

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

// NativeSoftwareManagementServiceClient is the client API for NativeSoftwareManagementService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type NativeSoftwareManagementServiceClient interface {
	// Get the software version information of the Active and Standby images
	GetSoftwareVersion(ctx context.Context, in *HardwareID, opts ...grpc.CallOption) (*GetSoftwareVersionInformationResponse, error)
	// Downloads and installs the image in the standby partition, returns the status/progress of the Install
	DownloadImage(ctx context.Context, in *DownloadImageRequest, opts ...grpc.CallOption) (NativeSoftwareManagementService_DownloadImageClient, error)
	// Activates and runs the OLT with the image in the standby partition. If things are fine this image will
	// henceforth be marked as the Active Partition. The old working image would remain on the Standby partition.
	// Any possibly required (sub-)steps like "commit" are left to the "Device Manager"
	ActivateImage(ctx context.Context, in *HardwareID, opts ...grpc.CallOption) (NativeSoftwareManagementService_ActivateImageClient, error)
	// Marks the image in the Standby as Active and reboots the device, so that it boots from that image which was in the standby.
	// This API is to be used if operator wants to go back to the previous software
	RevertToStandbyImage(ctx context.Context, in *HardwareID, opts ...grpc.CallOption) (NativeSoftwareManagementService_RevertToStandbyImageClient, error)
	// This API can be used to let the devices pickup their properitary configuration which they need at startup.
	UpdateStartupConfiguration(ctx context.Context, in *ConfigRequest, opts ...grpc.CallOption) (NativeSoftwareManagementService_UpdateStartupConfigurationClient, error)
	// This API can be used to retrieve information about the current startup configuration that a device is using
	GetStartupConfigurationInfo(ctx context.Context, in *StartupConfigInfoRequest, opts ...grpc.CallOption) (*StartupConfigInfoResponse, error)
	// This API can be used to upload to a remote location, information useful for troubleshooting problems on the hardware
	UploadDebugInfo(ctx context.Context, in *UploadDebugInfoRequest, opts ...grpc.CallOption) (NativeSoftwareManagementService_UploadDebugInfoClient, error)
}

type nativeSoftwareManagementServiceClient struct {
	cc *grpc.ClientConn
}

func NewNativeSoftwareManagementServiceClient(cc *grpc.ClientConn) NativeSoftwareManagementServiceClient {
	return &nativeSoftwareManagementServiceClient{cc}
}

func (c *nativeSoftwareManagementServiceClient) GetSoftwareVersion(ctx context.Context, in *HardwareID, opts ...grpc.CallOption) (*GetSoftwareVersionInformationResponse, error) {
	out := new(GetSoftwareVersionInformationResponse)
	err := c.cc.Invoke(ctx, "/dmi.NativeSoftwareManagementService/GetSoftwareVersion", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *nativeSoftwareManagementServiceClient) DownloadImage(ctx context.Context, in *DownloadImageRequest, opts ...grpc.CallOption) (NativeSoftwareManagementService_DownloadImageClient, error) {
	stream, err := c.cc.NewStream(ctx, &_NativeSoftwareManagementService_serviceDesc.Streams[0], "/dmi.NativeSoftwareManagementService/DownloadImage", opts...)
	if err != nil {
		return nil, err
	}
	x := &nativeSoftwareManagementServiceDownloadImageClient{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 NativeSoftwareManagementService_DownloadImageClient interface {
	Recv() (*ImageStatus, error)
	grpc.ClientStream
}

type nativeSoftwareManagementServiceDownloadImageClient struct {
	grpc.ClientStream
}

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

func (c *nativeSoftwareManagementServiceClient) ActivateImage(ctx context.Context, in *HardwareID, opts ...grpc.CallOption) (NativeSoftwareManagementService_ActivateImageClient, error) {
	stream, err := c.cc.NewStream(ctx, &_NativeSoftwareManagementService_serviceDesc.Streams[1], "/dmi.NativeSoftwareManagementService/ActivateImage", opts...)
	if err != nil {
		return nil, err
	}
	x := &nativeSoftwareManagementServiceActivateImageClient{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 NativeSoftwareManagementService_ActivateImageClient interface {
	Recv() (*ImageStatus, error)
	grpc.ClientStream
}

type nativeSoftwareManagementServiceActivateImageClient struct {
	grpc.ClientStream
}

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

func (c *nativeSoftwareManagementServiceClient) RevertToStandbyImage(ctx context.Context, in *HardwareID, opts ...grpc.CallOption) (NativeSoftwareManagementService_RevertToStandbyImageClient, error) {
	stream, err := c.cc.NewStream(ctx, &_NativeSoftwareManagementService_serviceDesc.Streams[2], "/dmi.NativeSoftwareManagementService/RevertToStandbyImage", opts...)
	if err != nil {
		return nil, err
	}
	x := &nativeSoftwareManagementServiceRevertToStandbyImageClient{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 NativeSoftwareManagementService_RevertToStandbyImageClient interface {
	Recv() (*ImageStatus, error)
	grpc.ClientStream
}

type nativeSoftwareManagementServiceRevertToStandbyImageClient struct {
	grpc.ClientStream
}

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

func (c *nativeSoftwareManagementServiceClient) UpdateStartupConfiguration(ctx context.Context, in *ConfigRequest, opts ...grpc.CallOption) (NativeSoftwareManagementService_UpdateStartupConfigurationClient, error) {
	stream, err := c.cc.NewStream(ctx, &_NativeSoftwareManagementService_serviceDesc.Streams[3], "/dmi.NativeSoftwareManagementService/UpdateStartupConfiguration", opts...)
	if err != nil {
		return nil, err
	}
	x := &nativeSoftwareManagementServiceUpdateStartupConfigurationClient{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 NativeSoftwareManagementService_UpdateStartupConfigurationClient interface {
	Recv() (*ConfigResponse, error)
	grpc.ClientStream
}

type nativeSoftwareManagementServiceUpdateStartupConfigurationClient struct {
	grpc.ClientStream
}

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

func (c *nativeSoftwareManagementServiceClient) GetStartupConfigurationInfo(ctx context.Context, in *StartupConfigInfoRequest, opts ...grpc.CallOption) (*StartupConfigInfoResponse, error) {
	out := new(StartupConfigInfoResponse)
	err := c.cc.Invoke(ctx, "/dmi.NativeSoftwareManagementService/GetStartupConfigurationInfo", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *nativeSoftwareManagementServiceClient) UploadDebugInfo(ctx context.Context, in *UploadDebugInfoRequest, opts ...grpc.CallOption) (NativeSoftwareManagementService_UploadDebugInfoClient, error) {
	stream, err := c.cc.NewStream(ctx, &_NativeSoftwareManagementService_serviceDesc.Streams[4], "/dmi.NativeSoftwareManagementService/UploadDebugInfo", opts...)
	if err != nil {
		return nil, err
	}
	x := &nativeSoftwareManagementServiceUploadDebugInfoClient{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 NativeSoftwareManagementService_UploadDebugInfoClient interface {
	Recv() (*UploadDebugInfoStatus, error)
	grpc.ClientStream
}

type nativeSoftwareManagementServiceUploadDebugInfoClient struct {
	grpc.ClientStream
}

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

// NativeSoftwareManagementServiceServer is the server API for NativeSoftwareManagementService service.
type NativeSoftwareManagementServiceServer interface {
	// Get the software version information of the Active and Standby images
	GetSoftwareVersion(context.Context, *HardwareID) (*GetSoftwareVersionInformationResponse, error)
	// Downloads and installs the image in the standby partition, returns the status/progress of the Install
	DownloadImage(*DownloadImageRequest, NativeSoftwareManagementService_DownloadImageServer) error
	// Activates and runs the OLT with the image in the standby partition. If things are fine this image will
	// henceforth be marked as the Active Partition. The old working image would remain on the Standby partition.
	// Any possibly required (sub-)steps like "commit" are left to the "Device Manager"
	ActivateImage(*HardwareID, NativeSoftwareManagementService_ActivateImageServer) error
	// Marks the image in the Standby as Active and reboots the device, so that it boots from that image which was in the standby.
	// This API is to be used if operator wants to go back to the previous software
	RevertToStandbyImage(*HardwareID, NativeSoftwareManagementService_RevertToStandbyImageServer) error
	// This API can be used to let the devices pickup their properitary configuration which they need at startup.
	UpdateStartupConfiguration(*ConfigRequest, NativeSoftwareManagementService_UpdateStartupConfigurationServer) error
	// This API can be used to retrieve information about the current startup configuration that a device is using
	GetStartupConfigurationInfo(context.Context, *StartupConfigInfoRequest) (*StartupConfigInfoResponse, error)
	// This API can be used to upload to a remote location, information useful for troubleshooting problems on the hardware
	UploadDebugInfo(*UploadDebugInfoRequest, NativeSoftwareManagementService_UploadDebugInfoServer) error
}

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

func (*UnimplementedNativeSoftwareManagementServiceServer) GetSoftwareVersion(ctx context.Context, req *HardwareID) (*GetSoftwareVersionInformationResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetSoftwareVersion not implemented")
}
func (*UnimplementedNativeSoftwareManagementServiceServer) DownloadImage(req *DownloadImageRequest, srv NativeSoftwareManagementService_DownloadImageServer) error {
	return status.Errorf(codes.Unimplemented, "method DownloadImage not implemented")
}
func (*UnimplementedNativeSoftwareManagementServiceServer) ActivateImage(req *HardwareID, srv NativeSoftwareManagementService_ActivateImageServer) error {
	return status.Errorf(codes.Unimplemented, "method ActivateImage not implemented")
}
func (*UnimplementedNativeSoftwareManagementServiceServer) RevertToStandbyImage(req *HardwareID, srv NativeSoftwareManagementService_RevertToStandbyImageServer) error {
	return status.Errorf(codes.Unimplemented, "method RevertToStandbyImage not implemented")
}
func (*UnimplementedNativeSoftwareManagementServiceServer) UpdateStartupConfiguration(req *ConfigRequest, srv NativeSoftwareManagementService_UpdateStartupConfigurationServer) error {
	return status.Errorf(codes.Unimplemented, "method UpdateStartupConfiguration not implemented")
}
func (*UnimplementedNativeSoftwareManagementServiceServer) GetStartupConfigurationInfo(ctx context.Context, req *StartupConfigInfoRequest) (*StartupConfigInfoResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetStartupConfigurationInfo not implemented")
}
func (*UnimplementedNativeSoftwareManagementServiceServer) UploadDebugInfo(req *UploadDebugInfoRequest, srv NativeSoftwareManagementService_UploadDebugInfoServer) error {
	return status.Errorf(codes.Unimplemented, "method UploadDebugInfo not implemented")
}

func RegisterNativeSoftwareManagementServiceServer(s *grpc.Server, srv NativeSoftwareManagementServiceServer) {
	s.RegisterService(&_NativeSoftwareManagementService_serviceDesc, srv)
}

func _NativeSoftwareManagementService_GetSoftwareVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HardwareID)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(NativeSoftwareManagementServiceServer).GetSoftwareVersion(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/dmi.NativeSoftwareManagementService/GetSoftwareVersion",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(NativeSoftwareManagementServiceServer).GetSoftwareVersion(ctx, req.(*HardwareID))
	}
	return interceptor(ctx, in, info, handler)
}

func _NativeSoftwareManagementService_DownloadImage_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(DownloadImageRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(NativeSoftwareManagementServiceServer).DownloadImage(m, &nativeSoftwareManagementServiceDownloadImageServer{stream})
}

type NativeSoftwareManagementService_DownloadImageServer interface {
	Send(*ImageStatus) error
	grpc.ServerStream
}

type nativeSoftwareManagementServiceDownloadImageServer struct {
	grpc.ServerStream
}

func (x *nativeSoftwareManagementServiceDownloadImageServer) Send(m *ImageStatus) error {
	return x.ServerStream.SendMsg(m)
}

func _NativeSoftwareManagementService_ActivateImage_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(HardwareID)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(NativeSoftwareManagementServiceServer).ActivateImage(m, &nativeSoftwareManagementServiceActivateImageServer{stream})
}

type NativeSoftwareManagementService_ActivateImageServer interface {
	Send(*ImageStatus) error
	grpc.ServerStream
}

type nativeSoftwareManagementServiceActivateImageServer struct {
	grpc.ServerStream
}

func (x *nativeSoftwareManagementServiceActivateImageServer) Send(m *ImageStatus) error {
	return x.ServerStream.SendMsg(m)
}

func _NativeSoftwareManagementService_RevertToStandbyImage_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(HardwareID)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(NativeSoftwareManagementServiceServer).RevertToStandbyImage(m, &nativeSoftwareManagementServiceRevertToStandbyImageServer{stream})
}

type NativeSoftwareManagementService_RevertToStandbyImageServer interface {
	Send(*ImageStatus) error
	grpc.ServerStream
}

type nativeSoftwareManagementServiceRevertToStandbyImageServer struct {
	grpc.ServerStream
}

func (x *nativeSoftwareManagementServiceRevertToStandbyImageServer) Send(m *ImageStatus) error {
	return x.ServerStream.SendMsg(m)
}

func _NativeSoftwareManagementService_UpdateStartupConfiguration_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(ConfigRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(NativeSoftwareManagementServiceServer).UpdateStartupConfiguration(m, &nativeSoftwareManagementServiceUpdateStartupConfigurationServer{stream})
}

type NativeSoftwareManagementService_UpdateStartupConfigurationServer interface {
	Send(*ConfigResponse) error
	grpc.ServerStream
}

type nativeSoftwareManagementServiceUpdateStartupConfigurationServer struct {
	grpc.ServerStream
}

func (x *nativeSoftwareManagementServiceUpdateStartupConfigurationServer) Send(m *ConfigResponse) error {
	return x.ServerStream.SendMsg(m)
}

func _NativeSoftwareManagementService_GetStartupConfigurationInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(StartupConfigInfoRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(NativeSoftwareManagementServiceServer).GetStartupConfigurationInfo(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/dmi.NativeSoftwareManagementService/GetStartupConfigurationInfo",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(NativeSoftwareManagementServiceServer).GetStartupConfigurationInfo(ctx, req.(*StartupConfigInfoRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _NativeSoftwareManagementService_UploadDebugInfo_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(UploadDebugInfoRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(NativeSoftwareManagementServiceServer).UploadDebugInfo(m, &nativeSoftwareManagementServiceUploadDebugInfoServer{stream})
}

type NativeSoftwareManagementService_UploadDebugInfoServer interface {
	Send(*UploadDebugInfoStatus) error
	grpc.ServerStream
}

type nativeSoftwareManagementServiceUploadDebugInfoServer struct {
	grpc.ServerStream
}

func (x *nativeSoftwareManagementServiceUploadDebugInfoServer) Send(m *UploadDebugInfoStatus) error {
	return x.ServerStream.SendMsg(m)
}

var _NativeSoftwareManagementService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "dmi.NativeSoftwareManagementService",
	HandlerType: (*NativeSoftwareManagementServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetSoftwareVersion",
			Handler:    _NativeSoftwareManagementService_GetSoftwareVersion_Handler,
		},
		{
			MethodName: "GetStartupConfigurationInfo",
			Handler:    _NativeSoftwareManagementService_GetStartupConfigurationInfo_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "DownloadImage",
			Handler:       _NativeSoftwareManagementService_DownloadImage_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "ActivateImage",
			Handler:       _NativeSoftwareManagementService_ActivateImage_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "RevertToStandbyImage",
			Handler:       _NativeSoftwareManagementService_RevertToStandbyImage_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "UpdateStartupConfiguration",
			Handler:       _NativeSoftwareManagementService_UpdateStartupConfiguration_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "UploadDebugInfo",
			Handler:       _NativeSoftwareManagementService_UploadDebugInfo_Handler,
			ServerStreams: true,
		},
	},
	Metadata: "dmi/sw_management_service.proto",
}
