[VOL-3493] Wrong Connectstatus of openonu go adaptor after disable device
[VOL-3495] Wrong reason of openonu go adaptor after dis-enable device

Change-Id: I64265e31bedf9264e403e94ce54e7a2ea6869f53
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index 9e98452..ee8e1b3 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -496,6 +496,7 @@
 //FlowUpdateIncremental removes and/or adds the flow changes on a given device
 func (dh *deviceHandler) FlowUpdateIncremental(apOfFlowChanges *openflow_13.FlowChanges,
 	apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
+	logger.Debugw("FlowUpdateIncremental started", log.Fields{"deviceId": dh.deviceID})
 
 	//Remove flows
 	if apOfFlowChanges.ToRemove != nil {
@@ -546,8 +547,6 @@
 }
 
 //disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
-// TODO!!! Clarify usage of this method, it is for sure not used within ONOS (OLT) device disable
-//         maybe it is obsolete by now
 func (dh *deviceHandler) disableDevice(device *voltha.Device) {
 	logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
 
@@ -563,18 +562,8 @@
 			dh.pLockStateFsm.setSuccessEvent(UniAdminStateDone)
 			dh.runUniLockFsm(true)
 		}
-
-		if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
-			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
-			logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
-		}
-		dh.deviceReason = "omci-admin-lock"
-		//200604: ConnState improved to 'unreachable' (was not set in python-code), OperState 'unknown' seems to be best choice
-		if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
-			voltha.OperStatus_UNKNOWN); err != nil {
-			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
-			logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
-		}
+		//VOL-3493/VOL-3495: postpone setting of deviceReason, conn- and operStatus until all omci-related communication regarding
+		//device disabling has finished successfully
 	}
 }
 
@@ -583,6 +572,8 @@
 	logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
 
 	// TODO!!! ConnectStatus and OperStatus to be set here could be more accurate, for now just ...(like python code)
+	logger.Debugw("call DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
+		"OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
 	if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
 		voltha.OperStatus_ACTIVE); err != nil {
 		//TODO with VOL-3045/VOL-3046: return the error and stop further processing
@@ -737,6 +728,8 @@
 		logger.Errorw("error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
 		return err
 	}
+	logger.Debugw("call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
+		"OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
 	if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
 		voltha.OperStatus_DISCOVERED); err != nil {
 		//TODO with VOL-3045/VOL-3046: return the error and stop further processing
@@ -1063,6 +1056,8 @@
 	dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
 
 	if !dh.reconciling {
+		logger.Debugw("call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
+			"OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
 		if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
 			voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
 			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
@@ -1324,6 +1319,8 @@
 		}
 		dh.deviceReason = "stopping-openomci"
 
+		logger.Debugw("call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
+			"OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
 		if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
 			voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
 			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
@@ -1432,6 +1429,8 @@
 	logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
 	//initiate DevStateUpdate
 	if !dh.reconciling {
+		logger.Debugw("call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
+			"OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
 		if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
 			voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
 			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
@@ -1701,7 +1700,7 @@
 		return
 	}
 	pLSFsm := newLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
-		sFsmName, dh.deviceID, chLSFsm)
+		sFsmName, dh, chLSFsm)
 	if pLSFsm != nil {
 		if aAdminState {
 			dh.pLockStateFsm = pLSFsm
diff --git a/internal/pkg/onuadaptercore/openonu.go b/internal/pkg/onuadaptercore/openonu.go
index 61b52f3..b1994d7 100644
--- a/internal/pkg/onuadaptercore/openonu.go
+++ b/internal/pkg/onuadaptercore/openonu.go
@@ -316,8 +316,9 @@
 	// no point in pushing omci flows if the device isn't reachable
 	if device.ConnectStatus != voltha.ConnectStatus_REACHABLE ||
 		device.AdminState != voltha.AdminState_ENABLED {
-		logger.Warnw("device disabled or offline - skipping flow-update", log.Fields{"deviceId": device.Id})
-		return errors.New("non-matching device state")
+		logger.Warnw("device disabled or offline - skipping flow-update", log.Fields{"ConnectStatus": device.ConnectStatus,
+			"AdminState": device.AdminState, "deviceId": device.Id})
+		return fmt.Errorf("non-matching device state: %s", device.Id)
 	}
 
 	// For now, there is no support for group changes (as in the actual Py-adapter code)
diff --git a/internal/pkg/onuadaptercore/uniportadmin.go b/internal/pkg/onuadaptercore/uniportadmin.go
index d196b73..0726be4 100644
--- a/internal/pkg/onuadaptercore/uniportadmin.go
+++ b/internal/pkg/onuadaptercore/uniportadmin.go
@@ -27,13 +27,14 @@
 	"github.com/opencord/omci-lib-go"
 	me "github.com/opencord/omci-lib-go/generated"
 	"github.com/opencord/voltha-lib-go/v3/pkg/log"
+	"github.com/opencord/voltha-protos/v3/go/voltha"
 	//ic "github.com/opencord/voltha-protos/v3/go/inter_container"
 	//"github.com/opencord/voltha-protos/v3/go/openflow_13"
-	//"github.com/opencord/voltha-protos/v3/go/voltha"
 )
 
 //lockStateFsm defines the structure for the state machine to lock/unlock the ONU UNI ports via OMCI
 type lockStateFsm struct {
+	pDeviceHandler           *deviceHandler
 	pOmciCC                  *omciCC
 	adminState               bool
 	requestEvent             OnuDeviceEvent
@@ -64,16 +65,17 @@
 
 //newLockStateFsm is the 'constructor' for the state machine to lock/unlock the ONU UNI ports via OMCI
 func newLockStateFsm(apDevOmciCC *omciCC, aAdminState bool, aRequestEvent OnuDeviceEvent,
-	aName string, aDeviceID string, aCommChannel chan Message) *lockStateFsm {
+	aName string, apDeviceHandler *deviceHandler, aCommChannel chan Message) *lockStateFsm {
 	instFsm := &lockStateFsm{
-		pOmciCC:      apDevOmciCC,
-		adminState:   aAdminState,
-		requestEvent: aRequestEvent,
+		pDeviceHandler: apDeviceHandler,
+		pOmciCC:        apDevOmciCC,
+		adminState:     aAdminState,
+		requestEvent:   aRequestEvent,
 	}
-	instFsm.pAdaptFsm = NewAdapterFsm(aName, aDeviceID, aCommChannel)
+	instFsm.pAdaptFsm = NewAdapterFsm(aName, apDeviceHandler.deviceID, aCommChannel)
 	if instFsm.pAdaptFsm == nil {
 		logger.Errorw("LockStateFsm's AdapterFsm could not be instantiated!!", log.Fields{
-			"device-id": aDeviceID})
+			"device-id": apDeviceHandler.deviceID})
 		return nil
 	}
 	if aAdminState { //port locking requested
@@ -145,11 +147,11 @@
 	}
 	if instFsm.pAdaptFsm.pFsm == nil {
 		logger.Errorw("LockStateFsm's Base FSM could not be instantiated!!", log.Fields{
-			"device-id": aDeviceID})
+			"device-id": apDeviceHandler.deviceID})
 		return nil
 	}
 
-	logger.Infow("LockStateFsm created", log.Fields{"device-id": aDeviceID})
+	logger.Infow("LockStateFsm created", log.Fields{"device-id": apDeviceHandler.deviceID})
 	return instFsm
 }
 
@@ -216,6 +218,26 @@
 	logger.Debugw("LockStateFSM", log.Fields{"send notification to core in State": e.FSM.Current(), "device-id": oFsm.pAdaptFsm.deviceID})
 	//use DeviceHandler event notification directly, no need/support to update DeviceEntryState for lock/unlock
 	oFsm.pOmciCC.pBaseDeviceHandler.deviceProcStatusUpdate(oFsm.requestEvent)
+
+	//VOL-3493/VOL-3495: postpone setting of deviceReason, conn- and operStatus until all omci-related communication regarding
+	//device disabling has finished successfully
+	if oFsm.adminState {
+		if err := oFsm.pDeviceHandler.coreProxy.DeviceReasonUpdate(context.TODO(),
+			oFsm.pDeviceHandler.deviceID, "omci-admin-lock"); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-updating-reason-state", log.Fields{"device-id": oFsm.pDeviceHandler.deviceID, "error": err})
+		}
+		oFsm.pDeviceHandler.deviceReason = "omci-admin-lock"
+		//200604: ConnState improved to 'unreachable' (was not set in python-code), OperState 'unknown' seems to be best choice
+		logger.Debugw("call DeviceStateUpdate", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
+			"OperStatus": voltha.OperStatus_UNKNOWN, "device-id": oFsm.pDeviceHandler.deviceID})
+		if err := oFsm.pDeviceHandler.coreProxy.DeviceStateUpdate(context.TODO(), oFsm.pDeviceHandler.deviceID,
+			voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
+			//TODO with VOL-3045/VOL-3046: return the error and stop further processing
+			logger.Errorw("error-updating-device-state", log.Fields{"device-id": oFsm.pDeviceHandler.deviceID, "error": err})
+		}
+	}
+
 	//let's reset the state machine in order to release all resources now
 	pLockStateAFsm := oFsm.pAdaptFsm
 	if pLockStateAFsm != nil {