[VOL-3548] Differentiate between OLT gRPC channel
disconnect and device reboot

Change-Id: Id52a3cf7b1a69f20e8b061d0655015857fa19ae5
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index 1e86007..8b3947e 100644
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -101,6 +101,9 @@
 	// Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
 	// A go routine per index, waits on a unique channel for incoming mcast flow or group (add/modify/remove).
 	incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
+
+	adapterPreviouslyConnected bool
+	agentPreviouslyConnected   bool
 }
 
 //OnuDevice represents ONU related info
@@ -642,6 +645,18 @@
 	raisedTs := time.Now().UnixNano()
 	go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
 
+	//check adapter and agent reconcile status
+	//reboot olt if needed (olt disconnection case)
+	if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
+		logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
+			log.Fields{
+				"device-id":      dh.device.Id,
+				"adapter-status": dh.adapterPreviouslyConnected,
+				"agent-status":   dh.agentPreviouslyConnected,
+			})
+		_ = dh.RebootDevice(ctx, dh.device)
+	}
+
 	return nil
 }
 
@@ -813,6 +828,7 @@
 		return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
 	}
 	dh.totalPonPorts = deviceInfo.GetPonPorts()
+	dh.agentPreviouslyConnected = deviceInfo.PreviouslyConnected
 
 	// Instantiate resource manager
 	if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, deviceInfo, dh.cm.Backend.PathPrefix); dh.resourceMgr == nil {
@@ -2044,6 +2060,9 @@
 		}
 		dh.lockDevice.RUnlock()
 
+		//reset adapter reconcile flag
+		dh.adapterPreviouslyConnected = false
+
 		dh.transitionMap.Handle(ctx, DeviceInit)
 
 	}