Using the OMCI-Sim library to respond to OMCI messages

Change-Id: I8a15f9dcb95fe8ce7b5f524d673d7c83882b6401
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a725465
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+vendor/
\ No newline at end of file
diff --git a/Makefile b/Makefile
index cfb0fc7..8e34d12 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,7 @@
 protos: api/bbsim/bbsim.pb.go # @HELP Build proto files
 
 build: protos # @HELP Build the binary
-	GO111MODULE=on go build -i -v \
+	GO111MODULE=on go build -i -v -mod vendor \
 	-ldflags "-X main.buildTime=$(shell date +”%Y/%m/%d-%H:%M:%S”) \
 		-X main.commitHash=$(shell git log --pretty=format:%H -n 1) \
 		-X main.gitStatus=${GIT_STATUS} \
diff --git a/build/package/Dockerfile b/build/package/Dockerfile
index 5af257d..c3c0c87 100644
--- a/build/package/Dockerfile
+++ b/build/package/Dockerfile
@@ -37,7 +37,8 @@
 
 # get dependencies
 COPY go.mod go.sum ./
-RUN go mod download
+COPY vendor ./vendor
+RUN go mod vendor
 
 # build the protos
 COPY Makefile ./
@@ -47,7 +48,7 @@
 # copy and build
 COPY . ./
 ARG GIT_STATUS=Clean
-RUN GO111MODULE=on go build \
+RUN GO111MODULE=on go build -mod vendor\
     -ldflags "-X main.buildTime=$(date +”%Y/%m/%d-%H:%M:%S”) \
     		-X main.commitHash=$(git log --pretty=format:%H -n 1) \
     		-X main.gitStatus=${GIT_STATUS}\
diff --git a/examples/sadis-minimal.json b/examples/sadis-minimal.json
new file mode 100644
index 0000000..10adc68
--- /dev/null
+++ b/examples/sadis-minimal.json
@@ -0,0 +1,66 @@
+{
+  "org.opencord.sadis": {
+    "sadis": {
+      "integration": {
+        "cache": {
+          "enabled": true,
+          "maxsize": 50,
+          "ttl": "PT1m"
+        }
+      },
+      "entries": [
+        {
+          "id": "BBSM00000001",
+          "cTag": 83,
+          "sTag": 99,
+          "nasPortId": "BBSM00000001",
+          "technologyProfileId": 64,
+          "upstreamBandwidthProfile": "High-Speed-Internet",
+          "downstreamBandwidthProfile": "User1-Specific"
+        },
+        {
+          "id": "BBSIM_OLT_0",
+          "hardwareIdentifier": "00:1b:22:00:b1:78",
+          "ipAddress": "192.168.1.252",
+          "uplinkPort": 65536,
+          "nasId": "BBSIM_OLT_0"
+        }
+      ]
+    },
+    "bandwidthprofile": {
+      "integration": {
+        "cache": {
+          "enabled": true,
+          "maxsize": 40,
+          "ttl": "PT1m"
+        }
+      },
+      "entries": [
+        {
+          "id": "High-Speed-Internet",
+          "cir": 200000000,
+          "cbs": 348000,
+          "eir": 10000000,
+          "ebs": 348000,
+          "air": 10000000
+        },
+        {
+          "id": "User1-Specific",
+          "cir": 300000000,
+          "cbs": 348000,
+          "eir": 20000000,
+          "ebs": 348000,
+          "air": 30000000
+        },
+        {
+          "id": "Default",
+          "cir": 300000000,
+          "cbs": 348000,
+          "eir": 20000000,
+          "ebs": 348000,
+          "air": 30000000
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 515d233..72fdc6f 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,10 @@
 require (
 	github.com/golang/protobuf v1.3.2
 	github.com/looplab/fsm v0.1.0
+	github.com/opencord/omci-sim v0.0.0-20190717165025-5ff7bb17f1e9
 	github.com/opencord/voltha-protos v0.0.0-20190813191205-792553b747df
 	github.com/sirupsen/logrus v1.4.2
 	google.golang.org/grpc v1.22.1
 )
+
+replace github.com/opencord/omci-sim v0.0.0-20190717165025-5ff7bb17f1e9 => ./vendor/github.com/opencord/omci-sim
\ No newline at end of file
diff --git a/go.sum b/go.sum
index b31d1f6..749af46 100644
--- a/go.sum
+++ b/go.sum
@@ -15,6 +15,8 @@
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20=
 github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI=
+github.com/opencord/omci-sim v0.0.0-20190717165025-5ff7bb17f1e9 h1:qUbCkEFUDEtOBeG6JfI2oMD6dmUa/zJldvBR59RhRdM=
+github.com/opencord/omci-sim v0.0.0-20190717165025-5ff7bb17f1e9/go.mod h1:W10NTwE0xK9Kh++wrflXPfkknMCaNKkb7Io/ihO4y3k=
 github.com/opencord/voltha-protos v0.0.0-20190813191205-792553b747df h1:j/gaZts38ij2uVVikbXGqlm6n3hts1s0zWzUnBI96C4=
 github.com/opencord/voltha-protos v0.0.0-20190813191205-792553b747df/go.mod h1:MDGL9ai3XOPbiZ0tA8U7k4twK/T/P0Hh4gtjNxNk/qY=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
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
 }