SPON-3043 [WIP] Added Reboot of device admin based on external (northbound) config requests

Change-Id: I0af1e3aa7fd73ddc537327e94894d4050683aa3a
diff --git a/internal/pkg/onuadaptercore/onu_device_entry.go b/internal/pkg/onuadaptercore/onu_device_entry.go
index b623bf9..53101be 100644
--- a/internal/pkg/onuadaptercore/onu_device_entry.go
+++ b/internal/pkg/onuadaptercore/onu_device_entry.go
@@ -20,6 +20,9 @@
 import (
 	"context"
 	"errors"
+	"github.com/opencord/omci-lib-go"
+	me "github.com/opencord/omci-lib-go/generated"
+	"time"
 
 	//"sync"
 	//"time"
@@ -195,7 +198,8 @@
 	pMibDownloadFsm *AdapterFsm //could be handled dynamically and more general as pAdapterFsm - perhaps later
 	//remark: general usage of pAdapterFsm would require generalization of commChan  usage and internal event setting
 	//  within the FSM event procedures
-	omciMessageReceived chan bool //seperate channel needed by DownloadFsm
+	omciMessageReceived              chan bool    //seperate channel needed by DownloadFsm
+	omciRebootMessageReceivedChannel chan Message // channel needed by Reboot request
 }
 
 //OnuDeviceEntry returns a new instance of a OnuDeviceEntry
@@ -211,6 +215,7 @@
 	onuDeviceEntry.coreProxy = core_proxy
 	onuDeviceEntry.adapterProxy = adapter_proxy
 	onuDeviceEntry.devState = DeviceStatusInit
+	onuDeviceEntry.omciRebootMessageReceivedChannel = make(chan Message, 2048)
 	//openomciagent.lockDeviceHandlersMap = sync.RWMutex{}
 	//OMCI related databases are on a per-agent basis. State machines and tasks
 	//are per ONU Vendor
@@ -389,6 +394,47 @@
 	return nil
 }
 
+func (oo *OnuDeviceEntry) Reboot(ctx context.Context) error {
+	logger.Info("reboot-OnuDeviceEntry")
+	if err := oo.PDevOmciCC.sendReboot(context.TODO(), ConstDefaultOmciTimeout, true, oo.omciRebootMessageReceivedChannel); err != nil {
+		logger.Errorw("onu didn't reboot", log.Fields{"for device": oo.deviceID})
+		return err
+	}
+	logger.Info("OnuDeviceEntry-reboot")
+	return nil
+}
+
+func (oo *OnuDeviceEntry) waitForRebootResponse(responseChannel chan Message) error {
+	select {
+	case <-time.After(3 * time.Second): //3s was detected to be to less in 8*8 bbsim test with debug Info/Debug
+		logger.Warnw("Reboot timeout", log.Fields{"for device-id": oo.deviceID})
+		return errors.New("RebootTimeout")
+	case data := <-responseChannel:
+		switch data.Data.(OmciMessage).OmciMsg.MessageType {
+		case omci.RebootResponseType:
+			{
+				msgLayer := (*data.Data.(OmciMessage).OmciPacket).Layer(omci.LayerTypeRebootResponse)
+				if msgLayer == nil {
+					return errors.New("Omci Msg layer could not be detected for RebootResponseType")
+				}
+				msgObj, msgOk := msgLayer.(*omci.GetResponse)
+				if !msgOk {
+					return errors.New("Omci Msg layer could not be assigned for RebootResponseType")
+				}
+				logger.Debugw("CreateResponse Data", log.Fields{"deviceId": oo.deviceID, "data-fields": msgObj})
+				if msgObj.Result != me.Success {
+					logger.Errorw("Omci RebootResponseType Error ", log.Fields{"Error": msgObj.Result})
+					// possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
+					return errors.New("Omci RebootResponse Result Error indication")
+				}
+				return nil
+			}
+		}
+		logger.Warnw("Reboot response error", log.Fields{"for device-id": oo.deviceID})
+		return errors.New("Unexpected OmciResponse type received")
+	}
+}
+
 //Relay the InSync message via Handler to Rw core - Status update
 func (oo *OnuDeviceEntry) transferSystemEvent(dev_Event OnuDeviceEvent) error {
 	logger.Debugw("relaying system-event", log.Fields{"Event": dev_Event})