VOL-3645:Add UpdateStartupConfig RPC

Change-Id: I668c5d0e5461fcde607b3353a574069161e4456a
diff --git a/VERSION b/VERSION
index a602fc9..b0bb878 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.9.4
+0.9.5
diff --git a/dmi.pb b/dmi.pb
index 784891f..918c971 100644
--- a/dmi.pb
+++ b/dmi.pb
Binary files differ
diff --git a/docs/DeviceImageManagement.md b/docs/DeviceImageManagement.md
index 0396ad2..014859e 100644
--- a/docs/DeviceImageManagement.md
+++ b/docs/DeviceImageManagement.md
@@ -1,6 +1,6 @@
-# Software Image Management
+# Software Management
 
-The software image management that this interface addresses are for devices that can be managed over IP directly.
+The software management that this interface addresses are for devices that can be managed over IP directly.
 
 The below diagram shows the message flows for the different Image management RPCs.
 
@@ -22,16 +22,22 @@
     // 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 pervious software
     rpc RevertToStandbyImage(HardwareID) returns(stream ImageStatus);
+
+    // This API can be used to let the devices pickup their properitary configuration which they need at startup.
+    rpc UpdateStartupConfiguration(ConfigRequest) returns(stream ConfigResponse);
 }
 ```
 The download of the image always happens on the standby. As of now the support is for one active image/partition and one standby image/partition. The download procedure would encompass the download as well as installation of the image and also any required configurations to be applied.
 
 The ActivateImage RPC always would activate the standby image/partition. This will trigger a reboot of the device to boot from the standby partition/image. After the boot of the new image, some tests are expected to run to validate if the activation was successful or not and only then would the image be committed. How such tests are run are upto the implementation of the device manager. If it's not able to activate the image, then it should fall back to the previous image automatically. This is especially important for devices which are in-band managed, as there is a possiblity that management plane could lose connectivity to the device in such a state.
 
-The RevertToStandbyImage is different from ActivateImage; it assumes that the standby image/partition was already a working version and so it would not run the image activation sanity checks (the same checks which are run when during the ActivateIamge RPC) when booted from the standby image. This would help the human operator to intervene and break a loop if boot up tests keep failing. 
+The RevertToStandbyImage is different from ActivateImage; it assumes that the standby image/partition was already a working version and so it would not run the image activation sanity checks (the same checks which are run when during the ActivateIamge RPC) when booted from the standby image. This would help the human operator to intervene and break a loop if boot up tests keep failing.
 
 As the image activation sanity checks are not run in this case, it is upto to operator to ensure that the image on the standby is a good working version. Additionally implementations can cross check if the image on the standby is a good already committed version else give an error response for this rpc.
 
 The status of the download, activation or reverting are also sent to the kafka bus in addition to the return of the grpc stream. This would help other components in the system which would want to monitor the progress of such processes.
 
 In the case when an OLT device gets upgraded; for other external systems like vOLTHA, it would just be a reboot of the OLT and should be handled exactly the same way. ***If*** OLT/adapter/agent implementations stores **presistent** config on the OLT then it needs to be ensured that this is available with the upgraded image so that vOLTHA does not see any difference compared to a reboot.
+
+Some of the devices have the concept of a running and a startup configuration. The running configuration is what gets created/updated at runtime and would be dependant on what the Device Manager or VOLTHA asks the device to do. For these type of devices, every time the device boots up, it overrides it's running configuration with the startup configuration.
+The API UpdateStartupConfiguration can be used to modify this startup configuration of the devices. Most of the standard running configuration would come from VOLTHA or the Device Manager, but there could/would be some properitary configuration that the devices need and this can be modified using this API.
diff --git a/go/dmi/commons.pb.go b/go/dmi/commons.pb.go
index 91791d2..1b3b9da 100644
--- a/go/dmi/commons.pb.go
+++ b/go/dmi/commons.pb.go
@@ -61,18 +61,22 @@
 	Reason_LOGGING_ENDPOINT_PROTOCOL_ERROR Reason = 6
 	Reason_KAFKA_ENDPOINT_ERROR            Reason = 7
 	Reason_UNKNOWN_LOG_ENTITY              Reason = 8
+	Reason_ERROR_FETCHING_CONFIG           Reason = 9
+	Reason_INVALID_CONFIG                  Reason = 10
 )
 
 var Reason_name = map[int32]string{
-	0: "UNDEFINED_REASON",
-	1: "UNKNOWN_DEVICE",
-	2: "INTERNAL_ERROR",
-	3: "WRONG_METRIC",
-	4: "WRONG_EVENT",
-	5: "LOGGING_ENDPOINT_ERROR",
-	6: "LOGGING_ENDPOINT_PROTOCOL_ERROR",
-	7: "KAFKA_ENDPOINT_ERROR",
-	8: "UNKNOWN_LOG_ENTITY",
+	0:  "UNDEFINED_REASON",
+	1:  "UNKNOWN_DEVICE",
+	2:  "INTERNAL_ERROR",
+	3:  "WRONG_METRIC",
+	4:  "WRONG_EVENT",
+	5:  "LOGGING_ENDPOINT_ERROR",
+	6:  "LOGGING_ENDPOINT_PROTOCOL_ERROR",
+	7:  "KAFKA_ENDPOINT_ERROR",
+	8:  "UNKNOWN_LOG_ENTITY",
+	9:  "ERROR_FETCHING_CONFIG",
+	10: "INVALID_CONFIG",
 }
 
 var Reason_value = map[string]int32{
@@ -85,6 +89,8 @@
 	"LOGGING_ENDPOINT_PROTOCOL_ERROR": 6,
 	"KAFKA_ENDPOINT_ERROR":            7,
 	"UNKNOWN_LOG_ENTITY":              8,
+	"ERROR_FETCHING_CONFIG":           9,
+	"INVALID_CONFIG":                  10,
 }
 
 func (x Reason) String() string {
@@ -139,27 +145,29 @@
 func init() { proto.RegisterFile("dmi/commons.proto", fileDescriptor_74aedf0dda1205d8) }
 
 var fileDescriptor_74aedf0dda1205d8 = []byte{
-	// 344 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0x4d, 0x6f, 0xba, 0x30,
-	0x00, 0xc6, 0xc5, 0x17, 0xfe, 0xda, 0xff, 0x5b, 0xd7, 0x18, 0xb3, 0xec, 0xb2, 0xc3, 0x6e, 0x26,
-	0xca, 0xc1, 0xd3, 0xb2, 0x83, 0x41, 0xa8, 0xa4, 0x81, 0xb5, 0xa6, 0x14, 0xcd, 0x76, 0x21, 0x08,
-	0x1d, 0x23, 0x59, 0xa9, 0x51, 0xf4, 0xd3, 0xee, 0xc3, 0x2c, 0xe8, 0x38, 0x6c, 0xbb, 0x3d, 0xfd,
-	0x3d, 0x79, 0x7e, 0x6d, 0x52, 0x70, 0x95, 0xa9, 0xc2, 0x4a, 0xb5, 0x52, 0xba, 0x3c, 0x4c, 0x77,
-	0x7b, 0x5d, 0x69, 0xd4, 0xc9, 0x54, 0x31, 0x9e, 0x03, 0x33, 0xac, 0x92, 0xea, 0x78, 0x40, 0x43,
-	0x00, 0x23, 0xea, 0xe2, 0x25, 0xa1, 0xd8, 0x8d, 0x43, 0x61, 0x8b, 0x28, 0x84, 0x2d, 0xf4, 0x17,
-	0x0c, 0x98, 0xdf, 0x1c, 0x0d, 0x04, 0xc1, 0x1f, 0xcc, 0x39, 0xe3, 0x0d, 0x69, 0x8f, 0xdf, 0x0d,
-	0x60, 0x72, 0x99, 0x1c, 0x74, 0xf9, 0xd5, 0xc0, 0xb1, 0x1d, 0x32, 0x0a, 0x5b, 0x08, 0x81, 0x7f,
-	0x11, 0xf5, 0x29, 0xdb, 0xd0, 0xd8, 0xc5, 0x6b, 0xe2, 0x60, 0x68, 0xd4, 0x8c, 0x50, 0x81, 0x39,
-	0xb5, 0x83, 0xf8, 0xec, 0x83, 0xed, 0x5a, 0xbd, 0xe1, 0x8c, 0x7a, 0xf1, 0x23, 0x16, 0x9c, 0x38,
-	0xb0, 0x83, 0xfe, 0x83, 0xdf, 0x17, 0x82, 0xd7, 0x98, 0x0a, 0xd8, 0x45, 0x37, 0x60, 0x14, 0x30,
-	0xcf, 0x23, 0x35, 0xa2, 0xee, 0x8a, 0x11, 0x2a, 0x3e, 0xe7, 0x3d, 0x74, 0x07, 0x6e, 0x7f, 0x74,
-	0x2b, 0xce, 0x04, 0x73, 0x58, 0x73, 0x87, 0x89, 0xae, 0xc1, 0xd0, 0xb7, 0x97, 0xbe, 0xfd, 0x7d,
-	0xfe, 0x0b, 0x8d, 0x00, 0x6a, 0x5e, 0x19, 0xb0, 0x5a, 0x21, 0x88, 0x78, 0x82, 0xfd, 0xf1, 0x1c,
-	0xf4, 0x03, 0x9d, 0x07, 0xf2, 0x24, 0xdf, 0xd0, 0x00, 0xf4, 0x04, 0xb7, 0x1d, 0x0c, 0x5b, 0x75,
-	0x74, 0xf1, 0x22, 0xf2, 0xa0, 0x81, 0xfa, 0xa0, 0x4b, 0xe8, 0x92, 0xc1, 0x76, 0x9d, 0x36, 0x36,
-	0xa7, 0xb0, 0x53, 0xd7, 0x17, 0x71, 0x77, 0xf1, 0xf0, 0x7c, 0x9f, 0x17, 0xd5, 0xeb, 0x71, 0x3b,
-	0x4d, 0xb5, 0xb2, 0xf4, 0x4e, 0x96, 0xa9, 0xde, 0x67, 0x56, 0x26, 0x4f, 0x45, 0x2a, 0x27, 0x2a,
-	0x29, 0x93, 0x5c, 0x2a, 0x59, 0x56, 0x93, 0xa2, 0xac, 0xe4, 0xfe, 0x25, 0x49, 0xa5, 0x75, 0x9a,
-	0x59, 0xb9, 0xb6, 0x32, 0x55, 0x6c, 0xcd, 0xf3, 0x4f, 0xcd, 0x3e, 0x02, 0x00, 0x00, 0xff, 0xff,
-	0x79, 0x7a, 0xa9, 0x6f, 0xbe, 0x01, 0x00, 0x00,
+	// 373 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0xcf, 0x6f, 0xd3, 0x30,
+	0x14, 0xc7, 0xdb, 0xb4, 0x0b, 0xed, 0xe3, 0x97, 0xb1, 0xc6, 0x04, 0x5c, 0x38, 0x70, 0xab, 0xb4,
+	0xe5, 0xb0, 0x13, 0xe2, 0x30, 0x79, 0x89, 0x13, 0xac, 0x04, 0x7b, 0x72, 0x9c, 0x56, 0x70, 0x89,
+	0xb2, 0xc4, 0x84, 0x48, 0x38, 0x9e, 0xda, 0xac, 0xff, 0x04, 0xff, 0x34, 0x72, 0x43, 0x0e, 0xc0,
+	0xed, 0xf9, 0xf3, 0xf4, 0x3e, 0x7e, 0x5f, 0x3d, 0x78, 0xd5, 0x98, 0x2e, 0xa8, 0xad, 0x31, 0xb6,
+	0x3f, 0x5c, 0x3d, 0xec, 0xed, 0x60, 0xf1, 0xa2, 0x31, 0xdd, 0xe6, 0x06, 0xfc, 0x7c, 0xa8, 0x86,
+	0xc7, 0x03, 0x3e, 0x07, 0x54, 0xf0, 0x88, 0xc6, 0x8c, 0xd3, 0xa8, 0xcc, 0x15, 0x51, 0x45, 0x8e,
+	0x66, 0xf8, 0x39, 0xac, 0x45, 0x3a, 0x3d, 0xe7, 0x18, 0xc1, 0x33, 0x2a, 0xa5, 0x90, 0x13, 0xf1,
+	0x36, 0xbf, 0x3c, 0xf0, 0xa5, 0xae, 0x0e, 0xb6, 0xff, 0xdb, 0x20, 0x29, 0xc9, 0x05, 0x47, 0x33,
+	0x8c, 0xe1, 0x45, 0xc1, 0x53, 0x2e, 0x76, 0xbc, 0x8c, 0xe8, 0x96, 0x85, 0x14, 0xcd, 0x1d, 0x63,
+	0x5c, 0x51, 0xc9, 0x49, 0x56, 0x9e, 0x7c, 0xc8, 0x73, 0xea, 0x9d, 0x14, 0x3c, 0x29, 0xbf, 0x50,
+	0x25, 0x59, 0x88, 0x16, 0xf8, 0x25, 0x3c, 0x1d, 0x09, 0xdd, 0x52, 0xae, 0xd0, 0x12, 0xbf, 0x83,
+	0x8b, 0x4c, 0x24, 0x09, 0x73, 0x88, 0x47, 0x77, 0x82, 0x71, 0xf5, 0x67, 0xfc, 0x0c, 0x7f, 0x80,
+	0xf7, 0xff, 0xf5, 0xee, 0xa4, 0x50, 0x22, 0x14, 0xd3, 0x1f, 0x3e, 0x7e, 0x03, 0xe7, 0x29, 0x89,
+	0x53, 0xf2, 0xef, 0xf8, 0x13, 0x7c, 0x01, 0x78, 0xda, 0x32, 0x13, 0x4e, 0xa1, 0x98, 0xfa, 0x8a,
+	0x56, 0xf8, 0x2d, 0xbc, 0x1e, 0x03, 0xc7, 0x54, 0x85, 0x9f, 0x9d, 0x3d, 0x14, 0x3c, 0x66, 0x09,
+	0x5a, 0x8f, 0x21, 0xb6, 0x24, 0x63, 0xd1, 0xc4, 0x60, 0x73, 0x03, 0xab, 0xcc, 0xb6, 0x99, 0x3e,
+	0xea, 0x9f, 0x78, 0x0d, 0x67, 0x4a, 0x92, 0x90, 0xa2, 0x99, 0x2b, 0x23, 0x7a, 0x5b, 0x24, 0x68,
+	0x8e, 0x57, 0xb0, 0x64, 0x3c, 0x16, 0xc8, 0x73, 0xd5, 0x8e, 0x48, 0x8e, 0x16, 0xae, 0x3d, 0xee,
+	0xb1, 0xbc, 0xfd, 0xf4, 0xed, 0x63, 0xdb, 0x0d, 0x3f, 0x1e, 0xef, 0xaf, 0x6a, 0x6b, 0x02, 0xfb,
+	0xa0, 0xfb, 0xda, 0xee, 0x9b, 0xa0, 0xd1, 0xc7, 0xae, 0xd6, 0x97, 0xa6, 0xea, 0xab, 0x56, 0x1b,
+	0xdd, 0x0f, 0x97, 0x5d, 0x3f, 0xe8, 0xfd, 0xf7, 0xaa, 0xd6, 0xc1, 0xf1, 0x3a, 0x68, 0x6d, 0xd0,
+	0x98, 0xee, 0xde, 0x3f, 0x1d, 0xf6, 0xfa, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc8, 0xb6, 0xed,
+	0xcf, 0xed, 0x01, 0x00, 0x00,
 }
diff --git a/go/dmi/sw_management_service.pb.go b/go/dmi/sw_management_service.pb.go
index f3ef3e6..c3c2718 100644
--- a/go/dmi/sw_management_service.pb.go
+++ b/go/dmi/sw_management_service.pb.go
@@ -171,45 +171,148 @@
 	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               Reason   `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.Reason" json:"reason,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() Reason {
+	if m != nil {
+		return m.Reason
+	}
+	return Reason_UNDEFINED_REASON
+}
+
 func init() {
 	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")
 }
 
 func init() { proto.RegisterFile("dmi/sw_management_service.proto", fileDescriptor_000929e4bec891d7) }
 
 var fileDescriptor_000929e4bec891d7 = []byte{
-	// 458 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x5d, 0x6b, 0x13, 0x41,
-	0x14, 0x65, 0x13, 0x29, 0x74, 0xd6, 0x36, 0xed, 0x50, 0x21, 0xee, 0x4b, 0x4a, 0x44, 0x08, 0x85,
-	0x66, 0x65, 0xd3, 0x17, 0xad, 0x08, 0x4a, 0x41, 0xf3, 0xa0, 0xe0, 0x46, 0x7d, 0xf0, 0x65, 0x99,
-	0xec, 0xdc, 0xa4, 0x03, 0xce, 0xdc, 0x38, 0x33, 0xbb, 0xd1, 0x3f, 0xe2, 0x4f, 0xd0, 0xbf, 0x29,
-	0xf3, 0x11, 0x53, 0x69, 0x03, 0x7d, 0xdb, 0x3d, 0xf7, 0x9c, 0x33, 0x67, 0xee, 0xbd, 0x43, 0x06,
-	0x5c, 0x8a, 0xdc, 0xac, 0x2b, 0xc9, 0x14, 0x5b, 0x82, 0x04, 0x65, 0x2b, 0x03, 0xba, 0x15, 0x35,
-	0x8c, 0x57, 0x1a, 0x2d, 0xd2, 0x2e, 0x97, 0x22, 0x3b, 0x76, 0xac, 0x1a, 0xa5, 0x44, 0x65, 0x02,
-	0x9e, 0x3d, 0x74, 0xd0, 0xf5, 0x3a, 0xfe, 0xd1, 0x68, 0x23, 0x24, 0x5b, 0x46, 0xe5, 0xf0, 0x57,
-	0x42, 0xb2, 0x19, 0x2e, 0xec, 0x9a, 0x69, 0xf8, 0x02, 0xda, 0x08, 0x54, 0x53, 0xb5, 0x40, 0x2d,
-	0x99, 0x15, 0xa8, 0xe8, 0x0b, 0xd2, 0x63, 0xb5, 0x15, 0x2d, 0x54, 0x6d, 0x28, 0x9a, 0x7e, 0x72,
-	0xda, 0x1d, 0xa5, 0xc5, 0xf1, 0x98, 0x4b, 0x31, 0x9e, 0x3a, 0xa7, 0x28, 0x2b, 0x0f, 0x03, 0x33,
-	0xfe, 0x1a, 0xfa, 0x92, 0x1c, 0x19, 0xcb, 0x14, 0x9f, 0xff, 0xdc, 0x8a, 0x3b, 0xbb, 0xc4, 0xbd,
-	0x48, 0xdd, 0xa8, 0x87, 0xbf, 0x13, 0xf2, 0xf4, 0x2d, 0xd8, 0xdd, 0xd9, 0x4a, 0x30, 0x2b, 0x54,
-	0x06, 0xe8, 0x13, 0xb2, 0x67, 0x2c, 0xb3, 0x8d, 0x8b, 0x96, 0x8c, 0x0e, 0x8b, 0xd4, 0xbb, 0xcf,
-	0x3c, 0x54, 0xc6, 0x92, 0x23, 0x69, 0x60, 0x06, 0x55, 0xbf, 0x73, 0x83, 0x54, 0x7a, 0xa8, 0x8c,
-	0x25, 0x3a, 0x21, 0x0f, 0x84, 0x5a, 0x60, 0xbf, 0x7b, 0x9a, 0x8c, 0xd2, 0x62, 0x10, 0x7c, 0x76,
-	0x07, 0xf0, 0xe4, 0xe1, 0x0f, 0x72, 0x72, 0x85, 0x6b, 0xf5, 0x0d, 0x19, 0xf7, 0x37, 0x2a, 0xe1,
-	0x7b, 0x03, 0xc6, 0xd2, 0x33, 0x92, 0x72, 0x70, 0x33, 0xaa, 0x9a, 0x46, 0x70, 0x9f, 0x2d, 0x2d,
-	0xf6, 0xbd, 0xe7, 0xe7, 0x46, 0xf0, 0x92, 0x84, 0xaa, 0xfb, 0xa6, 0x17, 0x84, 0xf8, 0xa1, 0x54,
-	0xfe, 0xf8, 0x8e, 0xa7, 0x3e, 0xda, 0x36, 0xe9, 0xe6, 0xa1, 0xfb, 0x62, 0x83, 0x14, 0x7f, 0x3a,
-	0x64, 0xf0, 0x81, 0xb9, 0x9e, 0x6f, 0x42, 0xbe, 0xff, 0xb7, 0x20, 0xb3, 0xb0, 0x1f, 0xf4, 0x23,
-	0xa1, 0xb7, 0xbb, 0x48, 0x7b, 0xde, 0xfb, 0x1d, 0xd3, 0xdc, 0xa1, 0xd3, 0xab, 0xec, 0xcc, 0x03,
-	0xf7, 0xeb, 0xf7, 0x2b, 0x72, 0xf0, 0xdf, 0x85, 0xe9, 0x63, 0x2f, 0xbe, 0xab, 0x09, 0xd9, 0xd1,
-	0xf6, 0x12, 0x61, 0x20, 0xcf, 0x12, 0x7a, 0x41, 0x0e, 0x5e, 0xbb, 0x4d, 0x61, 0x16, 0x82, 0xfe,
-	0x56, 0x9a, 0xbb, 0x54, 0x97, 0xe4, 0xa4, 0x84, 0x16, 0xb4, 0xfd, 0x84, 0xb3, 0xb0, 0x2a, 0xf7,
-	0x17, 0xbf, 0xb9, 0xfc, 0xfa, 0x7c, 0x29, 0xec, 0x75, 0x33, 0x1f, 0xd7, 0x28, 0x73, 0x5c, 0x81,
-	0xaa, 0x51, 0xf3, 0x3c, 0x4c, 0xe0, 0x7c, 0xfb, 0xac, 0xce, 0x85, 0xb2, 0xa0, 0x17, 0xac, 0x86,
-	0xbc, 0x9d, 0xe4, 0x4b, 0xcc, 0xb9, 0x14, 0xf3, 0x3d, 0xff, 0x52, 0x26, 0x7f, 0x03, 0x00, 0x00,
-	0xff, 0xff, 0x6d, 0x7d, 0x3b, 0xc8, 0x86, 0x03, 0x00, 0x00,
+	// 528 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xd1, 0x8a, 0x13, 0x3d,
+	0x14, 0x66, 0xda, 0x9f, 0x85, 0x9e, 0xfe, 0x6d, 0x77, 0xe3, 0x0a, 0x75, 0x40, 0xba, 0x54, 0x84,
+	0xb2, 0xb0, 0x9d, 0xa5, 0xdd, 0x1b, 0x5d, 0x11, 0xd4, 0x85, 0xb5, 0x17, 0x0a, 0x4e, 0xad, 0x17,
+	0xbd, 0x19, 0xd2, 0x49, 0x3a, 0x1b, 0x68, 0x92, 0x31, 0xc9, 0x4c, 0xf5, 0x45, 0x7c, 0x04, 0x9f,
+	0xcf, 0x47, 0x90, 0x24, 0x53, 0xbb, 0x65, 0xb7, 0xa0, 0xe2, 0xdd, 0xe4, 0x3b, 0xe7, 0xfb, 0xce,
+	0xc9, 0x39, 0xdf, 0x04, 0x7a, 0x84, 0xb3, 0x48, 0xaf, 0x13, 0x8e, 0x05, 0xce, 0x28, 0xa7, 0xc2,
+	0x24, 0x9a, 0xaa, 0x92, 0xa5, 0x74, 0x98, 0x2b, 0x69, 0x24, 0xaa, 0x13, 0xce, 0xc2, 0x23, 0x9b,
+	0x95, 0x4a, 0xce, 0xa5, 0xd0, 0x1e, 0x0f, 0xff, 0xb7, 0xd0, 0xcd, 0xba, 0x3a, 0xa1, 0x4a, 0x86,
+	0x71, 0x9c, 0x55, 0xcc, 0xfe, 0xb7, 0x00, 0xc2, 0xa9, 0x5c, 0x9a, 0x35, 0x56, 0xf4, 0x13, 0x55,
+	0x9a, 0x49, 0x31, 0x11, 0x4b, 0xa9, 0x38, 0x36, 0x4c, 0x0a, 0xf4, 0x1c, 0x3a, 0x38, 0x35, 0xac,
+	0xa4, 0x49, 0xe9, 0x83, 0xba, 0x1b, 0x9c, 0xd4, 0x07, 0xcd, 0xd1, 0xd1, 0x90, 0x70, 0x36, 0x9c,
+	0x58, 0xa5, 0x8a, 0x16, 0xb7, 0x7d, 0x66, 0x75, 0xd4, 0xe8, 0x05, 0x1c, 0x6a, 0x83, 0x05, 0x59,
+	0x7c, 0xdd, 0x92, 0x6b, 0xfb, 0xc8, 0x9d, 0x2a, 0x75, 0xc3, 0xee, 0x7f, 0x0f, 0xe0, 0xe9, 0x35,
+	0x35, 0xfb, 0x7b, 0x8b, 0xa9, 0xce, 0xa5, 0xd0, 0x14, 0x3d, 0x81, 0x03, 0x6d, 0xb0, 0x29, 0x6c,
+	0x6b, 0xc1, 0xa0, 0x3d, 0x6a, 0x3a, 0xf5, 0xa9, 0x83, 0xe2, 0x2a, 0x64, 0x93, 0x14, 0xc5, 0x5a,
+	0x8a, 0x6e, 0xed, 0x56, 0x52, 0xec, 0xa0, 0xb8, 0x0a, 0xa1, 0x31, 0xfc, 0xc7, 0xc4, 0x52, 0x76,
+	0xeb, 0x27, 0xc1, 0xa0, 0x39, 0xea, 0x79, 0x9d, 0xfd, 0x0d, 0xb8, 0xe4, 0xfe, 0x17, 0x38, 0xbe,
+	0x92, 0x6b, 0xb1, 0x92, 0x98, 0xb8, 0x1b, 0xc5, 0xf4, 0x73, 0x41, 0xb5, 0x41, 0xa7, 0xd0, 0x24,
+	0xd4, 0xee, 0x28, 0x29, 0x0a, 0x46, 0x5c, 0x6f, 0xcd, 0x51, 0xc3, 0x69, 0xce, 0x0a, 0x46, 0x62,
+	0xf0, 0x51, 0xfb, 0x8d, 0x2e, 0x00, 0xdc, 0x52, 0x12, 0x57, 0xbe, 0xe6, 0x52, 0x1f, 0x6e, 0x87,
+	0x74, 0xbb, 0x68, 0x83, 0x6d, 0x90, 0xfe, 0x1c, 0x5a, 0x6f, 0xa4, 0x58, 0xb2, 0xec, 0x6f, 0x4a,
+	0x3e, 0x06, 0x48, 0x1d, 0x39, 0x29, 0xd4, 0xca, 0x95, 0x6c, 0xc4, 0x0d, 0x8f, 0xcc, 0xd4, 0xaa,
+	0x3f, 0x87, 0xf6, 0x46, 0xfb, 0x5f, 0x8f, 0x79, 0xf4, 0xa3, 0x06, 0xbd, 0xf7, 0xd8, 0x7a, 0x65,
+	0x33, 0xdc, 0x77, 0xbf, 0x8c, 0x3d, 0xf5, 0xbe, 0x46, 0x1f, 0x00, 0xdd, 0xdd, 0x3e, 0xea, 0x38,
+	0xb9, 0xb7, 0x58, 0x11, 0x8b, 0x4e, 0xae, 0xc2, 0x53, 0x07, 0xfc, 0x9e, 0x4f, 0x5e, 0x42, 0x6b,
+	0x67, 0x51, 0xe8, 0x91, 0x23, 0xdf, 0xb7, 0xbc, 0xf0, 0x70, 0x3b, 0x7c, 0x7f, 0xc3, 0xf3, 0x00,
+	0x5d, 0x40, 0xeb, 0x95, 0x75, 0x38, 0x36, 0xd4, 0xf3, 0xef, 0x74, 0x73, 0x1f, 0xeb, 0x12, 0x8e,
+	0x63, 0x5a, 0x52, 0x65, 0x3e, 0xca, 0xa9, 0xb7, 0xf8, 0x1f, 0x90, 0xaf, 0x21, 0x9c, 0xe5, 0x04,
+	0x1b, 0x8b, 0x28, 0x53, 0xe4, 0x7e, 0x25, 0x85, 0xf2, 0x3f, 0x27, 0x72, 0x8c, 0x1d, 0x0b, 0x84,
+	0x0f, 0x76, 0x30, 0x7f, 0xf3, 0xf3, 0xe0, 0xf5, 0xe5, 0xfc, 0x59, 0xc6, 0xcc, 0x4d, 0xb1, 0x18,
+	0xa6, 0x92, 0x47, 0x32, 0xa7, 0x22, 0x95, 0x8a, 0x44, 0xde, 0x0f, 0x67, 0xdb, 0x77, 0xe5, 0x8c,
+	0x09, 0x43, 0xd5, 0x12, 0xa7, 0x34, 0x2a, 0xc7, 0x51, 0x26, 0x23, 0xc2, 0xd9, 0xe2, 0xc0, 0x3d,
+	0x15, 0xe3, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9c, 0xd0, 0x0a, 0x81, 0x87, 0x04, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -235,6 +338,8 @@
 	// 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)
 }
 
 type nativeSoftwareManagementServiceClient struct {
@@ -350,6 +455,38 @@
 	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
+}
+
 // NativeSoftwareManagementServiceServer is the server API for NativeSoftwareManagementService service.
 type NativeSoftwareManagementServiceServer interface {
 	// Get the software version information of the Active and Standby images
@@ -363,6 +500,8 @@
 	// 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
 }
 
 func RegisterNativeSoftwareManagementServiceServer(s *grpc.Server, srv NativeSoftwareManagementServiceServer) {
@@ -450,6 +589,27 @@
 	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)
+}
+
 var _NativeSoftwareManagementService_serviceDesc = grpc.ServiceDesc{
 	ServiceName: "dmi.NativeSoftwareManagementService",
 	HandlerType: (*NativeSoftwareManagementServiceServer)(nil),
@@ -475,6 +635,11 @@
 			Handler:       _NativeSoftwareManagementService_RevertToStandbyImage_Handler,
 			ServerStreams: true,
 		},
+		{
+			StreamName:    "UpdateStartupConfiguration",
+			Handler:       _NativeSoftwareManagementService_UpdateStartupConfiguration_Handler,
+			ServerStreams: true,
+		},
 	},
 	Metadata: "dmi/sw_management_service.proto",
 }
diff --git a/protos/dmi/commons.proto b/protos/dmi/commons.proto
index 61d6466..4b9757b 100644
--- a/protos/dmi/commons.proto
+++ b/protos/dmi/commons.proto
@@ -22,6 +22,8 @@
     LOGGING_ENDPOINT_PROTOCOL_ERROR = 6;
     KAFKA_ENDPOINT_ERROR = 7;
     UNKNOWN_LOG_ENTITY = 8;
+    ERROR_FETCHING_CONFIG = 9;
+    INVALID_CONFIG = 10;
 }
 
 //Log Level
diff --git a/protos/dmi/sw_management_service.proto b/protos/dmi/sw_management_service.proto
index 69de70d..3dda39f 100644
--- a/protos/dmi/sw_management_service.proto
+++ b/protos/dmi/sw_management_service.proto
@@ -29,6 +29,19 @@
     ImageInformation image_info = 2;

 }

 

+message ConfigRequest {

+    Uuid device_uuid = 1;

+    // 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

+    string config_url = 2;

+}

+

+message ConfigResponse {

+    Status status = 1;

+    Reason reason = 2;

+}

+

 service NativeSoftwareManagementService {

     // Get the software version information of the Active and Standby images

     rpc GetSoftwareVersion(HardwareID) returns(GetSoftwareVersionInformationResponse);

@@ -45,6 +58,9 @@
     // This API is to be used if operator wants to go back to the previous software

     rpc RevertToStandbyImage(HardwareID) returns(stream ImageStatus);

 

+    // This API can be used to let the devices pickup their properitary configuration which they need at startup.

+    rpc UpdateStartupConfiguration(ConfigRequest) returns(stream ConfigResponse);

+

     // If needed we can add this later

     //rpc SubscribeToEvents() returns (stream );

 }

diff --git a/python/dmi/commons_pb2.py b/python/dmi/commons_pb2.py
index 411acd1..ce1e20b 100644
--- a/python/dmi/commons_pb2.py
+++ b/python/dmi/commons_pb2.py
@@ -20,7 +20,7 @@
   syntax='proto3',
   serialized_options=b'Z9github.com/opencord/device-management-interface/v3/go/dmi',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x11\x64mi/commons.proto\x12\x03\x64mi*?\n\x06Status\x12\x14\n\x10UNDEFINED_STATUS\x10\x00\x12\r\n\tOK_STATUS\x10\x01\x12\x10\n\x0c\x45RROR_STATUS\x10\x02*\xdc\x01\n\x06Reason\x12\x14\n\x10UNDEFINED_REASON\x10\x00\x12\x12\n\x0eUNKNOWN_DEVICE\x10\x01\x12\x12\n\x0eINTERNAL_ERROR\x10\x02\x12\x10\n\x0cWRONG_METRIC\x10\x03\x12\x0f\n\x0bWRONG_EVENT\x10\x04\x12\x1a\n\x16LOGGING_ENDPOINT_ERROR\x10\x05\x12#\n\x1fLOGGING_ENDPOINT_PROTOCOL_ERROR\x10\x06\x12\x18\n\x14KAFKA_ENDPOINT_ERROR\x10\x07\x12\x16\n\x12UNKNOWN_LOG_ENTITY\x10\x08*?\n\x08LogLevel\x12\t\n\x05TRACE\x10\x00\x12\t\n\x05\x44\x45\x42UG\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\x08\n\x04WARN\x10\x03\x12\t\n\x05\x45RROR\x10\x04\x42;Z9github.com/opencord/device-management-interface/v3/go/dmib\x06proto3'
+  serialized_pb=b'\n\x11\x64mi/commons.proto\x12\x03\x64mi*?\n\x06Status\x12\x14\n\x10UNDEFINED_STATUS\x10\x00\x12\r\n\tOK_STATUS\x10\x01\x12\x10\n\x0c\x45RROR_STATUS\x10\x02*\x8b\x02\n\x06Reason\x12\x14\n\x10UNDEFINED_REASON\x10\x00\x12\x12\n\x0eUNKNOWN_DEVICE\x10\x01\x12\x12\n\x0eINTERNAL_ERROR\x10\x02\x12\x10\n\x0cWRONG_METRIC\x10\x03\x12\x0f\n\x0bWRONG_EVENT\x10\x04\x12\x1a\n\x16LOGGING_ENDPOINT_ERROR\x10\x05\x12#\n\x1fLOGGING_ENDPOINT_PROTOCOL_ERROR\x10\x06\x12\x18\n\x14KAFKA_ENDPOINT_ERROR\x10\x07\x12\x16\n\x12UNKNOWN_LOG_ENTITY\x10\x08\x12\x19\n\x15\x45RROR_FETCHING_CONFIG\x10\t\x12\x12\n\x0eINVALID_CONFIG\x10\n*?\n\x08LogLevel\x12\t\n\x05TRACE\x10\x00\x12\t\n\x05\x44\x45\x42UG\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\x08\n\x04WARN\x10\x03\x12\t\n\x05\x45RROR\x10\x04\x42;Z9github.com/opencord/device-management-interface/v3/go/dmib\x06proto3'
 )
 
 _STATUS = _descriptor.EnumDescriptor(
@@ -106,11 +106,21 @@
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='ERROR_FETCHING_CONFIG', index=9, number=9,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='INVALID_CONFIG', index=10, number=10,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
   ],
   containing_type=None,
   serialized_options=None,
   serialized_start=92,
-  serialized_end=312,
+  serialized_end=359,
 )
 _sym_db.RegisterEnumDescriptor(_REASON)
 
@@ -150,8 +160,8 @@
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=314,
-  serialized_end=377,
+  serialized_start=361,
+  serialized_end=424,
 )
 _sym_db.RegisterEnumDescriptor(_LOGLEVEL)
 
@@ -168,6 +178,8 @@
 LOGGING_ENDPOINT_PROTOCOL_ERROR = 6
 KAFKA_ENDPOINT_ERROR = 7
 UNKNOWN_LOG_ENTITY = 8
+ERROR_FETCHING_CONFIG = 9
+INVALID_CONFIG = 10
 TRACE = 0
 DEBUG = 1
 INFO = 2
diff --git a/python/dmi/sw_management_service_pb2.py b/python/dmi/sw_management_service_pb2.py
index cc5d459..a21d9cb 100644
--- a/python/dmi/sw_management_service_pb2.py
+++ b/python/dmi/sw_management_service_pb2.py
@@ -22,7 +22,7 @@
   syntax='proto3',
   serialized_options=b'Z9github.com/opencord/device-management-interface/v3/go/dmi',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x1f\x64mi/sw_management_service.proto\x12\x03\x64mi\x1a\x11\x64mi/commons.proto\x1a\x0c\x64mi/hw.proto\x1a\x12\x64mi/sw_image.proto\"u\n\x1aSoftwareVersionInformation\x12*\n\x0f\x61\x63tive_versions\x18\x01 \x03(\x0b\x32\x11.dmi.ImageVersion\x12+\n\x10standby_versions\x18\x02 \x03(\x0b\x32\x11.dmi.ImageVersion\"\x90\x01\n%GetSoftwareVersionInformationResponse\x12\x1b\n\x06status\x18\x01 \x01(\x0e\x32\x0b.dmi.Status\x12\x1b\n\x06reason\x18\x02 \x01(\x0e\x32\x0b.dmi.Reason\x12-\n\x04info\x18\x03 \x01(\x0b\x32\x1f.dmi.SoftwareVersionInformation\"a\n\x14\x44ownloadImageRequest\x12\x1e\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\t.dmi.Uuid\x12)\n\nimage_info\x18\x02 \x01(\x0b\x32\x15.dmi.ImageInformation2\xa7\x02\n\x1fNativeSoftwareManagementService\x12Q\n\x12GetSoftwareVersion\x12\x0f.dmi.HardwareID\x1a*.dmi.GetSoftwareVersionInformationResponse\x12>\n\rDownloadImage\x12\x19.dmi.DownloadImageRequest\x1a\x10.dmi.ImageStatus0\x01\x12\x34\n\rActivateImage\x12\x0f.dmi.HardwareID\x1a\x10.dmi.ImageStatus0\x01\x12;\n\x14RevertToStandbyImage\x12\x0f.dmi.HardwareID\x1a\x10.dmi.ImageStatus0\x01\x42;Z9github.com/opencord/device-management-interface/v3/go/dmib\x06proto3'
+  serialized_pb=b'\n\x1f\x64mi/sw_management_service.proto\x12\x03\x64mi\x1a\x11\x64mi/commons.proto\x1a\x0c\x64mi/hw.proto\x1a\x12\x64mi/sw_image.proto\"u\n\x1aSoftwareVersionInformation\x12*\n\x0f\x61\x63tive_versions\x18\x01 \x03(\x0b\x32\x11.dmi.ImageVersion\x12+\n\x10standby_versions\x18\x02 \x03(\x0b\x32\x11.dmi.ImageVersion\"\x90\x01\n%GetSoftwareVersionInformationResponse\x12\x1b\n\x06status\x18\x01 \x01(\x0e\x32\x0b.dmi.Status\x12\x1b\n\x06reason\x18\x02 \x01(\x0e\x32\x0b.dmi.Reason\x12-\n\x04info\x18\x03 \x01(\x0b\x32\x1f.dmi.SoftwareVersionInformation\"a\n\x14\x44ownloadImageRequest\x12\x1e\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\t.dmi.Uuid\x12)\n\nimage_info\x18\x02 \x01(\x0b\x32\x15.dmi.ImageInformation\"C\n\rConfigRequest\x12\x1e\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\t.dmi.Uuid\x12\x12\n\nconfig_url\x18\x02 \x01(\t\"J\n\x0e\x43onfigResponse\x12\x1b\n\x06status\x18\x01 \x01(\x0e\x32\x0b.dmi.Status\x12\x1b\n\x06reason\x18\x02 \x01(\x0e\x32\x0b.dmi.Reason2\xf0\x02\n\x1fNativeSoftwareManagementService\x12Q\n\x12GetSoftwareVersion\x12\x0f.dmi.HardwareID\x1a*.dmi.GetSoftwareVersionInformationResponse\x12>\n\rDownloadImage\x12\x19.dmi.DownloadImageRequest\x1a\x10.dmi.ImageStatus0\x01\x12\x34\n\rActivateImage\x12\x0f.dmi.HardwareID\x1a\x10.dmi.ImageStatus0\x01\x12;\n\x14RevertToStandbyImage\x12\x0f.dmi.HardwareID\x1a\x10.dmi.ImageStatus0\x01\x12G\n\x1aUpdateStartupConfiguration\x12\x12.dmi.ConfigRequest\x1a\x13.dmi.ConfigResponse0\x01\x42;Z9github.com/opencord/device-management-interface/v3/go/dmib\x06proto3'
   ,
   dependencies=[dmi_dot_commons__pb2.DESCRIPTOR,dmi_dot_hw__pb2.DESCRIPTOR,dmi_dot_sw__image__pb2.DESCRIPTOR,])
 
@@ -152,6 +152,84 @@
   serialized_end=456,
 )
 
+
+_CONFIGREQUEST = _descriptor.Descriptor(
+  name='ConfigRequest',
+  full_name='dmi.ConfigRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_uuid', full_name='dmi.ConfigRequest.device_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='config_url', full_name='dmi.ConfigRequest.config_url', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=458,
+  serialized_end=525,
+)
+
+
+_CONFIGRESPONSE = _descriptor.Descriptor(
+  name='ConfigResponse',
+  full_name='dmi.ConfigResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='status', full_name='dmi.ConfigResponse.status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='reason', full_name='dmi.ConfigResponse.reason', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=527,
+  serialized_end=601,
+)
+
 _SOFTWAREVERSIONINFORMATION.fields_by_name['active_versions'].message_type = dmi_dot_sw__image__pb2._IMAGEVERSION
 _SOFTWAREVERSIONINFORMATION.fields_by_name['standby_versions'].message_type = dmi_dot_sw__image__pb2._IMAGEVERSION
 _GETSOFTWAREVERSIONINFORMATIONRESPONSE.fields_by_name['status'].enum_type = dmi_dot_commons__pb2._STATUS
@@ -159,9 +237,14 @@
 _GETSOFTWAREVERSIONINFORMATIONRESPONSE.fields_by_name['info'].message_type = _SOFTWAREVERSIONINFORMATION
 _DOWNLOADIMAGEREQUEST.fields_by_name['device_uuid'].message_type = dmi_dot_hw__pb2._UUID
 _DOWNLOADIMAGEREQUEST.fields_by_name['image_info'].message_type = dmi_dot_sw__image__pb2._IMAGEINFORMATION
+_CONFIGREQUEST.fields_by_name['device_uuid'].message_type = dmi_dot_hw__pb2._UUID
+_CONFIGRESPONSE.fields_by_name['status'].enum_type = dmi_dot_commons__pb2._STATUS
+_CONFIGRESPONSE.fields_by_name['reason'].enum_type = dmi_dot_commons__pb2._REASON
 DESCRIPTOR.message_types_by_name['SoftwareVersionInformation'] = _SOFTWAREVERSIONINFORMATION
 DESCRIPTOR.message_types_by_name['GetSoftwareVersionInformationResponse'] = _GETSOFTWAREVERSIONINFORMATIONRESPONSE
 DESCRIPTOR.message_types_by_name['DownloadImageRequest'] = _DOWNLOADIMAGEREQUEST
+DESCRIPTOR.message_types_by_name['ConfigRequest'] = _CONFIGREQUEST
+DESCRIPTOR.message_types_by_name['ConfigResponse'] = _CONFIGRESPONSE
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 SoftwareVersionInformation = _reflection.GeneratedProtocolMessageType('SoftwareVersionInformation', (_message.Message,), {
@@ -185,6 +268,20 @@
   })
 _sym_db.RegisterMessage(DownloadImageRequest)
 
+ConfigRequest = _reflection.GeneratedProtocolMessageType('ConfigRequest', (_message.Message,), {
+  'DESCRIPTOR' : _CONFIGREQUEST,
+  '__module__' : 'dmi.sw_management_service_pb2'
+  # @@protoc_insertion_point(class_scope:dmi.ConfigRequest)
+  })
+_sym_db.RegisterMessage(ConfigRequest)
+
+ConfigResponse = _reflection.GeneratedProtocolMessageType('ConfigResponse', (_message.Message,), {
+  'DESCRIPTOR' : _CONFIGRESPONSE,
+  '__module__' : 'dmi.sw_management_service_pb2'
+  # @@protoc_insertion_point(class_scope:dmi.ConfigResponse)
+  })
+_sym_db.RegisterMessage(ConfigResponse)
+
 
 DESCRIPTOR._options = None
 
@@ -195,8 +292,8 @@
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=459,
-  serialized_end=754,
+  serialized_start=604,
+  serialized_end=972,
   methods=[
   _descriptor.MethodDescriptor(
     name='GetSoftwareVersion',
@@ -238,6 +335,16 @@
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='UpdateStartupConfiguration',
+    full_name='dmi.NativeSoftwareManagementService.UpdateStartupConfiguration',
+    index=4,
+    containing_service=None,
+    input_type=_CONFIGREQUEST,
+    output_type=_CONFIGRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
 ])
 _sym_db.RegisterServiceDescriptor(_NATIVESOFTWAREMANAGEMENTSERVICE)
 
diff --git a/python/dmi/sw_management_service_pb2_grpc.py b/python/dmi/sw_management_service_pb2_grpc.py
index b9669b7..f8b076e 100644
--- a/python/dmi/sw_management_service_pb2_grpc.py
+++ b/python/dmi/sw_management_service_pb2_grpc.py
@@ -36,6 +36,11 @@
                 request_serializer=dmi_dot_hw__pb2.HardwareID.SerializeToString,
                 response_deserializer=dmi_dot_sw__image__pb2.ImageStatus.FromString,
                 )
+        self.UpdateStartupConfiguration = channel.unary_stream(
+                '/dmi.NativeSoftwareManagementService/UpdateStartupConfiguration',
+                request_serializer=dmi_dot_sw__management__service__pb2.ConfigRequest.SerializeToString,
+                response_deserializer=dmi_dot_sw__management__service__pb2.ConfigResponse.FromString,
+                )
 
 
 class NativeSoftwareManagementServiceServicer(object):
@@ -72,6 +77,13 @@
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
+    def UpdateStartupConfiguration(self, request, context):
+        """This API can be used to let the devices pickup their properitary configuration which they need at startup.

+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
 
 def add_NativeSoftwareManagementServiceServicer_to_server(servicer, server):
     rpc_method_handlers = {
@@ -95,6 +107,11 @@
                     request_deserializer=dmi_dot_hw__pb2.HardwareID.FromString,
                     response_serializer=dmi_dot_sw__image__pb2.ImageStatus.SerializeToString,
             ),
+            'UpdateStartupConfiguration': grpc.unary_stream_rpc_method_handler(
+                    servicer.UpdateStartupConfiguration,
+                    request_deserializer=dmi_dot_sw__management__service__pb2.ConfigRequest.FromString,
+                    response_serializer=dmi_dot_sw__management__service__pb2.ConfigResponse.SerializeToString,
+            ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
             'dmi.NativeSoftwareManagementService', rpc_method_handlers)
@@ -172,3 +189,20 @@
             dmi_dot_sw__image__pb2.ImageStatus.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def UpdateStartupConfiguration(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_stream(request, target, '/dmi.NativeSoftwareManagementService/UpdateStartupConfiguration',
+            dmi_dot_sw__management__service__pb2.ConfigRequest.SerializeToString,
+            dmi_dot_sw__management__service__pb2.ConfigResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)