AAA Emulation & BBSim Containerization
VOL-1154, VOL-1168, VOL-1273
Change-Id: Ib0fbbaec897f633601976e8636c218f42375bedd
diff --git a/bbsim.go b/bbsim.go
index 28ab99f..27373f8 100755
--- a/bbsim.go
+++ b/bbsim.go
@@ -17,266 +17,20 @@
package main
import (
- "log"
- "net"
- "gerrit.opencord.org/voltha-bbsim/openolt"
- "google.golang.org/grpc"
- "fmt"
+ "gerrit.opencord.org/voltha-bbsim/protos"
+ "gerrit.opencord.org/voltha-bbsim/core"
"flag"
- "reflect"
- "strings"
+ "fmt"
+ "log"
+ "os"
+ "os/signal"
"strconv"
+ "strings"
"sync"
+ "time"
)
-type server struct{
- olt olt
- onus map[uint32]map[uint32]*onu
-}
-
-
-type oltState int
-type onuState int
-
-const(
- PRE_ENABLE oltState = iota
- OLT_UP
- PONIF_UP
- ONU_DISCOVERED
-)
-
-const(
- ONU_PRE_ACTIVATED onuState = iota
- ONU_ACTIVATED
-)
-
-type olt struct {
- ID uint32
- NumPonIntf uint32
- NumNniIntf uint32
- Mac string
- SerialNumber string
- Manufacture string
- Name string
- internalState oltState
- OperState string
- Intfs []intf
- HeartbeatSignature uint32
-}
-
-type intf struct{
- Type string
- IntfID uint32
- OperState string
-}
-
-type onu struct{
- internalState onuState
- IntfID uint32
- OperState string
- SerialNumber *openolt.SerialNumber
-}
-
-func createOlt(oltid uint32, npon uint32, nnni uint32) olt{
- olt := olt {}
- olt.ID = oltid
- olt.NumPonIntf = npon
- olt.NumNniIntf = nnni
- olt.Name = "BBSIM OLT"
- olt.internalState = PRE_ENABLE
- olt.OperState = "up"
- olt.Intfs = make([]intf, olt.NumPonIntf + olt.NumNniIntf)
- olt.HeartbeatSignature = oltid
- 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
-}
-
-func createSN(oltid uint32, intfid uint32, onuid uint32) string{
- sn := fmt.Sprintf("%X%X%02X", oltid, intfid, onuid)
- return sn
-}
-
-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]map[uint32] *onu) bool{
- for _, onus := range regonus{
- for _, onu := range onus{
- if validateSN(*targetonu.SerialNumber, *onu.SerialNumber){
- return true
- }
- }
- }
- return false
-}
-
-func validateSN(sn1 openolt.SerialNumber, sn2 openolt.SerialNumber) bool{
- 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 map[uint32] *onu, opstatus string){
- for i, onu := range onus{
- onu.OperState = "up"
- log.Printf("(PONIF:%d) ONU [%d] discovered.\n", ponif, i)
- }
-}
-
-func activateOLT(s *server, stream openolt.Openolt_EnableIndicationServer) error{
- // Activate OLT
- olt := &s.olt
- onus := s.onus
- if err := sendOltInd(stream, olt); err != nil {
- return err
- }
- olt.OperState = "up"
- olt.internalState = OLT_UP
- log.Printf("OLT %s sent OltInd.\n", olt.Name)
-
-
- // OLT sends Interface Indication to Adapter
- if err := sendIntfInd(stream, olt); err != nil {
- return err
- }
- log.Printf("OLT %s sent IntfInd.\n", olt.Name)
-
- // OLT sends Operation Indication to Adapter after activating each interface
- //time.Sleep(IF_UP_TIME * time.Second)
- olt.internalState = PONIF_UP
- if err := sendOperInd(stream, olt); err != nil {
- return err
- }
- log.Printf("OLT %s sent OperInd.\n", olt.Name)
-
- // OLT sends ONU Discover Indication to Adapter after ONU discovery
- for intfid := uint32(olt.NumNniIntf); intfid < olt.NumNniIntf + olt.NumPonIntf; intfid ++ {
- updateOnusOpStatus(intfid, onus[intfid], "up")
- }
-
- 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)
- }
-
- 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
-}
-
-func sendOltInd(stream openolt.Openolt_EnableIndicationServer, olt *olt) error{
- data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: "up"}}
- if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
- log.Printf("Failed to send OLT indication: %v\n", err)
- return err
- }
- return nil
-}
-
-func sendIntfInd(stream openolt.Openolt_EnableIndicationServer, olt *olt) error{
- for i := uint32(0); i < olt.NumPonIntf + olt.NumNniIntf; i ++ {
- intf := olt.Intfs[i]
- data := &openolt.Indication_IntfInd{&openolt.IntfIndication{IntfId: intf.IntfID, OperState: intf.OperState}}
- if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
- 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
-}
-
-func sendOperInd(stream openolt.Openolt_EnableIndicationServer, olt *olt) error{
- for i := uint32(0); i < olt.NumPonIntf + olt.NumNniIntf; i ++ {
- intf := olt.Intfs[i]
- data := &openolt.Indication_IntfOperInd{&openolt.IntfOperIndication{Type: intf.Type, IntfId: intf.IntfID, OperState: intf.OperState}}
- if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
- 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 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)
- if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
- log.Printf("Failed to send ONUDiscInd [id: %d]: %v\n", i, err)
- return err
- }
- }
- 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]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
-}
-
-func printBanner(){
+func printBanner() {
log.Println(" ________ _______ ________ ")
log.Println(" / ____ | / ____ | / ______/ __ ")
log.Println(" / /____/ / / /____/ / / /_____ /_/ ")
@@ -285,38 +39,63 @@
log.Println("/________/ /________/ /________/ /_/ /_/ /_/ /_/ ")
}
-func getOptions()(string, uint32, uint32, uint32, uint32){
- 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")
+func getOptions() (uint32, string, uint32, uint32, uint32, int, int, string, core.Mode) {
+ addressport := flag.String("H", ":50060", "IP address:port")
+ oltid := flag.Int("id", 0, "OLT-ID")
+ nintfs := flag.Int("i", 1, "Number of PON-IF ports")
+ nonus := flag.Int("n", 1, "Number of ONUs per PON-IF port")
+ modeopt := flag.String("m", "default", "Emulation mode (default, aaa, both (aaa & dhcp))")
+ aaawait := flag.Int("a", 30, "Wait time (sec) for activation WPA supplicants")
+ dhcpwait := flag.Int("d", 10, "Wait time (sec) for activation DHCP clients")
+ dhcpservip := flag.String("s", "182.21.0.1", "DHCP Server IP Address")
+ mode := core.DEFAULT
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)
+ if *modeopt == "aaa" {
+ mode = core.AAA
+ } else if *modeopt == "both" {
+ mode = core.BOTH
+ }
+ address := strings.Split(*addressport, ":")[0]
+ tmp, _ := strconv.Atoi(strings.Split(*addressport, ":")[1])
+ port := uint32(tmp)
+ return uint32(*oltid), address, port, uint32(*nintfs), uint32(*nonus), *aaawait, *dhcpwait, *dhcpservip, mode
}
-
func main() {
+ // CLI Shows up
printBanner()
- ipaddress, baseport, nolts, npon, nonus := getOptions()
- log.Printf("ip:%s, baseport:%d, nolts:%d, npon:%d, nonus:%d\n", ipaddress, baseport, nolts, npon, nonus)
- servers := make([] *server, nolts)
- grpcservers := make([] *grpc.Server, nolts)
- lis := make([] net.Listener, nolts)
+ oltid, ip, port, npon, nonus, aaawait, dhcpwait, dhcpservip, mode := getOptions()
+ log.Printf("ip:%s, baseport:%d, npon:%d, nonus:%d, mode:%d\n", ip, port, npon, nonus, mode)
+
+ // Set up gRPC Server
var wg sync.WaitGroup
- wg.Add(int(nolts))
- for oltid := uint32(0); oltid < nolts; oltid ++ {
- portnum := baseport + oltid
- addressport := ipaddress + ":" + strconv.Itoa(int(portnum))
- log.Printf("Listening %s ...", addressport)
- lis[oltid], _ = net.Listen("tcp", addressport)
- servers[oltid] = newServer(oltid, npon, nonus)
- grpcservers[oltid] = grpc.NewServer()
- openolt.RegisterOpenoltServer(grpcservers[oltid], servers[oltid])
- go grpcservers[oltid].Serve(lis[oltid])
+
+ addressport := ip + ":" + strconv.Itoa(int(port))
+ endchan := make(chan int, 1)
+ listener, gserver, err := core.CreateGrpcServer(oltid, npon, nonus, addressport)
+ server := core.CreateServer(oltid, npon, nonus, aaawait, dhcpwait, dhcpservip, gserver, mode, endchan)
+ if err != nil {
+ log.Println(err)
}
+ openolt.RegisterOpenoltServer(gserver, server)
+
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ gserver.Serve(listener)
+ }()
+
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, os.Interrupt)
+ go func() {
+ for sig := range c {
+ fmt.Println("SIGINT", sig)
+ close(c)
+ close(server.Endchan)
+ gserver.Stop()
+ }
+ }()
wg.Wait()
+ time.Sleep(5 * time.Second)
+ log.Println("Reach to the end line")
}