[VOL-4688] openonuAdapterGo: OMCI extended message set - derive the capability from the OMCC version
Do not merge before https://gerrit.opencord.org/c/bbsim/+/32128

Change-Id: I800f1bae3b696f320c63c80336a22f187b9c947c
diff --git a/internal/pkg/omcitst/omci_test_request.go b/internal/pkg/omcitst/omci_test_request.go
index 9f802a4..9dac298 100755
--- a/internal/pkg/omcitst/omci_test_request.go
+++ b/internal/pkg/omcitst/omci_test_request.go
@@ -19,20 +19,23 @@
 
 import (
 	"context"
+	"encoding/hex"
 	"fmt"
 
 	gp "github.com/google/gopacket"
 	"github.com/opencord/omci-lib-go/v2"
 	me "github.com/opencord/omci-lib-go/v2/generated"
-	cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
-
+	"github.com/opencord/omci-lib-go/v2/meframe"
+	oframe "github.com/opencord/omci-lib-go/v2/meframe"
 	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+	cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
 )
 
 //OmciTestRequest structure holds the information for the OMCI test
 type OmciTestRequest struct {
 	deviceID     string
 	pDevOmciCC   *cmn.OmciCC
+	extended     bool
 	started      bool
 	result       bool
 	exclusiveCc  bool
@@ -41,14 +44,18 @@
 	verifyDone   chan<- bool
 }
 
+// CTestRequestOmciTimeout - Special OMCI timeout for low prio test request
+const CTestRequestOmciTimeout = 5
+
 //NewOmciTestRequest returns a new instance of OmciTestRequest
 func NewOmciTestRequest(ctx context.Context,
-	deviceID string, omciCc *cmn.OmciCC,
+	deviceID string, omciCc *cmn.OmciCC, extended bool,
 	exclusive bool, allowFailure bool) *OmciTestRequest {
 	logger.Debug(ctx, "OmciTestRequest-init")
 	var OmciTestRequest OmciTestRequest
 	OmciTestRequest.deviceID = deviceID
 	OmciTestRequest.pDevOmciCC = omciCc
+	OmciTestRequest.extended = extended
 	OmciTestRequest.started = false
 	OmciTestRequest.result = false
 	OmciTestRequest.exclusiveCc = exclusive
@@ -66,7 +73,7 @@
 		// test functionality is limited to ONU-2G get request for the moment
 		// without yet checking the received response automatically here (might be improved ??)
 		tid := oo.pDevOmciCC.GetNextTid(false)
-		onu2gBaseGet, _ := oo.createOnu2gBaseGet(ctx, tid)
+		onu2gGet, _ := oo.createOnu2gGet(ctx, tid)
 		omciRxCallbackPair := cmn.CallbackPair{
 			CbKey: tid,
 			CbEntry: cmn.CallbackPairEntry{
@@ -75,11 +82,10 @@
 				FramePrint:    true,
 			},
 		}
-
-		logger.Debugw(ctx, "performOmciTest-start sending frame", log.Fields{"for device-id": oo.deviceID})
+		logger.Debugw(ctx, "performOmciTest-start sending frame", log.Fields{"for device-id": oo.deviceID, "onu2gGet": hex.EncodeToString(onu2gGet)})
 		// send with default timeout and normal prio
 		// Note: No reference to fetch the OMCI timeout value from configuration, so hardcode it to 10s
-		go oo.pDevOmciCC.Send(ctx, onu2gBaseGet, 10, cmn.CDefaultRetries, false, omciRxCallbackPair)
+		go oo.pDevOmciCC.Send(ctx, onu2gGet, CTestRequestOmciTimeout, cmn.CDefaultRetries, false, omciRxCallbackPair)
 
 	} else {
 		logger.Errorw(ctx, "performOmciTest: Device does not exist", log.Fields{"for device-id": oo.deviceID})
@@ -89,26 +95,40 @@
 // these are OMCI related functions, could/should be collected in a separate file? TODO!!!
 // for a simple start just included in here
 //basic approach copied from bbsim, cmp /devices/onu.go and /internal/common/omci/mibpackets.go
-func (oo *OmciTestRequest) createOnu2gBaseGet(ctx context.Context, tid uint16) ([]byte, error) {
+func (oo *OmciTestRequest) createOnu2gGet(ctx context.Context, tid uint16) ([]byte, error) {
 
-	request := &omci.GetRequest{
-		MeBasePacket: omci.MeBasePacket{
-			EntityClass:    me.Onu2GClassID,
-			EntityInstance: 0, //there is only the 0 instance of ONU2-G (still hard-coded - TODO!!!)
-		},
-		AttributeMask: 0xE000, //example hardcoded (TODO!!!) request EquId, OmccVersion, VendorCode
+	meParams := me.ParamData{
+		EntityID: 0,
+		Attributes: me.AttributeValueMap{
+			me.Onu2G_EquipmentId: "",
+			me.Onu2G_OpticalNetworkUnitManagementAndControlChannelOmccVersion: 0},
 	}
+	meInstance, omciErr := me.NewOnu2G(meParams)
+	if omciErr.GetError() == nil {
+		var messageSet omci.DeviceIdent = omci.BaselineIdent
+		if oo.extended {
+			messageSet = omci.ExtendedIdent
+		}
+		omciLayer, msgLayer, err := oframe.EncodeFrame(meInstance, omci.GetRequestType, oframe.TransactionID(tid),
+			meframe.FrameFormat(messageSet))
+		if err != nil {
+			logger.Errorw(ctx, "Cannot encode ONU2-G instance for get", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil, err
+		}
+		oo.txSeqNo = tid
 
-	oo.txSeqNo = tid
-	pkt, err := cmn.Serialize(ctx, omci.GetRequestType, request, tid)
-	if err != nil {
-		//omciLogger.WithFields(log.Fields{ ...
-		logger.Errorw(ctx, "Cannot serialize Onu2-G GetRequest", log.Fields{"device-id": oo.deviceID, "Err": err})
-		return nil, err
+		pkt, err := cmn.SerializeOmciLayer(ctx, omciLayer, msgLayer)
+		if err != nil {
+			logger.Errorw(ctx, "Cannot serialize ONU2-G get", log.Fields{
+				"Err": err, "device-id": oo.deviceID})
+			return nil, err
+		}
+		return pkt, nil
 	}
-	// hexEncode would probably work as well, but not needed and leads to wrong logs on OltAdapter frame
-	//	return hexEncode(pkt)
-	return pkt, nil
+	logger.Errorw(ctx, "Cannot generate ONU2-G", log.Fields{
+		"Err": omciErr.GetError(), "device-id": oo.deviceID})
+	return nil, omciErr.GetError()
 }
 
 //ReceiveOmciVerifyResponse supply a response handler - in this testobject the message is evaluated directly, no response channel used
@@ -133,6 +153,16 @@
 		oo.verifyDone <- false
 		return fmt.Errorf("unexpected MessageType %s", oo.deviceID)
 	}
+	if oo.extended {
+		if omciMsg.DeviceIdentifier == omci.ExtendedIdent {
+			logger.Debugw(ctx, "verify-omci-message-response", log.Fields{"correct DeviceIdentifier": omciMsg.DeviceIdentifier})
+		} else {
+			logger.Debugw(ctx, "verify-omci-message-response error", log.Fields{"incorrect DeviceIdentifier": omciMsg.DeviceIdentifier,
+				"expected": omci.ExtendedIdent})
+			oo.verifyDone <- false
+			return fmt.Errorf("unexpected DeviceIdentifier %s", oo.deviceID)
+		}
+	}
 
 	//TODO!!! further tests on the payload should be done here ...