VOL-1350 BBSim - AAA/DHCP client activation triggered by OpenOMCI

Change-Id: Ifa08f8817b51a6a9663646205925c542a7097ba0
diff --git a/core/core_server.go b/core/core_server.go
index 8ebdaa0..c38419d 100644
--- a/core/core_server.go
+++ b/core/core_server.go
@@ -80,7 +80,7 @@
        <-              <-
 */
 
-func NewCore(opt *option, omciOut chan openolt.OmciMsg, omciIn chan openolt.OmciIndication) *Server {
+func NewCore(opt *option) *Server {
 	// TODO: make it decent
 	oltid := opt.oltid
 	npon := opt.npon
@@ -97,8 +97,8 @@
 		EnableServer: nil,
 		state:        INACTIVE,
 		stateChan:    make(chan coreState, 8),
-		omciIn:       omciIn,
-		omciOut:      omciOut,
+		omciIn:       make(chan openolt.OmciIndication, 1024),
+		omciOut:      make(chan openolt.OmciMsg, 1024),
 	}
 
 	nnni := s.Olt.NumNniIntf
@@ -330,6 +330,16 @@
 	defer logger.Debug("runPacketInDaemon Done")
 	unichannel := make(chan Packet, 2048)
 
+
+	logger.Debug("runOMCIDaemon Start")
+	defer logger.Debug("runOMCIDaemon Done")
+	errch := make (chan error)
+	OmciRun(s.omciOut, s.omciIn, s.Onumap, errch)
+	go func(){
+		<-errch	// Wait for OmciInitialization
+		s.updateState(ACTIVE)
+	}()
+
 	for intfid, _ := range s.Onumap {
 		for _, onu := range s.Onumap[intfid] {
 			onuid := onu.OnuID
@@ -352,7 +362,6 @@
 	go RecvWorker(ioinfo, nhandler, nnichannel)
 
 	data := &openolt.Indication_PktInd{}
-	s.updateState(ACTIVE)
 	for {
 		select {
 		case msg := <-s.omciIn:
@@ -505,7 +514,7 @@
 
 func getGemPortID(intfid uint32, onuid uint32) (uint32, error) {
 	key := OnuKey{intfid, onuid}
-	if onuState, ok := Onus[key]; !ok {
+	if onuState, ok := OnuOmciStateMap[key]; !ok {
 		idx := uint32(0)
 		// Backwards compatible with bbsim_olt adapter
 		return 1024 + (((MAX_ONUS_PER_PON*intfid + onuid - 1) * 7) + idx), nil
diff --git a/core/mediator.go b/core/mediator.go
index 2bf2c40..ee25264 100644
--- a/core/mediator.go
+++ b/core/mediator.go
@@ -26,7 +26,6 @@
 	"sync"
 
 	"gerrit.opencord.org/voltha-bbsim/common/logger"
-	"gerrit.opencord.org/voltha-bbsim/protos"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -126,10 +125,7 @@
 func (m *mediator) Start() {
 	var wg sync.WaitGroup
 	opt := m.opt
-	omciOut := make(chan openolt.OmciMsg, 1024)
-	omciIn := make(chan openolt.OmciIndication, 1024)
-	go OmciRun(omciOut, omciIn)
-	server := NewCore(opt, omciOut, omciIn)
+	server := NewCore(opt)
 	wg.Add(1)
 	go func() {
 		if err := server.Start(); err != nil { //Blocking
diff --git a/core/omci.go b/core/omci.go
index 25701b0..acf7bbe 100644
--- a/core/omci.go
+++ b/core/omci.go
@@ -22,6 +22,8 @@
 
 	"gerrit.opencord.org/voltha-bbsim/common/logger"
 	"gerrit.opencord.org/voltha-bbsim/protos"
+	"gerrit.opencord.org/voltha-bbsim/device"
+	"time"
 )
 
 //
@@ -89,13 +91,21 @@
 	IntfId, OnuId uint32
 }
 
-type OnuState struct {
+type OnuOmciState struct {
 	gemPortId    uint16
 	mibUploadCtr uint16
 	uniGInstance uint8
 	pptpInstance uint8
+	init  istate
 }
 
+type istate int
+
+const (
+	INCOMPLETE istate = iota
+	DONE
+)
+
 type OmciMsgHandler func(class OmciClass, content OmciContent, key OnuKey) []byte
 
 var Handlers = map[OmciMsgType]OmciMsgHandler{
@@ -108,40 +118,52 @@
 	GetAllAlarms:  getAllAlarms,
 }
 
-var Onus = map[OnuKey]*OnuState{}
+var OnuOmciStateMap = map[OnuKey]*OnuOmciState{}
 
-func OmciRun(omciOut chan openolt.OmciMsg, omciIn chan openolt.OmciIndication) {
-
-	for {
-		var resp openolt.OmciIndication
-
-		m := <-omciOut
-
-		transactionId, deviceId, msgType, class, instance, content := ParsePkt(m.Pkt)
-
-		logger.Debug("OmciRun - transactionId: %d msgType: %d, ME Class: %d, ME Instance: %d",
-			transactionId, msgType, class, instance)
-
-		key := OnuKey{m.IntfId, m.OnuId}
-		if _, ok := Onus[key]; !ok {
-			Onus[key] = NewOnuState()
+func OmciRun(omciOut chan openolt.OmciMsg, omciIn chan openolt.OmciIndication, onumap map[uint32][] *device.Onu, errch chan error) {
+	go func() { //For monitoring the OMCI states
+		for {
+			time.Sleep(1 * time.Second)
+			if isAllOmciInitDone(onumap) {
+				logger.Info("OmciRun - All the omci init process were done")
+				close(errch)
+				break
+			}
 		}
+	}()
 
-		if _, ok := Handlers[msgType]; !ok {
-			logger.Warn("Ignore omci msg (msgType %d not handled)", msgType)
-			continue
+	go func(){
+		for {
+			var resp openolt.OmciIndication
+
+			m := <-omciOut
+
+			transactionId, deviceId, msgType, class, instance, content := ParsePkt(m.Pkt)
+
+			logger.Debug("OmciRun - transactionId: %d msgType: %d, ME Class: %d, ME Instance: %d",
+				transactionId, msgType, class, instance)
+
+			key := OnuKey{m.IntfId, m.OnuId}
+			if _, ok := OnuOmciStateMap[key]; !ok {
+				OnuOmciStateMap[key] = NewOnuOmciState()
+			}
+
+			if _, ok := Handlers[msgType]; !ok {
+				logger.Warn("Ignore omci msg (msgType %d not handled)", msgType)
+				continue
+			}
+
+			resp.Pkt = Handlers[msgType](class, content, key)
+
+			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
 		}
-
-		resp.Pkt = Handlers[msgType](class, content, key)
-
-		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) (uint16, uint8, OmciMsgType, OmciClass, uint16, OmciContent) {
@@ -154,7 +176,6 @@
 	}
 	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
 
 }
@@ -173,8 +194,8 @@
 	return p
 }
 
-func NewOnuState() *OnuState {
-	return &OnuState{gemPortId: 0, mibUploadCtr: 0, uniGInstance: 1, pptpInstance: 1}
+func NewOnuOmciState() *OnuOmciState {
+	return &OnuOmciState{gemPortId: 0, mibUploadCtr: 0, uniGInstance: 1, pptpInstance: 1}
 }
 
 func mibReset(class OmciClass, content OmciContent, key OnuKey) []byte {
@@ -215,7 +236,7 @@
 
 	logger.Debug("Omci MibUploadNext")
 
-	state := Onus[key]
+	state := OnuOmciStateMap[key]
 
 	switch state.mibUploadCtr {
 	case 0:
@@ -277,11 +298,12 @@
 	var pkt []byte
 
 	if class == GEMPortNetworkCTP {
-		if onuState, ok := Onus[key]; !ok {
+		if onuOmciState, ok := OnuOmciStateMap[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)
+			onuOmciState.gemPortId = binary.BigEndian.Uint16(content[:2])
+			logger.Debug("Gem Port Id %d", onuOmciState.gemPortId)
+			OnuOmciStateMap[key].init = DONE
 		}
 	}
 
@@ -329,3 +351,17 @@
 
 	return pkt
 }
+
+func isAllOmciInitDone(onumap map[uint32][] *device.Onu) bool {
+	for _, onus := range onumap {
+		for _, onu := range onus{
+			key := OnuKey{onu.IntfID, onu.OnuID}
+			state := OnuOmciStateMap[key]
+			if state.init == INCOMPLETE{
+				return false
+			}
+		}
+	}
+	return true
+}
+