[VOL-1754] :changes to handle device states on olt disable/re-enable

Change-Id: Ied1fb534028e2a3d7b443a69540a3780aeae98c5
diff --git a/adaptercore/device_handler.go b/adaptercore/device_handler.go
index 3053f2a..ccbdc46 100644
--- a/adaptercore/device_handler.go
+++ b/adaptercore/device_handler.go
@@ -292,20 +292,12 @@
 		dh.lockDevice.RLock()
 		adminState := dh.adminState
 		dh.lockDevice.RUnlock()
-		// When OLT is admin down, allow only NNI operation status change indications.
+		// When OLT is admin down, ignore all indications.
 		if adminState == "down" {
-			_, isIntfOperInd := indication.Data.(*oop.Indication_IntfOperInd)
-			if isIntfOperInd {
-				intfOperInd := indication.GetIntfOperInd()
-				if intfOperInd.GetType() == "nni" {
-					log.Infow("olt is admin down, allow nni ind", log.Fields{})
-				}
-			} else {
-				log.Infow("olt is admin down, ignore indication", log.Fields{})
-				continue
-			}
-		}
 
+			log.Infow("olt is admin down, ignore indication", log.Fields{})
+			continue
+		}
 		dh.handleIndication(indication)
 
 	}
@@ -1025,19 +1017,23 @@
 	dh.adminState = "down"
 	dh.lockDevice.Unlock()
 	if _, err := dh.Client.DisableOlt(context.Background(), new(oop.Empty)); err != nil {
-		log.Errorw("Failed to disable olt ", log.Fields{"err": err})
-		dh.lockDevice.Lock()
-		dh.adminState = "up"
-		dh.lockDevice.Unlock()
-		return err
+		if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
+			log.Errorw("failed-to-disable-olt ", log.Fields{"err": err})
+			dh.lockDevice.Lock()
+			dh.adminState = "up"
+			dh.lockDevice.Unlock()
+			return err
+		}
+
 	}
 	log.Debug("olt-disabled")
 	dh.lockDevice.Lock()
 	/* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
 	   UNREACHABLE state which needs to be configured again*/
 	dh.discOnus = make(map[string]bool)
+	dh.onus = make(map[string]*OnuDevice)
 	dh.lockDevice.Unlock()
-
+	go dh.notifyChildDevices()
 	cloned := proto.Clone(device).(*voltha.Device)
 	// Update the all ports state on that device to disable
 	if err := dh.coreProxy.PortsStateUpdate(context.TODO(), cloned.Id, voltha.OperStatus_UNKNOWN); err != nil {
@@ -1045,10 +1041,34 @@
 		return err
 	}
 
-	log.Debugw("Disable_device-end", log.Fields{"deviceID": device.Id})
+	log.Debugw("disable-device-end", log.Fields{"deviceID": device.Id})
 	return nil
 }
 
+func (dh *DeviceHandler) notifyChildDevices() {
+
+	// Update onu state as unreachable in onu adapter
+	onuInd := oop.OnuIndication{}
+	onuInd.OperState = "unreachable"
+	//get the child device for the parent device
+	onuDevices, err := dh.coreProxy.GetChildDevices(context.TODO(), dh.device.Id)
+	if err != nil {
+		log.Errorw("failed-to-get-child-devices-information", log.Fields{"deviceID": dh.device.Id, "error": err})
+	}
+	if onuDevices != nil {
+		for _, onuDevice := range onuDevices.Items {
+			err := dh.AdapterProxy.SendInterAdapterMessage(context.TODO(), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
+				"openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
+			if err != nil {
+				log.Errorw("failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
+					"From Adapter": "openolt", "DeviceType": onuDevice.Type, "DeviceID": onuDevice.Id})
+			}
+
+		}
+	}
+
+}
+
 //ReenableDevice re-enables the olt device after disable
 //It marks the following for the given device:
 //Device-Handler Admin-State : up
@@ -1056,8 +1076,10 @@
 //Device Oper-State: ACTIVE
 func (dh *DeviceHandler) ReenableDevice(device *voltha.Device) error {
 	if _, err := dh.Client.ReenableOlt(context.Background(), new(oop.Empty)); err != nil {
-		log.Errorw("Failed to reenable olt ", log.Fields{"err": err})
-		return err
+		if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
+			log.Errorw("Failed to reenable olt ", log.Fields{"err": err})
+			return err
+		}
 	}
 
 	dh.lockDevice.Lock()