SEBA-336 - Gemport handling for packet-in

Change-Id: Iec3ca370d32d064b186f613480632a824285f9a8
diff --git a/core/omci.go b/core/omci.go
index 8d891dc..f4147dd 100644
--- a/core/omci.go
+++ b/core/omci.go
@@ -17,13 +17,70 @@
 package core
 
 import (
+	"bytes"
+	"encoding/binary"
+
 	"gerrit.opencord.org/voltha-bbsim/common/logger"
+	"gerrit.opencord.org/voltha-bbsim/protos"
 )
 
-type OmciMsg struct {
-	IntfId uint32
-	OnuId  uint32
-	Pkt    []byte
+//
+// OMCI definitions
+//
+
+// OmciMsgType represents a OMCI message-type
+type OmciMsgType byte
+
+const (
+	// Message Types
+	_                                 = iota
+	Create                OmciMsgType = 4
+	Delete                OmciMsgType = 6
+	Set                   OmciMsgType = 8
+	Get                   OmciMsgType = 9
+	GetAllAlarms          OmciMsgType = 11
+	GetAllAlarmsNext      OmciMsgType = 12
+	MibUpload             OmciMsgType = 13
+	MibUploadNext         OmciMsgType = 14
+	MibReset              OmciMsgType = 15
+	AlarmNotification     OmciMsgType = 16
+	AttributeValueChange  OmciMsgType = 17
+	Test                  OmciMsgType = 18
+	StartSoftwareDownload OmciMsgType = 19
+	DownloadSection       OmciMsgType = 20
+	EndSoftwareDownload   OmciMsgType = 21
+	ActivateSoftware      OmciMsgType = 22
+	CommitSoftware        OmciMsgType = 23
+	SynchronizeTime       OmciMsgType = 24
+	Reboot                OmciMsgType = 25
+	GetNext               OmciMsgType = 26
+	TestResult            OmciMsgType = 27
+	GetCurrentData        OmciMsgType = 28
+	SetTable              OmciMsgType = 29 // Defined in Extended Message Set Only
+)
+
+const (
+	// Managed Entity Class values
+	GEMPortNetworkCTP OmciClass = 268
+)
+
+// OMCI Managed Entity Class
+type OmciClass uint16
+
+// OMCI Message Identifier
+type OmciMessageIdentifier struct {
+	Class    OmciClass
+	Instance uint16
+}
+
+type OmciContent [32]byte
+
+type OmciMessage struct {
+	TransactionId uint16
+	MessageType   OmciMsgType
+	DeviceId      uint8
+	MessageId     OmciMessageIdentifier
+	Content       OmciContent
 }
 
 const NumMibUploads byte = 9
@@ -33,42 +90,45 @@
 }
 
 type OnuState struct {
+	gemPortId    uint16
 	mibUploadCtr uint16
 	uniGInstance uint8
 	pptpInstance uint8
 }
 
-func OmciRun(omciOut chan OmciMsg, omciIn chan OmciMsg) {
+var Onus = map[OnuKey]*OnuState{}
 
-	onus := make(map[OnuKey]*OnuState)
+func OmciRun(omciOut chan openolt.OmciMsg, omciIn chan openolt.OmciIndication) {
 
 	for {
-		var resp OmciMsg
+		var resp openolt.OmciIndication
 
 		m := <-omciOut
 
-		msgType, transactionId, meClass, meInstance := ParsePkt(m.Pkt)
+		transactionId, deviceId, msgType, class, instance, content := ParsePkt(m.Pkt)
 
 		logger.Debug("OmciRun - transactionId: %d msgType: %d, ME Class: %d, ME Instance: %d",
-			transactionId, msgType, meClass, meInstance)
+			transactionId, msgType, class, instance)
 
 		key := OnuKey{m.IntfId, m.OnuId}
-		if _, ok := onus[key]; !ok {
-			onus[key] = NewOnuState()
+		if _, ok := Onus[key]; !ok {
+			Onus[key] = NewOnuState()
 		}
 		switch msgType {
-		case 15:
-			resp.Pkt = MibReset()
+		case MibReset:
+			resp.Pkt = mibReset()
 		case 13:
-			resp.Pkt = MibUpload()
+			resp.Pkt = mibUpload()
 		case 14:
-			resp.Pkt = MibUploadNext(onus[key])
+			resp.Pkt = mibUploadNext(Onus[key])
 		case 8:
-			resp.Pkt = Set()
+			resp.Pkt = set()
 		case 4:
-			resp.Pkt = Create()
+			resp.Pkt = create(class, content, key)
 		case 9:
-			resp.Pkt = Get()
+			resp.Pkt = get()
+		case 11:
+			resp.Pkt = getAllAlarms()
 		default:
 			logger.Warn("Omci msg type not handled: %d", msgType)
 			continue
@@ -76,65 +136,81 @@
 
 		resp.Pkt[0] = byte(transactionId >> 8)
 		resp.Pkt[1] = byte(transactionId & 0xFF)
+		resp.Pkt[2] = 0x2<<4 | byte(msgType)
+		resp.Pkt[3] = deviceId
 		resp.IntfId = m.IntfId
 		resp.OnuId = m.OnuId
 		omciIn <- resp
 	}
 }
 
-func ParsePkt(pkt []byte) (byte, uint16, uint16, uint16) {
+func ParsePkt(pkt []byte) (uint16, uint8, OmciMsgType, OmciClass, uint16, OmciContent) {
+	var m OmciMessage
+
+	r := bytes.NewReader(HexDecode(pkt))
+
+	if err := binary.Read(r, binary.BigEndian, &m); err != nil {
+		logger.Error("binary.Read failed: %s", err)
+	}
+	logger.Debug("OmciRun - TransactionId: %d MessageType: %d, ME Class: %d, ME Instance: %d, Content: %x",
+		m.TransactionId, m.MessageType&0x0F, m.MessageId.Class, m.MessageId.Instance, m.Content)
+
+	return m.TransactionId, m.DeviceId, m.MessageType & 0x0F, m.MessageId.Class, m.MessageId.Instance, m.Content
+
+}
+
+func HexDecode(pkt []byte) []byte {
+	// Convert the hex encoding to binary
+	// TODO - Change openolt adapter to send raw binary instead of hex encoded
 	p := make([]byte, len(pkt)/2)
 	for i, j := 0, 0; i < len(pkt); i, j = i+2, j+1 {
+		// Go figure this ;)
 		u := (pkt[i] & 15) + (pkt[i]>>6)*9
 		l := (pkt[i+1] & 15) + (pkt[i+1]>>6)*9
 		p[j] = u<<4 + l
 	}
 	logger.Debug("Omci decoded: %x.", p)
-	msgType := p[2] & 0x0F
-	transactionId := (uint16(p[0]) << 8) | uint16(p[1])
-	meClass := (uint16(p[4]) << 8) | uint16(p[5])
-	meInstance := (uint16(p[6]) << 8) | uint16(p[7])
-	return msgType, transactionId, meClass, meInstance
+	return p
 }
 
 func NewOnuState() *OnuState {
-	return &OnuState{mibUploadCtr: 0, uniGInstance: 1, pptpInstance: 1}
+	return &OnuState{gemPortId: 0, mibUploadCtr: 0, uniGInstance: 1, pptpInstance: 1}
 }
 
-func MibReset() []byte {
+func mibReset() []byte {
 	var pkt []byte
 
 	logger.Debug("Omci MibReset")
 
 	pkt = []byte{
-		0x00, 0x01, 0x2f, 0x0a, 0x00, 0x02, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x28, 0x1f, 0x75, 0x69, 0xaa}
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	return pkt
 }
 
-func MibUpload() []byte {
+func mibUpload() []byte {
 	var pkt []byte
 
 	logger.Debug("Omci MibUpload")
 
 	pkt = []byte{
-		0x00, 0x02, 0x2d, 0x0a, 0x00, 0x02, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x28, 0x0c, 0x63, 0x21, 0x65}
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 
 	pkt[9] = NumMibUploads // Number of subsequent MibUploadNext cmds
 
 	return pkt
 }
 
-func MibUploadNext(state *OnuState) []byte {
+func mibUploadNext(state *OnuState) []byte {
 	var pkt []byte
 
 	logger.Debug("Omci MibUploadNext")
@@ -143,31 +219,31 @@
 	case 0:
 		// ANI-G
 		pkt = []byte{
-			0x00, 0x03, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x01, 0x07, 0x80, 0x01, 0xff, 0xff, 0x01, 0x00,
 			0x08, 0x00, 0x30, 0x00, 0x00, 0x05, 0x09, 0x00,
 			0x00, 0xe0, 0x54, 0xff, 0xff, 0x00, 0x00, 0x0c,
 			0x63, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x28, 0x2c, 0x4d, 0xa9, 0xc8}
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 	case 1, 2, 3, 4:
 		// UNI-G
 		pkt = []byte{
-			0x00, 0x04, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x01, 0x08, 0x01, 0x01, 0xf8, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x28, 0x05, 0x19, 0xae, 0x66}
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 		pkt[11] = state.uniGInstance // ME Instance
 		state.uniGInstance++
 	case 5, 6, 7, 8:
 		pkt = []byte{
-			0x00, 0x16, 0x2e, 0x0a, 0x00, 0x02, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
 			0x00, 0x0b, 0x01, 0x01, 0xff, 0xfe, 0x00, 0x2f,
 			0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0xee, 0x00,
 			0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x28, 0x6f, 0x10, 0x9b, 0x27}
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 		pkt[11] = state.pptpInstance // ME Instance
 		state.pptpInstance++
 	default:
@@ -179,50 +255,75 @@
 	return pkt
 }
 
-func Set() []byte {
+func set() []byte {
 	var pkt []byte
 
 	pkt = []byte{
-		0x01, 0x15, 0x28, 0x0a, 0x01, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x28, 0x41, 0xb3, 0x95, 0x12}
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 
 	logger.Debug("Omci Set")
 
 	return pkt
 }
 
-func Create() []byte {
+func create(class OmciClass, content OmciContent, key OnuKey) []byte {
 	var pkt []byte
 
+	if class == GEMPortNetworkCTP {
+		if onuState, ok := Onus[key]; !ok {
+			logger.Error("ONU Key Error - IntfId: %d, OnuId:", key.IntfId, key.OnuId)
+		} else {
+			onuState.gemPortId = binary.BigEndian.Uint16(content[:2])
+			logger.Debug("Gem Port Id %d", onuState.gemPortId)
+		}
+	}
+
 	pkt = []byte{
-		0x01, 0x17, 0x24, 0x0a, 0x01, 0x10, 0x00, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x01,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x28, 0x85, 0xcb, 0x98, 0x86}
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 
 	logger.Debug("Omci Create")
 
 	return pkt
 }
 
-func Get() []byte {
+func get() []byte {
 	var pkt []byte
 
 	pkt = []byte{
-		0x01, 0x26, 0x29, 0x0a, 0x00, 0x2d, 0x02, 0x01,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x02, 0x01,
 		0x00, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x28, 0xbc, 0x0c, 0xa4, 0x18}
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 
 	logger.Debug("Omci Get")
 
 	return pkt
 }
+
+func getAllAlarms() []byte {
+	var pkt []byte
+
+	pkt = []byte{
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+		0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+	logger.Debug("Omci GetAllAlarms")
+
+	return pkt
+}