[VOL-3832] Reporting correct EntityIDs dirung the MIB Upload process

Change-Id: I8e3e8998abc0d495495c1699aa17fa582241ec32
diff --git a/internal/common/omci/mibpackets.go b/internal/common/omci/mibpackets.go
index 5e25d7f..6d22200 100755
--- a/internal/common/omci/mibpackets.go
+++ b/internal/common/omci/mibpackets.go
@@ -18,26 +18,28 @@
 
 import (
 	"errors"
+	"fmt"
 	"github.com/google/gopacket"
 	"github.com/opencord/omci-lib-go"
 	me "github.com/opencord/omci-lib-go/generated"
 	log "github.com/sirupsen/logrus"
+	"strconv"
 )
 
 var omciLogger = log.WithFields(log.Fields{
 	"module": "OMCI",
 })
 
-const galEthernetEID = uint16(1)
-const maxGemPayloadSize = uint16(48)
-const gemEID = uint16(1)
-
-type txFrameCreator func() ([]byte, error)
-type rxFrameParser func(gopacket.Packet) error
-
-type ServiceStep struct {
-	MakeTxFrame txFrameCreator
-	RxHandler   rxFrameParser
+// we have a fixed number of 8 T-CONTS
+var reportedTcontsMeId = []uint16{
+	32769,
+	32770,
+	32771,
+	32772,
+	32773,
+	32774,
+	32775,
+	32776,
 }
 
 // NOTE this is basically the same as https://github.com/opencord/voltha-openonu-adapter-go/blob/master/internal/pkg/onuadaptercore/omci_cc.go#L545-L564
@@ -181,101 +183,107 @@
 		"CommandSequenceNumber": msgObj.CommandSequenceNumber,
 	}).Trace("received-omci-mibUploadNext-request")
 
-	// depending on the sequenceNumber we'll report a different
-	reportedMe := &me.ManagedEntity{}
+	var reportedMe *me.ManagedEntity
 	var meErr me.OmciErrors
-	//var entityInstance uint16
+
 	switch msgObj.CommandSequenceNumber {
 	case 0:
 		reportedMe, meErr = me.NewOnuData(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId": me.OnuDataClassID,
-			"MibDataSync":     mds,
+			"MibDataSync": mds,
 		}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewOnuData %v", meErr.Error())
 		}
 
 	case 1:
-		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId": me.CircuitPackClassID,
-			"Type":            47,
-			"NumberOfPorts":   4,
-			"SerialNumber":    toOctets("BBSM-Circuit-Pack", 20),
-			"Version":         toOctets("v0.0.1", 20),
-		}})
+		reportedMe, meErr = me.NewCircuitPack(me.ParamData{
+			EntityID: 257, // first UNI
+			Attributes: me.AttributeValueMap{
+				"Type":          47,
+				"NumberOfPorts": 4,
+				"SerialNumber":  toOctets("BBSM-Circuit-Pack", 20),
+				"Version":       toOctets("v0.0.1", 20),
+			}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
 		}
 	case 2:
-		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":     me.CircuitPackClassID,
-			"VendorId":            "ONF",
-			"AdministrativeState": 0,
-			"OperationalState":    0,
-			"BridgedOrIpInd":      0,
-		}})
+		reportedMe, meErr = me.NewCircuitPack(me.ParamData{
+			EntityID: 257, // first UNI
+			Attributes: me.AttributeValueMap{
+				"VendorId":            "ONF",
+				"AdministrativeState": 0,
+				"OperationalState":    0,
+				"BridgedOrIpInd":      0,
+			}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
 		}
 	case 3:
-		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":             me.CircuitPackClassID,
-			"EquipmentId":                 toOctets("BBSM-Circuit-Pack", 20),
-			"CardConfiguration":           0,
-			"TotalTContBufferNumber":      0,
-			"TotalPriorityQueueNumber":    8,
-			"TotalTrafficSchedulerNumber": 0,
-		}})
+		reportedMe, meErr = me.NewCircuitPack(me.ParamData{
+			EntityID: 257, // first UNI
+			Attributes: me.AttributeValueMap{
+				"EquipmentId":                 toOctets("BBSM-Circuit-Pack", 20),
+				"CardConfiguration":           0,
+				"TotalTContBufferNumber":      8,
+				"TotalPriorityQueueNumber":    8,
+				"TotalTrafficSchedulerNumber": 16,
+			}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
 		}
 	case 4:
-		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":   me.CircuitPackClassID,
-			"PowerShedOverride": uint32(0),
-		}})
+		reportedMe, meErr = me.NewCircuitPack(me.ParamData{
+			EntityID: 257, // first UNI
+			Attributes: me.AttributeValueMap{
+				"PowerShedOverride": uint32(0),
+			}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
 		}
 	case 5:
-		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId": me.CircuitPackClassID,
-			"Type":            238,
-			"NumberOfPorts":   1,
-			"SerialNumber":    toOctets("BBSM-Circuit-Pack-2", 20),
-			"Version":         toOctets("v0.0.1", 20),
-		}})
+		reportedMe, meErr = me.NewCircuitPack(me.ParamData{
+			EntityID: 257,
+			Attributes: me.AttributeValueMap{
+				"Type":          238,
+				"NumberOfPorts": 4, //number of UNI for this device
+				"SerialNumber":  toOctets("BBSM-Circuit-Pack-2", 20),
+				"Version":       toOctets("v0.0.1", 20),
+			}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
 		}
 	case 6:
-		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":     me.CircuitPackClassID,
-			"VendorId":            "ONF",
-			"AdministrativeState": 0,
-			"OperationalState":    0,
-			"BridgedOrIpInd":      0,
-		}})
+		reportedMe, meErr = me.NewCircuitPack(me.ParamData{
+			EntityID: 257, // first UNI
+			Attributes: me.AttributeValueMap{
+				"VendorId":            "ONF",
+				"AdministrativeState": 0,
+				"OperationalState":    0,
+				"BridgedOrIpInd":      0,
+			}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
 		}
 	case 7:
-		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":             me.CircuitPackClassID,
-			"EquipmentId":                 toOctets("BBSM-Circuit-Pack", 20),
-			"CardConfiguration":           0,
-			"TotalTContBufferNumber":      8,
-			"TotalPriorityQueueNumber":    40,
-			"TotalTrafficSchedulerNumber": 10,
-		}})
+		reportedMe, meErr = me.NewCircuitPack(me.ParamData{
+			EntityID: 257, // first UNI
+			Attributes: me.AttributeValueMap{
+				"EquipmentId":                 toOctets("BBSM-Circuit-Pack", 20),
+				"CardConfiguration":           0,
+				"TotalTContBufferNumber":      0,
+				"TotalPriorityQueueNumber":    8,
+				"TotalTrafficSchedulerNumber": 0,
+			}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
 		}
 	case 8:
-		reportedMe, meErr = me.NewCircuitPack(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":   me.CircuitPackClassID,
-			"PowerShedOverride": uint32(0),
-		}})
+		reportedMe, meErr = me.NewCircuitPack(me.ParamData{
+			EntityID: 257, // first UNI
+			Attributes: me.AttributeValueMap{
+				"PowerShedOverride": uint32(0),
+			}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewCircuitPack %v", meErr.Error())
 		}
@@ -305,47 +313,57 @@
 			omciLogger.Errorf("NewPhysicalPathTerminationPointEthernetUni %v", meErr.Error())
 		}
 	case 13, 14, 15, 16, 17, 18, 19, 20:
-		// TODO report different MeID (see omci-sim pcap filter "frame[22:2] == 01:06")
-		reportedMe, meErr = me.NewTCont(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId": me.TContClassID,
-			"AllocId":         0,
-		}})
+		reportedMe, meErr = me.NewTCont(me.ParamData{
+			// NOTE fetch the correct T-CONT MeID based on the sequence number
+			EntityID: reportedTcontsMeId[msgObj.CommandSequenceNumber-13],
+			Attributes: me.AttributeValueMap{
+				"AllocId": 65535,
+			},
+		})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewTCont %v", meErr.Error())
 		}
 	case 21:
-		reportedMe, meErr = me.NewAniG(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":             me.AniGClassID,
-			"SrIndication":                1,
-			"TotalTcontNumber":            8,
-			"GemBlockLength":              30,
-			"PiggybackDbaReporting":       0,
-			"Deprecated":                  0,
-			"SignalFailThreshold":         5,
-			"SignalDegradeThreshold":      9,
-			"Arc":                         0,
-			"ArcInterval":                 0,
-			"OpticalSignalLevel":          57428,
-			"LowerOpticalThreshold":       255,
-			"UpperOpticalThreshold":       255,
-			"OnuResponseTime":             0,
-			"TransmitOpticalLevel":        3171,
-			"LowerTransmitPowerThreshold": 129,
-			"UpperTransmitPowerThreshold": 129,
-		}})
+		reportedMe, meErr = me.NewAniG(me.ParamData{
+			EntityID: 32769, // same as the first T-CONT
+			Attributes: me.AttributeValueMap{
+				"Arc":                         0,
+				"ArcInterval":                 0,
+				"Deprecated":                  0,
+				"GemBlockLength":              48,
+				"LowerOpticalThreshold":       255,
+				"LowerTransmitPowerThreshold": 129,
+				"OnuResponseTime":             0,
+				"OpticalSignalLevel":          57428,
+				"PiggybackDbaReporting":       0,
+				"SignalDegradeThreshold":      9,
+				"SignalFailThreshold":         5,
+				"SrIndication":                1,
+				"TotalTcontNumber":            8,
+				"TransmitOpticalLevel":        3171,
+				"UpperOpticalThreshold":       255,
+				"UpperTransmitPowerThreshold": 129,
+			},
+		})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewAniG %v", meErr.Error())
 		}
 	case 22, 23, 24, 25:
-		// TODO report different MeID (see omci-sim pcap filter "frame[22:2] == 01:08")
-		reportedMe, meErr = me.NewUniG(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":     me.UniGClassID,
-			"Deprecated":          0,
-			"AdministrativeState": 0,
-		}})
+		// NOTE we're reporting for different UNIs, the IDs are 257, 258, 259, 260
+		meInstance := 235 + msgObj.CommandSequenceNumber
+		reportedMe, meErr = me.NewUniG(me.ParamData{
+			EntityID: meInstance,
+			Attributes: me.AttributeValueMap{
+				"AdministrativeState":         0,
+				"Deprecated":                  0,
+				"ManagementCapability":        0,
+				"NonOmciManagementIdentifier": 0,
+				"RelayAgentOptions":           0,
+			}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewUniG %v", meErr.Error())
 		}
+	// Prior-Q with mask downstream
 	case 26, 30, 34, 38, 42, 46, 50, 54,
 		58, 62, 66, 70, 74, 78, 82, 86,
 		90, 94, 98, 102, 106, 110, 114, 118,
@@ -353,24 +371,27 @@
 		154, 158, 162, 166, 170, 174, 178, 182,
 		186, 190, 194, 198, 202, 206, 210, 214,
 		218, 222, 226, 230, 234, 238, 242, 246,
-		250, 254, 258, 262, 266, 270, 274, 278:
-	case 27, 31, 35, 39, 43, 47, 51, 55,
+		250, 254, 258, 262, 266, 270, 274, 278,
+		// Prior-Q with attribute list downstream
+		27, 31, 35, 39, 43, 47, 51, 55,
 		59, 63, 67, 71, 75, 79, 83, 87,
 		91, 95, 99, 103, 107, 111, 115, 119,
 		123, 127, 131, 135, 139, 143, 147, 151,
 		155, 159, 163, 167, 171, 175, 179, 183,
 		187, 191, 195, 199, 203, 207, 211, 215,
 		219, 223, 227, 231, 235, 239, 243, 247,
-		251, 255, 259, 263, 267, 271, 275, 279:
-	case 28, 32, 36, 40, 44, 48, 52, 56,
+		251, 255, 259, 263, 267, 271, 275, 279,
+		// Prior-Q with mask upstream
+		28, 32, 36, 40, 44, 48, 52, 56,
 		60, 64, 68, 72, 76, 80, 84, 88,
 		92, 96, 100, 104, 108, 112, 116, 120,
 		124, 128, 132, 136, 140, 144, 148, 152,
 		156, 160, 164, 168, 172, 176, 180, 184,
 		188, 192, 196, 200, 204, 208, 212, 216,
 		220, 224, 228, 232, 236, 240, 244, 248,
-		252, 256, 260, 264, 268, 272, 276, 280:
-	case 29, 33, 37, 41, 45, 49, 53, 57,
+		252, 256, 260, 264, 268, 272, 276, 280,
+		// Prior-Q with attribute list upstream
+		29, 33, 37, 41, 45, 49, 53, 57,
 		61, 65, 69, 73, 77, 81, 85, 89,
 		93, 97, 101, 105, 109, 113, 117, 121,
 		125, 129, 133, 137, 141, 145, 149, 153,
@@ -378,28 +399,15 @@
 		189, 193, 197, 201, 205, 209, 213, 217,
 		221, 225, 229, 233, 237, 241, 245, 249,
 		253, 257, 261, 265, 269, 273, 277, 281:
-		reportedMe, meErr = me.NewPriorityQueue(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":                                     me.PriorityQueueClassID,
-			"QueueConfigurationOption":                            0,
-			"MaximumQueueSize":                                    100,
-			"AllocatedQueueSize":                                  100,
-			"DiscardBlockCounterResetInterval":                    0,
-			"ThresholdValueForDiscardedBlocksDueToBufferOverflow": 0,
-			"RelatedPort":                                         80010000, // does this need to change?
-			"TrafficSchedulerPointer":                             8008,     // does this need to change?
-			"Weight":                                              1,
-			"BackPressureOperation":                               1,
-			"BackPressureTime":                                    0,
-			"BackPressureOccurQueueThreshold":                     0,
-			"BackPressureClearQueueThreshold":                     0,
-		}})
+
+		reportedMe, meErr = GeneratePriorityQueueMe(msgObj.CommandSequenceNumber)
+
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewPriorityQueue %v", meErr.Error())
 		}
 	case 282, 283, 284, 285, 286, 287, 288, 289:
 		reportedMe, meErr = me.NewTrafficScheduler(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":         me.TrafficSchedulerClassID,
-			"TContPointer":            8008, // NOTE does this need to change?
+			"TContPointer":            32768, // NOTE does this need to change?
 			"TrafficSchedulerPointer": 0,
 			"Policy":                  02,
 			"PriorityWeight":          0,
@@ -409,12 +417,15 @@
 		}
 	case 290:
 		reportedMe, meErr = me.NewOnu2G(me.ParamData{Attributes: me.AttributeValueMap{
-			"ManagedEntityId":             me.Onu2GClassID,
-			"TotalPriorityQueueNumber":    40,
-			"SecurityMode":                1,
-			"TotalTrafficSchedulerNumber": 8,
-			"TotalGemPortIdNumber":        0,
-			"Sysuptime":                   0,
+			"ConnectivityCapability":                      127,
+			"CurrentConnectivityMode":                     0,
+			"Deprecated":                                  1,
+			"PriorityQueueScaleFactor":                    1,
+			"QualityOfServiceQosConfigurationFlexibility": 63,
+			"Sysuptime":                                   0,
+			"TotalGemPortIdNumber":                        8,
+			"TotalPriorityQueueNumber":                    64,
+			"TotalTrafficSchedulerNumber":                 8,
 		}})
 		if meErr.GetError() != nil {
 			omciLogger.Errorf("NewOnu2G %v", meErr.Error())
@@ -446,3 +457,83 @@
 
 	return pkt, nil
 }
+
+func GeneratePriorityQueueMe(sequence uint16) (*me.ManagedEntity, me.OmciErrors) {
+
+	iteration := sequence - 26
+
+	// we report 256 messages for priority queues,
+	// 128 downstream and 128 upstream
+	// we repeat 64 times the quartet:
+	// - downstream with mask
+	// - downstream with attributes (same MeID as the previous)
+	// - upstream with mask
+	// - upstream with attributes (same MeID as the previous)
+
+	// very ugly way to define whether the priority queue is upstream or downstream
+	// (first 2 blocks are downstream, second two are upstream)
+	// for example sequence 26, 27 are downstream
+	// sequence 28, 29 are upstream
+	isDownstream := ((sequence-26)%4 == 0) || ((sequence-27)%4 == 0)
+	// entityIds are:
+	// - 1 to 64 for downstream (hex 0001 to 0040)
+	// - 32769 to 32832 for upstream (hex 8001 to 8040)
+	var entityId uint16
+	if isDownstream {
+		entityId = (iteration)/4 + 1
+	} else {
+		entityId = (iteration)/4 + 32769
+	}
+
+	var relatedPort uint32
+	if isDownstream {
+		// downstream the related port is:
+		// - Circuit Pack/ UNI port of UNI Port (01 01/04)
+		// - priority 0 to 15 -> iteration%16
+
+		// every 16 iteration (of 4 commands) we move to the next the TCONT MeID
+		uniPort := int(iteration/64) + 1
+		priority := (iteration / 4) % 16
+
+		// concat the uniPort and priority in an hex string
+		// we have a single circuit pack, so we hardcode it
+		v := fmt.Sprintf("010%x000%x", uniPort, priority)
+
+		// convert back to int
+		k, _ := strconv.ParseInt(v, 16, 64)
+		relatedPort = uint32(k)
+	} else {
+		// upstream the related port is:
+		// - Tcont MeID -> reportedTcontsMeId[ceil(iteration/4/8)]
+		// - priority 0 to 7 -> iteration%8
+
+		// every 8 iteration (of 4 commands) we move to the next the TCONT MeID
+		tcontMe := reportedTcontsMeId[int(iteration/32)]
+		priority := (iteration / 4) % 8
+
+		// concat the tcontMe and priority in an hex string
+		v := fmt.Sprintf("%x000%x", tcontMe, priority)
+
+		// convert back to int
+		k, _ := strconv.ParseInt(v, 16, 64)
+		relatedPort = uint32(k)
+	}
+
+	return me.NewPriorityQueue(me.ParamData{
+		EntityID: entityId,
+		Attributes: me.AttributeValueMap{
+			"QueueConfigurationOption":                            0,
+			"MaximumQueueSize":                                    100,
+			"AllocatedQueueSize":                                  100,
+			"DiscardBlockCounterResetInterval":                    0,
+			"ThresholdValueForDiscardedBlocksDueToBufferOverflow": 0,
+			"RelatedPort":                                         relatedPort,
+			"TrafficSchedulerPointer":                             264,
+			"Weight":                                              1,
+			"BackPressureOperation":                               1,
+			"BackPressureTime":                                    0,
+			"BackPressureOccurQueueThreshold":                     0,
+			"BackPressureClearQueueThreshold":                     0,
+		},
+	})
+}