blob: f243801d90240219b754f437e1a79246a10875fa [file] [log] [blame]
Matteo Scandolo11006992019-08-28 11:29:46 -07001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Matteo Scandolo4747d292019-08-05 11:50:18 -070017package main
18
19import (
20 "flag"
Matteo Scandolo11006992019-08-28 11:29:46 -070021 "github.com/opencord/bbsim/api/bbsim"
Matteo Scandolo82c16d02019-09-24 09:34:32 -070022 "github.com/opencord/bbsim/internal/bbsim/api"
Matteo Scandolo11006992019-08-28 11:29:46 -070023 "github.com/opencord/bbsim/internal/bbsim/devices"
Matteo Scandolo2bf742a2019-10-01 11:33:34 -070024 bbsimLogger "github.com/opencord/bbsim/internal/bbsim/logger"
Matteo Scandolo4747d292019-08-05 11:50:18 -070025 log "github.com/sirupsen/logrus"
Matteo Scandolo84f7d482019-08-08 19:00:47 -070026 "google.golang.org/grpc"
27 "google.golang.org/grpc/reflection"
28 "net"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070029 "os"
30 "runtime/pprof"
Matteo Scandolo4747d292019-08-05 11:50:18 -070031 "sync"
32)
33
Matteo Scandolo82c16d02019-09-24 09:34:32 -070034type CliOptions struct {
35 OltID int
36 NumNniPerOlt int
37 NumPonPerOlt int
38 NumOnuPerPon int
39 STag int
40 CTagInit int
41 profileCpu *string
Matteo Scandolo2bf742a2019-10-01 11:33:34 -070042 logLevel string
43 logCaller bool
Matteo Scandolo82c16d02019-09-24 09:34:32 -070044}
45
Matteo Scandolo4747d292019-08-05 11:50:18 -070046func getOpts() *CliOptions {
47
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070048 olt_id := flag.Int("olt_id", 0, "Number of OLT devices to be emulated (default is 1)")
49 nni := flag.Int("nni", 1, "Number of NNI ports per OLT device to be emulated (default is 1)")
50 pon := flag.Int("pon", 1, "Number of PON ports per OLT device to be emulated (default is 1)")
51 onu := flag.Int("onu", 1, "Number of ONU devices per PON port to be emulated (default is 1)")
Matteo Scandolo2bf742a2019-10-01 11:33:34 -070052
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070053 s_tag := flag.Int("s_tag", 900, "S-Tag value (default is 900)")
54 c_tag_init := flag.Int("c_tag", 900, "C-Tag starting value (default is 900), each ONU will get a sequentail one (targeting 1024 ONUs per BBSim instance the range is bug enough)")
Matteo Scandolo2bf742a2019-10-01 11:33:34 -070055
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070056 profileCpu := flag.String("cpuprofile", "", "write cpu profile to file")
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070057
Matteo Scandolo2bf742a2019-10-01 11:33:34 -070058 logLevel := flag.String("logLevel", "debug", "Set the log level (trace, debug, info, warn, error)")
59 logCaller := flag.Bool("logCaller", false, "Whether to print the caller filename or not")
60
Matteo Scandolo4747d292019-08-05 11:50:18 -070061 flag.Parse()
62
63 o := new(CliOptions)
64
65 o.OltID = int(*olt_id)
66 o.NumNniPerOlt = int(*nni)
67 o.NumPonPerOlt = int(*pon)
68 o.NumOnuPerPon = int(*onu)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070069 o.STag = int(*s_tag)
70 o.CTagInit = int(*c_tag_init)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070071 o.profileCpu = profileCpu
Matteo Scandolo2bf742a2019-10-01 11:33:34 -070072 o.logLevel = *logLevel
73 o.logCaller = *logCaller
Matteo Scandolo4747d292019-08-05 11:50:18 -070074
75 return o
76}
77
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070078func startApiServer(channel chan bool, group *sync.WaitGroup) {
Matteo Scandolo84f7d482019-08-08 19:00:47 -070079 // TODO make configurable
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070080 address := "0.0.0.0:50070"
Matteo Scandolo84f7d482019-08-08 19:00:47 -070081 log.Debugf("APIServer Listening on: %v", address)
82 lis, err := net.Listen("tcp", address)
83 if err != nil {
84 log.Fatalf("APIServer failed to listen: %v", err)
85 }
86 grpcServer := grpc.NewServer()
Matteo Scandolo82c16d02019-09-24 09:34:32 -070087 bbsim.RegisterBBSimServer(grpcServer, api.BBSimServer{})
Matteo Scandolo84f7d482019-08-08 19:00:47 -070088
89 reflection.Register(grpcServer)
90
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070091 wg := sync.WaitGroup{}
92 wg.Add(1)
93
Matteo Scandolo84f7d482019-08-08 19:00:47 -070094 go grpcServer.Serve(lis)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070095
96 for {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070097 _, ok := <-channel
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070098 if !ok {
99 // if the olt channel is closed, stop the gRPC server
100 log.Warnf("Stopping API gRPC server")
101 grpcServer.Stop()
102 wg.Done()
103 break
104 }
105 }
106
107 wg.Wait()
108 group.Done()
109 return
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700110}
111
Matteo Scandolo4747d292019-08-05 11:50:18 -0700112func main() {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700113 options := getOpts()
114
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700115 bbsimLogger.SetLogLevel(log.StandardLogger(), options.logLevel, options.logCaller)
116
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700117 if *options.profileCpu != "" {
118 // start profiling
119 log.Infof("Creating profile file at: %s", *options.profileCpu)
120 f, err := os.Create(*options.profileCpu)
121 if err != nil {
122 log.Fatal(err)
123 }
124 pprof.StartCPUProfile(f)
125 }
126
Matteo Scandolo4747d292019-08-05 11:50:18 -0700127 log.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700128 "OltID": options.OltID,
Matteo Scandolo4747d292019-08-05 11:50:18 -0700129 "NumNniPerOlt": options.NumNniPerOlt,
130 "NumPonPerOlt": options.NumPonPerOlt,
131 "NumOnuPerPon": options.NumOnuPerPon,
132 }).Info("BroadBand Simulator is on")
133
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700134 // control channels, they are only closed when the goroutine needs to be terminated
135 oltDoneChannel := make(chan bool)
136 apiDoneChannel := make(chan bool)
137
Matteo Scandolo4747d292019-08-05 11:50:18 -0700138 wg := sync.WaitGroup{}
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700139 wg.Add(2)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700140
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700141 go devices.CreateOLT(options.OltID, options.NumNniPerOlt, options.NumPonPerOlt, options.NumOnuPerPon, options.STag, options.CTagInit, &oltDoneChannel, &apiDoneChannel, &wg)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700142 log.Debugf("Created OLT with id: %d", options.OltID)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700143 go startApiServer(apiDoneChannel, &wg)
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700144 log.Debugf("Started APIService")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700145
146 wg.Wait()
147
148 defer func() {
149 log.Info("BroadBand Simulator is off")
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700150 if *options.profileCpu != "" {
151 log.Info("Stopping profiler")
152 pprof.StopCPUProfile()
153 }
Matteo Scandolo4747d292019-08-05 11:50:18 -0700154 }()
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700155}