Add ONU Ind-related features
Change-Id: Ib6dd74efc0893b2d56275ecf5a1c56c5958fddbd
VOL-1118
diff --git a/bbsim.go b/bbsim.go
index 2466dbb..2c3a15d 100755
--- a/bbsim.go
+++ b/bbsim.go
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package main
import (
@@ -5,11 +21,9 @@
"log"
"net"
"google.golang.org/grpc"
- "golang.org/x/net/context"
"fmt"
"flag"
"reflect"
- "time"
"strings"
"strconv"
"sync"
@@ -17,11 +31,12 @@
type server struct{
olt olt
- onus map[uint32][]onu
+ onus map[uint32]map[uint32]*onu
}
type oltState int
+type onuState int
const(
PRE_ENABLE oltState = iota
@@ -30,8 +45,11 @@
ONU_DISCOVERED
)
+const(
+ ONU_PRE_ACTIVATED onuState = iota
+ ONU_ACTIVATED
+)
-//a
type olt struct {
ID uint32
NumPonIntf uint32
@@ -53,6 +71,7 @@
}
type onu struct{
+ internalState onuState
IntfID uint32
OperState string
SerialNumber *openolt.SerialNumber
@@ -68,16 +87,16 @@
olt.OperState = "up"
olt.Intfs = make([]intf, olt.NumPonIntf + olt.NumNniIntf)
olt.HeartbeatSignature = oltid
- for i := uint32(0); i < olt.NumPonIntf; i ++ {
- olt.Intfs[i].IntfID = i
- olt.Intfs[i].OperState = "up"
- olt.Intfs[i].Type = "pon"
- }
- for i := uint32(olt.NumPonIntf); i < olt.NumPonIntf + olt.NumNniIntf; i ++ {
+ for i := uint32(0); i < olt.NumNniIntf; i ++ {
olt.Intfs[i].IntfID = i
olt.Intfs[i].OperState = "up"
olt.Intfs[i].Type = "nni"
}
+ for i := uint32(olt.NumNniIntf); i < olt.NumPonIntf + olt.NumNniIntf; i ++ {
+ olt.Intfs[i].IntfID = i
+ olt.Intfs[i].OperState = "up"
+ olt.Intfs[i].Type = "pon"
+ }
return olt
}
@@ -86,19 +105,22 @@
return sn
}
-func createOnus(oltid uint32, intfid uint32, nonus uint32) [] onu {
- onus := make([]onu ,nonus)
- for onuid := uint32(0); onuid < nonus; onuid ++ {
- onus[onuid].IntfID = intfid
- onus[onuid].OperState = "down"
- onus[onuid].SerialNumber = new(openolt.SerialNumber)
- onus[onuid].SerialNumber.VendorId = []byte("BRCM")
- onus[onuid].SerialNumber.VendorSpecific = []byte(createSN(oltid, intfid, uint32(onuid))) //FIX
+func createOnus(oltid uint32, intfid uint32, nonus uint32, nnni uint32) map[uint32] *onu {
+ onus := make(map[uint32] *onu ,nonus)
+ for onuid := uint32(1 + (intfid - nnni) * nonus); onuid <= (intfid - nnni + 1) * nonus; onuid ++ {
+ onu := onu{}
+ onu.internalState = ONU_PRE_ACTIVATED
+ onu.IntfID = intfid
+ onu.OperState = "up"
+ onu.SerialNumber = new(openolt.SerialNumber)
+ onu.SerialNumber.VendorId = []byte("BRCM")
+ onu.SerialNumber.VendorSpecific = []byte(createSN(oltid, intfid, uint32(onuid))) //FIX
+ onus[onuid] = &onu
}
return onus
}
-func validateONU(targetonu openolt.Onu, regonus map[uint32][]onu) bool{
+func validateONU(targetonu openolt.Onu, regonus map[uint32]map[uint32] *onu) bool{
for _, onus := range regonus{
for _, onu := range onus{
if validateSN(*targetonu.SerialNumber, *onu.SerialNumber){
@@ -113,11 +135,21 @@
return reflect.DeepEqual(sn1.VendorId, sn2.VendorId) && reflect.DeepEqual(sn1.VendorSpecific, sn2.VendorSpecific)
}
+func isAllONUActive(regonus map[uint32]map[uint32] *onu ) bool{
+ for _, onus := range regonus{
+ for _, onu := range onus{
+ if onu.internalState != ONU_ACTIVATED{
+ return false
+ }
+ }
+ }
+ return true
+}
-func updateOnusOpStatus(ponif uint32, onus [] onu, opstatus string){
+func updateOnusOpStatus(ponif uint32, onus map[uint32] *onu, opstatus string){
for i, onu := range onus{
onu.OperState = "up"
- log.Printf("(PONIF:%d) ONU [%d] %v discovered.\n", ponif, i, onu.SerialNumber)
+ log.Printf("(PONIF:%d) ONU [%d] discovered.\n", ponif, i)
}
}
@@ -148,15 +180,26 @@
log.Printf("OLT %s sent OperInd.\n", olt.Name)
// OLT sends ONU Discover Indication to Adapter after ONU discovery
- for intfid := uint32(0); intfid < olt.NumPonIntf; intfid ++ {
+ for intfid := uint32(olt.NumNniIntf); intfid < olt.NumNniIntf + olt.NumPonIntf; intfid ++ {
updateOnusOpStatus(intfid, onus[intfid], "up")
}
- for intfid := uint32(0); intfid < olt.NumPonIntf; intfid ++ {
+ for intfid := uint32(olt.NumNniIntf); intfid < olt.NumNniIntf + olt.NumPonIntf; intfid ++ {
sendOnuDiscInd(stream, onus[intfid])
log.Printf("OLT id:%d sent ONUDiscInd.\n", olt.ID)
}
- olt.internalState = ONU_DISCOVERED
+
+ for{
+ //log.Printf("stop %v\n", s.onus)
+ if isAllONUActive(s.onus){
+ //log.Printf("break! %v\n", s.onus)
+ break
+ }
+ }
+ for intfid := uint32(olt.NumNniIntf); intfid < olt.NumNniIntf + olt.NumPonIntf; intfid ++ {
+ sendOnuInd(stream, onus[intfid])
+ log.Printf("OLT id:%d sent ONUInd.\n", olt.ID)
+ }
return nil
}
@@ -177,6 +220,7 @@
log.Printf("Failed to send Intf [id: %d] indication : %v\n", i, err)
return err
}
+ log.Printf("SendIntfInd olt:%d intf:%d (%s)\n", olt.ID, intf.IntfID, intf.Type)
}
return nil
}
@@ -189,11 +233,12 @@
log.Printf("Failed to send IntfOper [id: %d] indication : %v\n", i, err)
return err
}
+ log.Printf("SendOperInd olt:%d intf:%d (%s)\n", olt.ID, intf.IntfID, intf.Type)
}
return nil
}
-func sendOnuDiscInd(stream openolt.Openolt_EnableIndicationServer, onus [] onu) error{
+func sendOnuDiscInd(stream openolt.Openolt_EnableIndicationServer, onus map[uint32] *onu) error{
for i, onu := range onus {
data := &openolt.Indication_OnuDiscInd{&openolt.OnuDiscIndication{IntfId: onu.IntfID, SerialNumber:onu.SerialNumber}}
log.Printf("sendONUDiscInd Onuid: %d\n", i)
@@ -205,15 +250,29 @@
return nil
}
+func sendOnuInd(stream openolt.Openolt_EnableIndicationServer, onus map[uint32] *onu) error{
+ for i, onu := range onus {
+ data := &openolt.Indication_OnuInd{&openolt.OnuIndication{IntfId: onu.IntfID, OnuId: uint32(i), OperState: "up", AdminState: "up", SerialNumber:onu.SerialNumber}}
+ log.Printf("sendONUInd Onuid: %d\n", i)
+ if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+ log.Printf("Failed to send ONUInd [id: %d]: %v\n", i, err)
+ return err
+ }
+ }
+ return nil
+}
+
func newServer(oltid uint32, npon uint32, nonus uint32) *server{
s := new(server)
s.olt = createOlt(oltid, npon, 1)
+ nnni := s.olt.NumNniIntf
log.Printf("OLT ID: %d was retrieved.\n", s.olt.ID)
- s.onus = make(map[uint32][]onu)
- for intfid := uint32(0); intfid < npon; intfid ++ {
- s.onus[intfid] = createOnus(oltid, intfid, nonus)
+ s.onus = make(map[uint32]map[uint32] *onu)
+ for intfid := nnni; intfid < npon + nnni; intfid ++ {
+ s.onus[intfid] = createOnus(oltid, intfid, nonus, nnni)
}
+ //log.Printf("s.onus: %v\n", s.onus)
return s
}
@@ -227,66 +286,19 @@
}
func getOptions()(string, uint32, uint32, uint32, uint32){
- var(
- addressport = flag.String("H","172.17.0.1:50060","IP address:port")
- address = strings.Split(*addressport, ":")[0]
- port,_ = strconv.Atoi(strings.Split(*addressport, ":")[1])
- nolts = flag.Int("N", 1, "Number of OLTs")
- nports = flag.Int("i", 1, "Number of PON-IF ports")
- nonus = flag.Int("n", 1, "Number of ONUs per PON-IF port")
- )
-
-
+ addressport := flag.String("H","127.0.0.1:50060","IP address:port")
+ nolts := flag.Int("N", 1, "Number of OLTs")
+ nports := flag.Int("i", 1, "Number of PON-IF ports")
+ nonus := flag.Int("n", 1, "Number of ONUs per PON-IF port")
flag.Parse()
+ fmt.Printf("%v\n", *addressport)
//fmt.Println("nports:", *nports, "nonus:", *nonus)
+ address := strings.Split(*addressport, ":")[0]
+ port,_ := strconv.Atoi(strings.Split(*addressport, ":")[1])
return address, uint32(port), uint32(*nolts), uint32(*nports), uint32(*nonus)
}
-// gRPC Service
-func (s *server) ActivateOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error){
- log.Printf("OLT receives ActivateONU()")
- result := validateONU(*onu, s.onus)
- if result == true {
- log.Printf("ONU %d activated succesufully.\n", onu.OnuId)
- }
- return new(openolt.Empty), nil
-}
-
-func (s *server)OmciMsgOut(c context.Context, msg *openolt.OmciMsg)(*openolt.Empty, error){
- return new(openolt.Empty), nil
-}
-
-func (s *server) OnuPacketOut(c context.Context, packet *openolt.OnuPacket)(*openolt.Empty, error){
- return new(openolt.Empty), nil
-}
-
-func (s *server) FlowAdd(c context.Context, flow *openolt.Flow)(*openolt.Empty, error){
- return new(openolt.Empty), nil
-}
-
-func (s *server) EnableIndication(empty *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
- log.Printf("OLT receives EnableInd.\n")
- if err := activateOLT(s, stream); err != nil {
- log.Printf("Failed to activate OLT: %v\n", err)
- return err
- }
- for ;;{
- //if err := sendIntfInd(stream, &s.olt); err != nil{
- // return err
- //}
- time.Sleep(1 * time.Second)
- }
- return nil
-}
-
-func (s *server) HeartbeatCheck(c context.Context, empty *openolt.Empty) (*openolt.Heartbeat, error){
- log.Printf("OLT receives HeartbeatCheck.\n")
- signature := new(openolt.Heartbeat)
- signature.HeartbeatSignature = s.olt.HeartbeatSignature
- return signature, nil
-}
-
func main() {
printBanner()
ipaddress, baseport, nolts, npon, nonus := getOptions()