[VOL-4723] openonuAdapterGo: OMCI extended message set - support alarm data retrieval

Change-Id: I3c5c3a9e8126b4e7b44ffc1a7fd9e10694c6e2d6
diff --git a/internal/pkg/almgr/alarm_manager.go b/internal/pkg/almgr/alarm_manager.go
index 159736b..cfdaa7b 100755
--- a/internal/pkg/almgr/alarm_manager.go
+++ b/internal/pkg/almgr/alarm_manager.go
@@ -111,8 +111,9 @@
 	onuDBCopy                  alarmBitMapDB
 	bufferedNotifications      []*omci.AlarmNotificationMsg
 	alarmUploadSeqNo           uint16
-	alarmUploadNoOfCmds        uint16
+	alarmUploadNoOfCmdsOrMEs   uint16
 	StopAlarmAuditTimer        chan struct{}
+	isExtendedOmci             bool
 }
 
 // NewAlarmManager - TODO: add comment
@@ -231,7 +232,7 @@
 		}
 	}
 	if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarm(log.WithSpanFromContext(context.TODO(), ctx), 0,
-		am.pDeviceHandler.GetOmciTimeout(), true); err != nil {
+		am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
 		// Transition to failure so that alarm sync can be restarted again
 		go failureTransition()
 	}
@@ -366,7 +367,7 @@
 			am.processMessage = false
 			am.activeAlarms = nil
 			am.alarmBitMapDB = nil
-			am.alarmUploadNoOfCmds = 0
+			am.alarmUploadNoOfCmdsOrMEs = 0
 			am.alarmUploadSeqNo = 0
 			am.onuAlarmManagerLock.Unlock()
 			return
@@ -406,7 +407,7 @@
 		return
 	}
 	am.onuAlarmManagerLock.Lock()
-	am.alarmUploadNoOfCmds = msgObj.NumberOfCommands
+	am.alarmUploadNoOfCmdsOrMEs = msgObj.NumberOfCommands
 	am.onuAlarmManagerLock.Unlock()
 	failureTransition := func() {
 		if err := am.AlarmSyncFsm.PFsm.Event(AsEvFailure); err != nil {
@@ -414,7 +415,7 @@
 		}
 	}
 	am.onuAlarmManagerLock.Lock()
-	if am.alarmUploadSeqNo < am.alarmUploadNoOfCmds {
+	if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
 		// Reset Onu Alarm Sequence
 		am.resetAlarmSequence()
 		// Get a copy of the alarm bit map db.
@@ -423,11 +424,11 @@
 		}
 		am.onuAlarmManagerLock.Unlock()
 		if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
-			log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true); err != nil {
+			log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
 			// Transition to failure
 			go failureTransition()
 		}
-	} else if am.alarmUploadNoOfCmds == 0 {
+	} else if am.alarmUploadNoOfCmdsOrMEs == 0 {
 		// Reset Onu Alarm Sequence
 		am.resetAlarmSequence()
 		// Get a copy of the alarm bit map db.
@@ -452,7 +453,7 @@
 		}
 	} else {
 		logger.Errorw(ctx, "invalid-number-of-commands-received", log.Fields{"device-id": am.deviceID,
-			"upload-no-of-cmds": am.alarmUploadNoOfCmds, "upload-seq-no": am.alarmUploadSeqNo})
+			"upload-no-of-cmds": am.alarmUploadNoOfCmdsOrMEs, "upload-seq-no": am.alarmUploadSeqNo})
 		am.onuAlarmManagerLock.Unlock()
 		go failureTransition()
 	}
@@ -487,11 +488,30 @@
 			logger.Debugw(ctx, "alarm-sync-fsm-cannot-go-to-state-failure", log.Fields{"device-id": am.deviceID, "err": err})
 		}
 	}
+	if msg.OmciMsg.DeviceIdentifier == omci.ExtendedIdent {
+		logger.Debugw(ctx, "get-all-alarms-next-response-additional-data",
+			log.Fields{"device-id": am.deviceID, "additional-data": msgObj.AdditionalAlarms})
+
+		for _, additionalAlarmReport := range msgObj.AdditionalAlarms {
+			meClassID := additionalAlarmReport.AlarmEntityClass
+			meEntityID := additionalAlarmReport.AlarmEntityInstance
+			meAlarmBitMap := additionalAlarmReport.AlarmBitMap
+
+			am.onuAlarmManagerLock.Lock()
+			am.onuDBCopy[meAlarmKey{
+				classID:    meClassID,
+				instanceID: meEntityID,
+			}] = meAlarmBitMap
+			am.onuAlarmManagerLock.Unlock()
+
+			am.IncrementAlarmUploadSeqNo()
+		}
+	}
 	am.onuAlarmManagerLock.RLock()
-	if am.alarmUploadSeqNo < am.alarmUploadNoOfCmds {
+	if am.alarmUploadSeqNo < am.alarmUploadNoOfCmdsOrMEs {
 		am.onuAlarmManagerLock.RUnlock()
 		if err := am.pOnuDeviceEntry.GetDevOmciCC().SendGetAllAlarmNext(
-			log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true); err != nil {
+			log.WithSpanFromContext(context.TODO(), ctx), am.pDeviceHandler.GetOmciTimeout(), true, am.isExtendedOmci); err != nil {
 			// Transition to failure
 			go failureTransition()
 		} //TODO: needs to handle timeouts
@@ -524,6 +544,8 @@
 		am.activeAlarms = make(map[alarmInfo]struct{})
 	}
 	am.alarmBitMapDB = make(map[meAlarmKey][alarmBitMapSizeBytes]byte)
+	// when instantiating alarm manager it was too early, but now we can check for ONU's extended OMCI support
+	am.isExtendedOmci = am.pOnuDeviceEntry.GetPersIsExtOmciSupported()
 	am.onuAlarmManagerLock.Unlock()
 	am.flushAlarmSyncChannels(ctx) // Need to do this first as there might be stale data on the channels and the start state waits on same channels
 
@@ -778,7 +800,7 @@
 func (am *OnuAlarmManager) ResetAlarmUploadCounters() {
 	am.onuAlarmManagerLock.Lock()
 	am.alarmUploadSeqNo = 0
-	am.alarmUploadNoOfCmds = 0
+	am.alarmUploadNoOfCmdsOrMEs = 0
 	am.onuAlarmManagerLock.Unlock()
 }
 
diff --git a/internal/pkg/common/omci_cc.go b/internal/pkg/common/omci_cc.go
index ef7711b..a47ca1a 100755
--- a/internal/pkg/common/omci_cc.go
+++ b/internal/pkg/common/omci_cc.go
@@ -959,55 +959,99 @@
 }
 
 // SendGetAllAlarm gets all alarm ME instances
-func (oo *OmciCC) SendGetAllAlarm(ctx context.Context, alarmRetreivalMode uint8, timeout int, highPrio bool) error {
+func (oo *OmciCC) SendGetAllAlarm(ctx context.Context, alarmRetreivalMode uint8, timeout int, highPrio bool, isExtendedOmci bool) error {
 	logger.Debugw(ctx, "send GetAllAlarms-msg to:", log.Fields{"device-id": oo.deviceID})
+
+	tid := oo.GetNextTid(highPrio)
+	omciLayer := &omci.OMCI{
+		TransactionID: tid,
+		MessageType:   omci.GetAllAlarmsRequestType,
+		// DeviceIdentifier: omci.BaselineIdent,		// Optional, defaults to Baseline
+	}
+	if isExtendedOmci {
+		omciLayer.DeviceIdentifier = omci.ExtendedIdent
+	}
 	request := &omci.GetAllAlarmsRequest{
 		MeBasePacket: omci.MeBasePacket{
 			EntityClass: me.OnuDataClassID,
+			Extended:    isExtendedOmci,
 		},
 		AlarmRetrievalMode: byte(alarmRetreivalMode),
 	}
-	tid := oo.GetNextTid(highPrio)
-	pkt, err := Serialize(ctx, omci.GetAllAlarmsRequestType, request, tid)
+	var options gopacket.SerializeOptions
+	options.FixLengths = true
+	buffer := gopacket.NewSerializeBuffer()
+	err := gopacket.SerializeLayers(buffer, options, omciLayer, request)
 	if err != nil {
-		logger.Errorw(ctx, "Cannot serialize GetAllAlarmsRequest", log.Fields{
-			"Err": err, "device-id": oo.deviceID})
+		logger.Errorw(ctx, "Cannot serialize GetAllAlarmsRequest", log.Fields{"Err": err,
+			"device-id": oo.deviceID})
 		return err
 	}
+	outgoingPacket := buffer.Bytes()
+
 	oo.pOnuAlarmManager.ResetAlarmUploadCounters()
 
 	omciRxCallbackPair := CallbackPair{
 		CbKey:   tid,
 		CbEntry: CallbackPairEntry{oo.pOnuAlarmManager.GetAlarmMgrEventChannel(), oo.receiveOmciResponse, true},
 	}
-	return oo.Send(ctx, pkt, timeout, CDefaultRetries, highPrio, omciRxCallbackPair)
+	err = oo.Send(ctx, outgoingPacket, timeout, CDefaultRetries, highPrio, omciRxCallbackPair)
+	if err != nil {
+		logger.Errorw(ctx, "Cannot send GetAllAlarmsRequest", log.Fields{"Err": err,
+			"device-id": oo.deviceID})
+		return err
+	}
+	logger.Debug(ctx, "send GetAllAlarmsRequest done")
+	return nil
 }
 
 // SendGetAllAlarmNext gets next alarm ME instance
-func (oo *OmciCC) SendGetAllAlarmNext(ctx context.Context, timeout int, highPrio bool) error {
+func (oo *OmciCC) SendGetAllAlarmNext(ctx context.Context, timeout int, highPrio bool, isExtendedOmci bool) error {
 	alarmUploadSeqNo := oo.pOnuAlarmManager.GetAlarmUploadSeqNo()
 	logger.Debugw(ctx, "send SendGetAllAlarmNext-msg to:", log.Fields{"device-id": oo.deviceID,
 		"alarmUploadSeqNo": alarmUploadSeqNo})
+
+	tid := oo.GetNextTid(highPrio)
+	omciLayer := &omci.OMCI{
+		TransactionID: tid,
+		MessageType:   omci.GetAllAlarmsNextRequestType,
+		// DeviceIdentifier: omci.BaselineIdent,		// Optional, defaults to Baseline
+	}
+	if isExtendedOmci {
+		omciLayer.DeviceIdentifier = omci.ExtendedIdent
+	}
 	request := &omci.GetAllAlarmsNextRequest{
 		MeBasePacket: omci.MeBasePacket{
 			EntityClass: me.OnuDataClassID,
+			Extended:    isExtendedOmci,
 		},
 		CommandSequenceNumber: alarmUploadSeqNo,
 	}
-	tid := oo.GetNextTid(highPrio)
-	pkt, err := Serialize(ctx, omci.GetAllAlarmsNextRequestType, request, tid)
+	var options gopacket.SerializeOptions
+	options.FixLengths = true
+	buffer := gopacket.NewSerializeBuffer()
+	err := gopacket.SerializeLayers(buffer, options, omciLayer, request)
 	if err != nil {
-		logger.Errorw(ctx, "Cannot serialize GetAllAlarmsNextRequest", log.Fields{
-			"Err": err, "device-id": oo.deviceID})
+		logger.Errorw(ctx, "Cannot serialize GetAllAlarmsNextRequest", log.Fields{"Err": err,
+			"device-id": oo.deviceID})
 		return err
 	}
+	outgoingPacket := buffer.Bytes()
+
 	oo.pOnuAlarmManager.IncrementAlarmUploadSeqNo()
 
 	omciRxCallbackPair := CallbackPair{
 		CbKey:   tid,
 		CbEntry: CallbackPairEntry{oo.pOnuAlarmManager.GetAlarmMgrEventChannel(), oo.receiveOmciResponse, true},
 	}
-	return oo.Send(ctx, pkt, timeout, CDefaultRetries, highPrio, omciRxCallbackPair)
+	err = oo.Send(ctx, outgoingPacket, timeout, CDefaultRetries, highPrio, omciRxCallbackPair)
+	if err != nil {
+		logger.Errorw(ctx, "Cannot send GetAllAlarmsNextRequest", log.Fields{"Err": err,
+			"device-id": oo.deviceID})
+		return err
+	}
+	logger.Debug(ctx, "send GetAllAlarmsNextRequest done")
+	return nil
 }
 
 // SendCreateGalEthernetProfile creates GalEthernetProfile ME instance