Using the OMCI-Sim library to respond to OMCI messages

Change-Id: I8a15f9dcb95fe8ce7b5f524d673d7c83882b6401
diff --git a/internal/bbsim/bbsim.go b/internal/bbsim/bbsim.go
index 589d557..b353662 100644
--- a/internal/bbsim/bbsim.go
+++ b/internal/bbsim/bbsim.go
@@ -46,7 +46,8 @@
 }
 
 func init() {
-	log.SetLevel(log.DebugLevel)
+	//log.SetLevel(log.DebugLevel)
+	log.SetLevel(log.TraceLevel)
 	//log.SetReportCaller(true)
 }
 
diff --git a/internal/bbsim/devices/olt.go b/internal/bbsim/devices/olt.go
index 1923b14..95cd882 100644
--- a/internal/bbsim/devices/olt.go
+++ b/internal/bbsim/devices/olt.go
@@ -366,12 +366,14 @@
 }
 
 func (o OltDevice) FlowAdd(context.Context, *openolt.Flow) (*openolt.Empty, error)  {
-	oltLogger.Error("FlowAdd not implemented")
+	oltLogger.Info("received FlowAdd")
+	// TODO store flows somewhere
 	return new(openolt.Empty) , nil
 }
 
 func (o OltDevice) FlowRemove(context.Context, *openolt.Flow) (*openolt.Empty, error)  {
-	oltLogger.Error("FlowRemove not implemented")
+	oltLogger.Info("received FlowRemove")
+	// TODO store flows somewhere
 	return new(openolt.Empty) , nil
 }
 
@@ -407,15 +409,14 @@
 }
 
 func (o OltDevice) OmciMsgOut(ctx context.Context, omci_msg *openolt.OmciMsg) (*openolt.Empty, error)  {
-	oltLogger.Debugf("Recevied OmciMsgOut - IntfId: %d OnuId: %d", omci_msg.IntfId, omci_msg.OnuId)
 	pon, _ := o.getPonById(omci_msg.IntfId)
 	onu, _ := pon.getOnuById(omci_msg.OnuId)
 	msg := Message{
 		Type:      OMCI,
 		Data:      OmciMessage{
 			OnuSN:  onu.SerialNumber,
-			OnuId: 	onu.ID,
-			msg: 	omci_msg,
+			OnuID: 	onu.ID,
+			omciMsg: 	omci_msg,
 		},
 	}
 	onu.channel <- msg
@@ -439,7 +440,7 @@
 }
 
 func (o OltDevice) UplinkPacketOut(context context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
-	oltLogger.Error("UplinkPacketOut not implemented")
+	oltLogger.Warn("UplinkPacketOut not implemented")
 	return new(openolt.Empty) , nil
 }
 
@@ -459,21 +460,21 @@
 }
 
 func (s OltDevice) CreateTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
-	oltLogger.Error("CreateTrafficQueues not implemented")
+	oltLogger.Info("received CreateTrafficQueues")
 	return new(openolt.Empty), nil
 }
 
 func (s OltDevice) RemoveTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
-	oltLogger.Error("RemoveTrafficQueues not implemented")
+	oltLogger.Info("received RemoveTrafficQueues")
 	return new(openolt.Empty), nil
 }
 
 func (s OltDevice) CreateTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
-	oltLogger.Error("CreateTrafficSchedulers not implemented")
+	oltLogger.Info("received CreateTrafficSchedulers")
 	return new(openolt.Empty), nil
 }
 
 func (s OltDevice) RemoveTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
-	oltLogger.Error("RemoveTrafficSchedulers not implemented")
+	oltLogger.Info("received RemoveTrafficSchedulers")
 	return new(openolt.Empty), nil
 }
\ No newline at end of file
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index 2ab53fc..8922b66 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -3,6 +3,7 @@
 import (
 	"github.com/opencord/voltha-protos/go/openolt"
 	"github.com/looplab/fsm"
+	omci "github.com/opencord/omci-sim"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -67,8 +68,9 @@
 			msg, _ := message.Data.(OnuIndicationMessage)
 			o.sendOnuIndication(msg, stream)
 		case OMCI:
+			msg, _ := message.Data.(OmciMessage)
 			o.InternalState.Event("start_omci")
-			onuLogger.Warn("Don't know how to handle OMCI Messages yet...")
+			o.handleOmciMessage(msg, stream)
 		default:
 			onuLogger.Warnf("Received unknown message data %v for type %v in OLT channel", message.Data, message.Type)
 		}
@@ -126,4 +128,46 @@
 		"AdminState": msg.OperState.String(),
 		"SerialNumber": o.SerialNumber,
 	}).Debug("Sent Indication_OnuInd")
+}
+
+func (o Onu) handleOmciMessage(msg OmciMessage, stream openolt.Openolt_EnableIndicationServer) {
+
+	onuLogger.WithFields(log.Fields{
+		"IntfId": o.PonPortID,
+		"SerialNumber": o.SerialNumber,
+		"omciPacket": msg.omciMsg.Pkt,
+	}).Tracef("Received OMCI message")
+
+	var omciInd openolt.OmciIndication
+	respPkt, err := omci.OmciSim(o.PonPortID, o.ID, HexDecode(msg.omciMsg.Pkt))
+	if err != nil {
+		onuLogger.Errorf("Error handling OMCI message %v", msg)
+	}
+
+	omciInd.IntfId = o.PonPortID
+	omciInd.OnuId = o.ID
+	omciInd.Pkt = respPkt
+
+	omci := &openolt.Indication_OmciInd{OmciInd: &omciInd}
+	if err := stream.Send(&openolt.Indication{Data: omci}); err != nil {
+		onuLogger.Error("send omci indication failed: %v", err)
+	}
+	onuLogger.WithFields(log.Fields{
+		"IntfId": o.PonPortID,
+		"SerialNumber": o.SerialNumber,
+		"omciPacket": omciInd.Pkt,
+	}).Tracef("Sent OMCI message")
+}
+
+// HexDecode converts the hex encoding to binary
+func HexDecode(pkt []byte) []byte {
+	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
+	}
+	onuLogger.Tracef("Omci decoded: %x.", p)
+	return p
 }
\ No newline at end of file
diff --git a/internal/bbsim/devices/types.go b/internal/bbsim/devices/types.go
index 78666f2..c1ec3b4 100644
--- a/internal/bbsim/devices/types.go
+++ b/internal/bbsim/devices/types.go
@@ -136,8 +136,8 @@
 
 type OmciMessage struct {
 	OnuSN     *openolt.SerialNumber
-	OnuId 	uint32
-	msg 	*openolt.OmciMsg
+	OnuID 	  uint32
+	omciMsg   *openolt.OmciMsg
 }