Merge "Onu transitions to ACTIVE and uni port is created."
diff --git a/core/omci.go b/core/omci.go
index 6644f08..4b56895 100644
--- a/core/omci.go
+++ b/core/omci.go
@@ -16,28 +16,212 @@
 
 package core
 
+import (
+	"gerrit.opencord.org/voltha-bbsim/common/logger"
+)
+
 type OmciMsg struct {
 	IntfId uint32
 	OnuId  uint32
 	Pkt    []byte
 }
 
+const NumMibUploads byte = 9
+
+type OnuKey struct {
+	IntfId, OnuId uint32
+}
+
+type OnuState struct {
+	mibUploadCtr uint16
+	uniGInstance uint8
+	pptpInstance uint8
+}
+
 func OmciRun(omciOut chan OmciMsg, omciIn chan OmciMsg) {
+
+	onus := make(map[OnuKey]*OnuState)
+
 	for {
 		var resp OmciMsg
 
-		msg := <-omciOut
+		m := <-omciOut
 
-		resp.Pkt = []byte{
-			0x00, 0x01, 0x2f, 0x0a, 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}
+		msgType, transactionId, meClass, meInstance := ParsePkt(m.Pkt)
 
-		resp.IntfId = msg.IntfId
-		resp.OnuId = msg.OnuId
+		logger.Debug("OmciRun - transactionId: %d msgType: %d, ME Class: %d, ME Instance: %d",
+			transactionId, msgType, meClass, meInstance)
+
+		key := OnuKey{m.IntfId, m.OnuId}
+		if _, ok := onus[key]; !ok {
+			onus[key] = NewOnuState()
+		}
+		switch msgType {
+		case 15:
+			resp.Pkt = MibReset()
+		case 13:
+			resp.Pkt = MibUpload()
+		case 14:
+			resp.Pkt = MibUploadNext(onus[key])
+		case 8:
+			resp.Pkt = Set()
+		case 4:
+			resp.Pkt = Create()
+		case 9:
+			resp.Pkt = Get()
+		default:
+			logger.Debug("Omci msg type not handled: %d", msgType)
+		}
+
+		resp.Pkt[0] = byte(transactionId >> 8)
+		resp.Pkt[1] = byte(transactionId & 0xFF)
+		resp.IntfId = m.IntfId
+		resp.OnuId = m.OnuId
 		omciIn <- resp
 	}
 }
+
+func ParsePkt(pkt []byte) (byte, uint16, uint16, uint16) {
+	p := make([]byte, len(pkt)/2)
+	for i, j := 0, 0; i < len(pkt); i, j = i+2, j+1 {
+		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
+}
+
+func NewOnuState() *OnuState {
+	return &OnuState{mibUploadCtr: 0, uniGInstance: 1, pptpInstance: 1}
+}
+
+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, 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}
+	return pkt
+}
+
+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, 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}
+
+	pkt[9] = NumMibUploads // Number of subsequent MibUploadNext cmds
+
+	return pkt
+}
+
+func MibUploadNext(state *OnuState) []byte {
+	var pkt []byte
+
+	logger.Debug("Omci MibUploadNext")
+
+	switch state.mibUploadCtr {
+	case 0:
+		// ANI-G
+		pkt = []byte{
+			0x00, 0x03, 0x2e, 0x0a, 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}
+	case 1, 2, 3, 4:
+		// UNI-G
+		pkt = []byte{
+			0x00, 0x04, 0x2e, 0x0a, 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}
+		pkt[11] = state.uniGInstance // ME Instance
+		state.uniGInstance++
+	case 5, 6, 7, 8:
+		pkt = []byte{
+			0x00, 0x16, 0x2e, 0x0a, 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}
+		pkt[11] = state.pptpInstance // ME Instance
+		state.pptpInstance++
+	default:
+		logger.Error("Invalid MibUpload request %d", state.mibUploadCtr)
+	}
+
+	state.mibUploadCtr++
+
+	return pkt
+}
+
+func Set() []byte {
+	var pkt []byte
+
+	pkt = []byte{
+		0x01, 0x15, 0x28, 0x0a, 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}
+
+	logger.Debug("Omci Set")
+
+	return pkt
+}
+
+func Create() []byte {
+	var pkt []byte
+
+	pkt = []byte{
+		0x01, 0x17, 0x24, 0x0a, 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}
+
+	logger.Debug("Omci Create")
+
+	return pkt
+}
+
+func Get() []byte {
+	var pkt []byte
+
+	pkt = []byte{
+		0x01, 0x26, 0x29, 0x0a, 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}
+
+	logger.Debug("Omci Get")
+
+	return pkt
+}