[VOL-4682] BBSIM: OMCI extended message set - support alarm data retrieval

Change-Id: I47e0f3433515d401a80480ef016d98946fe7080a
diff --git a/VERSION b/VERSION
index 393ccdb..feaae22 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.12.10
+1.13.0
diff --git a/go.mod b/go.mod
index 97507f3..9708ccb 100644
--- a/go.mod
+++ b/go.mod
@@ -23,7 +23,7 @@
 	github.com/olekukonko/tablewriter v0.0.4
 	github.com/opencord/cordctl v0.0.0-20190909161711-01e9c1f04bf4
 	github.com/opencord/device-management-interface v1.4.0
-	github.com/opencord/omci-lib-go/v2 v2.2.0
+	github.com/opencord/omci-lib-go/v2 v2.2.1
 	github.com/opencord/voltha-protos/v5 v5.2.3
 	github.com/pkg/errors v0.8.1 // indirect
 	github.com/sirupsen/logrus v1.4.2
diff --git a/go.sum b/go.sum
index 07457c1..b2aa54e 100644
--- a/go.sum
+++ b/go.sum
@@ -87,8 +87,8 @@
 github.com/opencord/cordctl v0.0.0-20190909161711-01e9c1f04bf4/go.mod h1:/+3S0pwQUy7HeKnH0KfKp5W6hmh/LdZzuZTNT/m7vA4=
 github.com/opencord/device-management-interface v1.4.0 h1:hutRUn/rfYHZQr0K2i7HpZTMyMyLcGL1XdmbUrWt2kM=
 github.com/opencord/device-management-interface v1.4.0/go.mod h1:G1owSqGBGaqllrwtjxfLTsy9EDsGhdhmqkJM3XOnPD0=
-github.com/opencord/omci-lib-go/v2 v2.2.0 h1:9eawwD1+oWHTzEv9Q/JeSN12N/3YSGKoj1dr2Pm434g=
-github.com/opencord/omci-lib-go/v2 v2.2.0/go.mod h1:o1S/jhDLHNikFU7uG2TR5UOM5KmKlqwLlVncXi0FBYQ=
+github.com/opencord/omci-lib-go/v2 v2.2.1 h1:Eai3feaixdQ7ZT8zgqIa94QlJ4tfQCgL0sTM8Q6/rkI=
+github.com/opencord/omci-lib-go/v2 v2.2.1/go.mod h1:o1S/jhDLHNikFU7uG2TR5UOM5KmKlqwLlVncXi0FBYQ=
 github.com/opencord/voltha-protos/v5 v5.2.3 h1:G16GLWL3augy9GQUraePumvin4SdTZc0WZAcCuSW/BU=
 github.com/opencord/voltha-protos/v5 v5.2.3/go.mod h1:ZGcyW79kQKIo7AySo1LRu613E6uiozixrCF0yNB/4x8=
 github.com/pierrec/lz4 v2.4.1+incompatible h1:mFe7ttWaflA46Mhqh+jUfjp2qTbPYxLB2/OyBppH9dg=
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index 4d913b6..e06705b 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -1248,7 +1248,7 @@
 			o.onuAlarmsInfo[key] = alarmInfo
 		}
 		o.onuAlarmsInfoLock.Unlock()
-		responsePkt, _ = omcilib.CreateGetAllAlarmsResponse(msg.OmciMsg.TransactionID, o.onuAlarmsInfo)
+		responsePkt, _ = omcilib.CreateGetAllAlarmsResponse(msg.OmciMsg, o.onuAlarmsInfo)
 	case omci.GetAllAlarmsNextRequestType:
 		if responsePkt, errResp = omcilib.CreateGetAllAlarmsNextResponse(msg.OmciPkt, msg.OmciMsg, o.onuAlarmsInfo); errResp != nil {
 			responsePkt = nil //Do not send any response for error case
diff --git a/internal/common/omci/alarms.go b/internal/common/omci/alarms.go
index 7f7c5ab..e18a737 100644
--- a/internal/common/omci/alarms.go
+++ b/internal/common/omci/alarms.go
@@ -17,8 +17,11 @@
 package omci
 
 import (
+	"encoding/hex"
 	"errors"
 	"fmt"
+	"strconv"
+
 	"github.com/google/gopacket"
 	"github.com/opencord/omci-lib-go/v2"
 	me "github.com/opencord/omci-lib-go/v2/generated"
@@ -70,36 +73,59 @@
 	return pkt, notif.AlarmBitmap
 }
 
-func CreateGetAllAlarmsResponse(tid uint16, onuAlarmDetails map[OnuAlarmInfoMapKey]OnuAlarmInfo) ([]byte, error) {
+func CreateGetAllAlarmsResponse(omciMsg *omci.OMCI, onuAlarmDetails map[OnuAlarmInfoMapKey]OnuAlarmInfo) ([]byte, error) {
 	var alarmEntityClass me.ClassID
-	var meInstance uint16
 	var noOfCommands uint16 = 0
-	alarmEntityClass = me.PhysicalPathTerminationPointEthernetUniClassID //Currently doing for PPTP classID
-	meInstance = 257
-	key := OnuAlarmInfoMapKey{
-		MeInstance: meInstance,
-		MeClassID:  alarmEntityClass,
-	}
-	if _, ok := onuAlarmDetails[key]; ok {
-		noOfCommands = 1
-	}
-	numberOfCommands := uint16(noOfCommands)
+	var isExtended bool = false
 
-	request := &omci.GetAllAlarmsResponse{
+	if omciMsg.DeviceIdentifier == omci.ExtendedIdent {
+		isExtended = true
+	}
+	alarmEntityClass = me.PhysicalPathTerminationPointEthernetUniClassID //Currently doing it for PPTP classID only
+
+	key := OnuAlarmInfoMapKey{
+		MeClassID: alarmEntityClass,
+	}
+	for i := 257; i < 261; i++ { //Currently doing it for up to four PPTP instances only
+		key.MeInstance = uint16(i)
+		if _, ok := onuAlarmDetails[key]; ok {
+			noOfCommands++
+		}
+	}
+	response := &omci.GetAllAlarmsResponse{
 		MeBasePacket: omci.MeBasePacket{
 			EntityClass: me.OnuDataClassID,
+			Extended:    isExtended,
 		},
-		NumberOfCommands: numberOfCommands,
+		NumberOfCommands: noOfCommands,
 	}
-	pkt, err := Serialize(omci.GetAllAlarmsResponseType, request, tid)
+	omciLayer := &omci.OMCI{
+		TransactionID:    omciMsg.TransactionID,
+		MessageType:      omci.GetAllAlarmsResponseType,
+		DeviceIdentifier: omciMsg.DeviceIdentifier,
+	}
+	var options gopacket.SerializeOptions
+	options.FixLengths = true
+
+	buffer := gopacket.NewSerializeBuffer()
+	err := gopacket.SerializeLayers(buffer, options, omciLayer, response)
 	if err != nil {
 		omciLogger.WithFields(log.Fields{
-			"Err": err,
-		}).Error("Cannot Serialize GetAllAlarmsResponse")
+			"Err":  err,
+			"TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
+		}).Error("cannot-Serialize-GetAllAlarmsResponse")
 		return nil, err
 	}
+	pkt := buffer.Bytes()
+
+	log.WithFields(log.Fields{
+		"TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
+		"pkt":  hex.EncodeToString(pkt),
+	}).Trace("omci-get-all-alarms-response")
+
 	return pkt, nil
 }
+
 func ParseGetAllAlarmsNextRequest(omciPkt gopacket.Packet) (*omci.GetAllAlarmsNextRequest, error) {
 	msgLayer := omciPkt.Layer(omci.LayerTypeGetAllAlarmsNextRequest)
 	if msgLayer == nil {
@@ -124,60 +150,75 @@
 		omciLogger.Error(err)
 		return nil, errors.New(err)
 	}
-
-	omciLogger.WithFields(log.Fields{
-		"EntityClass":           msgObj.EntityClass,
-		"EntityInstance":        msgObj.EntityInstance,
-		"CommandSequenceNumber": msgObj.CommandSequenceNumber,
-	}).Trace("received-omci-get-all-alarms-next-request")
-
-	var alarmEntityClass me.ClassID
-	var meInstance uint16
-	var alarmBitMap [28]byte
-
-	switch msgObj.CommandSequenceNumber {
-	case 0:
-		alarmEntityClass = me.PhysicalPathTerminationPointEthernetUniClassID
-		meInstance = 257
-		//Checking if the alarm is raised in the bitmap, we will send clear just to generate missed clear alarm and
-		// vice versa.
-		key := OnuAlarmInfoMapKey{
-			MeInstance: meInstance,
-			MeClassID:  alarmEntityClass,
-		}
-		if alarmInfo, ok := onuAlarmDetails[key]; ok {
-			alarmBitMap = alarmInfo.AlarmBitMap
-		} else {
-			return nil, fmt.Errorf("alarm-info-for-me-not-present-in-alarm-info-map")
-		}
-	default:
+	if msgObj.CommandSequenceNumber > 4 { //Currently doing it for up to four PPTP instances only
 		omciLogger.Warn("unsupported-CommandSequenceNumber-in-get-all-alarm-next", msgObj.CommandSequenceNumber)
 		return nil, fmt.Errorf("unspported-command-sequence-number-in-get-all-alarms-next")
 	}
+	var alarmEntityClass me.ClassID
+	var meInstance uint16
+	var alarmBitMap [28]byte
+	var isExtended bool
+	var additionalAlarms omci.AdditionalAlarmsData
 
+	if omciMsg.DeviceIdentifier == omci.ExtendedIdent {
+		isExtended = true
+	} else {
+		isExtended = false
+	}
+	alarmEntityClass = me.PhysicalPathTerminationPointEthernetUniClassID //Currently doing it for PPTP classID only
+
+	key := OnuAlarmInfoMapKey{
+		MeClassID: alarmEntityClass,
+	}
+	meInstance = 257 + msgObj.CommandSequenceNumber
+	key.MeInstance = meInstance
+	if alarmInfo, ok := onuAlarmDetails[key]; ok {
+		alarmBitMap = alarmInfo.AlarmBitMap
+	} else {
+		return nil, fmt.Errorf("alarm-info-for-me-not-present-in-alarm-info-map")
+	}
 	response := &omci.GetAllAlarmsNextResponse{
 		MeBasePacket: omci.MeBasePacket{
 			EntityClass: me.OnuDataClassID,
+			Extended:    isExtended,
 		},
 		AlarmEntityClass:    alarmEntityClass,
 		AlarmEntityInstance: meInstance,
 		AlarmBitMap:         alarmBitMap,
 	}
+	if isExtended && msgObj.CommandSequenceNumber == 0 {
+		for i := 258; i < 261; i++ {
+			key.MeInstance = uint16(i)
+			if addAlarmInfo, ok := onuAlarmDetails[key]; ok {
+				additionalAlarms.AlarmEntityClass = key.MeClassID
+				additionalAlarms.AlarmEntityInstance = uint16(i)
+				additionalAlarms.AlarmBitMap = addAlarmInfo.AlarmBitMap
+				response.AdditionalAlarms = append(response.AdditionalAlarms, additionalAlarms)
+			}
+		}
+	}
+	omciLayer := &omci.OMCI{
+		TransactionID:    omciMsg.TransactionID,
+		MessageType:      omci.GetAllAlarmsNextResponseType,
+		DeviceIdentifier: omciMsg.DeviceIdentifier,
+	}
+	var options gopacket.SerializeOptions
+	options.FixLengths = true
 
-	omciLogger.WithFields(log.Fields{
-		"AlarmEntityClass":    alarmEntityClass,
-		"AlarmEntityInstance": meInstance,
-		"AlarmBitMap":         alarmBitMap,
-	}).Trace("created-omci-getAllAlarmsNext-response")
-
-	pkt, err := Serialize(omci.GetAllAlarmsNextResponseType, response, omciMsg.TransactionID)
-
+	buffer := gopacket.NewSerializeBuffer()
+	err = gopacket.SerializeLayers(buffer, options, omciLayer, response)
 	if err != nil {
 		omciLogger.WithFields(log.Fields{
-			"Err": err,
-		}).Fatalf("Cannot Serialize GetAllAlarmsNextRequest")
+			"Err":  err,
+			"TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
+		}).Error("cannot-Serialize-GetAllAlarmsNextResponse")
 		return nil, err
 	}
+	pkt := buffer.Bytes()
 
+	log.WithFields(log.Fields{
+		"TxID": strconv.FormatInt(int64(omciMsg.TransactionID), 16),
+		"pkt":  hex.EncodeToString(pkt),
+	}).Trace("omci-get-all-alarms-next-response")
 	return pkt, nil
 }
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/VERSION b/vendor/github.com/opencord/omci-lib-go/v2/VERSION
index ccbccc3..c043eea 100644
--- a/vendor/github.com/opencord/omci-lib-go/v2/VERSION
+++ b/vendor/github.com/opencord/omci-lib-go/v2/VERSION
@@ -1 +1 @@
-2.2.0
+2.2.1
diff --git a/vendor/github.com/opencord/omci-lib-go/v2/alarms.go b/vendor/github.com/opencord/omci-lib-go/v2/alarms.go
index 2bf61b5..2bb163c 100644
--- a/vendor/github.com/opencord/omci-lib-go/v2/alarms.go
+++ b/vendor/github.com/opencord/omci-lib-go/v2/alarms.go
@@ -21,6 +21,7 @@
 	"encoding/binary"
 	"errors"
 	"fmt"
+
 	"github.com/google/gopacket"
 	me "github.com/opencord/omci-lib-go/v2/generated"
 )
@@ -513,7 +514,7 @@
 		contentLength += 2 // Length field
 		if omci.AdditionalAlarms != nil {
 			extraMEs = len(omci.AdditionalAlarms)
-			contentLength += extraMEs*4 + 28
+			contentLength += extraMEs * (4 + 28)
 		}
 	}
 	if contentLength > maxLength {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 47c4e40..9b5e3e5 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -76,7 +76,7 @@
 github.com/opencord/cordctl/pkg/format
 # github.com/opencord/device-management-interface v1.4.0
 github.com/opencord/device-management-interface/go/dmi
-# github.com/opencord/omci-lib-go/v2 v2.2.0
+# github.com/opencord/omci-lib-go/v2 v2.2.1
 github.com/opencord/omci-lib-go/v2
 github.com/opencord/omci-lib-go/v2/generated
 # github.com/opencord/voltha-protos/v5 v5.2.3