blob: 075665177e71ea196cb8dcb0e6f7f7c05a3e9e69 [file] [log] [blame]
Keita NISHIMOTO9708e042018-10-27 09:24:44 +09001/*
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
17package core
18
19import (
Matteo Scandolo88e91892018-11-06 16:29:19 -080020 "flag"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090021 "os"
22 "os/signal"
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020023 "reflect"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090024 "strconv"
Matteo Scandolo88e91892018-11-06 16:29:19 -080025 "strings"
26 "sync"
Mahir Gunyel32dfd722019-08-05 16:18:06 +030027 "time"
Matteo Scandolo88e91892018-11-06 16:29:19 -080028
Zack Williams2abf3932019-08-05 14:07:05 -070029 "github.com/opencord/voltha-bbsim/common/logger"
30 "github.com/opencord/voltha-bbsim/device"
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020031 log "github.com/sirupsen/logrus"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090032)
33
Keita NISHIMOTO2807c542019-06-04 22:58:32 +090034const (
35 DEFAULT Mode = iota
36 AAA
37 BOTH
38)
39
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020040// Store emulation mode
Keita NISHIMOTO2807c542019-06-04 22:58:32 +090041type Mode int
42
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020043// AutoONUActivate is flag for Auto ONU Add on/off.
44var AutoONUActivate int
45
Matteo Scandolo88e91892018-11-06 16:29:19 -080046type option struct {
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020047 address string
48 port uint32
49 mgmtGrpcPort uint32
50 mgmtRestPort uint32
51 oltid uint32
52 npon uint32
53 nonus uint32
54 aaawait int
55 dhcpwait int
56 dhcpservip string
Mahir Gunyel32dfd722019-08-05 16:18:06 +030057 intvl time.Duration
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020058 interactiveOnuActivation bool
59 Mode Mode
60 KafkaBroker string
61 Debuglvl string
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090062}
63
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020064// GetOptions receives command line options and stores them in option structure
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090065func GetOptions() *option {
66 o := new(option)
67 addressport := flag.String("H", ":50060", "IP address:port")
Matteo Scandolo88e91892018-11-06 16:29:19 -080068 oltid := flag.Int("id", 0, "OLT-ID")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090069 npon := flag.Int("i", 1, "Number of PON-IF ports")
70 nonus := flag.Int("n", 1, "Number of ONUs per PON-IF port")
71 modeopt := flag.String("m", "default", "Emulation mode (default, aaa, both (aaa & dhcp))")
Keita NISHIMOTO2807c542019-06-04 22:58:32 +090072 aaawait := flag.Int("aw", 2, "Wait time (sec) for activation WPA supplicants after EAPOL flow entry installed")
73 dhcpwait := flag.Int("dw", 2, "Wait time (sec) for activation DHCP clients after DHCP flow entry installed")
Keita NISHIMOTO2f8a6a42019-02-08 09:47:07 +090074 dhcpservip := flag.String("s", "182.21.0.128", "DHCP Server IP Address")
Mahir Gunyel32dfd722019-08-05 16:18:06 +030075 intvl := flag.Duration("v", 0, "Interval each Discovery Indication, in the form of unit+suffix, such as '10ms', '1s' or '1m''. defaults to 0")
Matteo Scandolo88e91892018-11-06 16:29:19 -080076 kafkaBroker := flag.String("k", "", "Kafka broker")
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020077 interactiveOnuActivation := flag.Bool("ia", false, "Enable interactive activation of ONUs")
78 mgmtGrpcPort := flag.Int("grpc", 50061, "BBSim API server gRPC port")
79 mgmtRestPort := flag.Int("rest", 50062, "BBSim API server REST port")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090080 o.Mode = DEFAULT
Mahir Gunyel09183342019-01-29 14:26:50 -080081 debg := flag.String("d", "DEBUG", "Debug Level(TRACE DEBUG INFO WARN ERROR)")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090082 flag.Parse()
83 if *modeopt == "aaa" {
84 o.Mode = AAA
85 } else if *modeopt == "both" {
86 o.Mode = BOTH
87 }
Mahir Gunyel09183342019-01-29 14:26:50 -080088 o.Debuglvl = *debg
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090089 o.oltid = uint32(*oltid)
90 o.npon = uint32(*npon)
91 o.nonus = uint32(*nonus)
92 o.aaawait = *aaawait
93 o.dhcpwait = *dhcpwait
94 o.dhcpservip = *dhcpservip
95 o.intvl = *intvl
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020096 o.interactiveOnuActivation = *interactiveOnuActivation
Matteo Scandolo88e91892018-11-06 16:29:19 -080097 o.KafkaBroker = *kafkaBroker
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020098 o.address = strings.Split(*addressport, ":")[0]
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090099 tmp, _ := strconv.Atoi(strings.Split(*addressport, ":")[1])
100 o.port = uint32(tmp)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200101 o.mgmtGrpcPort = uint32(*mgmtGrpcPort)
102 o.mgmtRestPort = uint32(*mgmtRestPort)
103
104 if o.interactiveOnuActivation == true {
105 log.Info("Automatic ONU activation disabled: use BBSim API to activate ONUs")
106 }
107
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900108 return o
109}
110
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900111type mediator struct {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900112 opt *option
113 server *Server
114 testmanager *TestManager
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900115}
116
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200117// NewMediator returns a new mediator object
Matteo Scandolo88e91892018-11-06 16:29:19 -0800118func NewMediator(o *option) *mediator {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900119 m := new(mediator)
120 m.opt = o
Matteo Scandolo88e91892018-11-06 16:29:19 -0800121 logger.WithFields(log.Fields{
122 "ip": o.address,
123 "baseport": o.port,
124 "pon_ports": o.npon,
125 "onus": o.nonus,
126 "mode": o.Mode,
127 }).Debug("New mediator")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900128 return m
129}
130
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200131// Start mediator
Matteo Scandolo88e91892018-11-06 16:29:19 -0800132func (m *mediator) Start() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900133 var wg sync.WaitGroup
134 opt := m.opt
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900135 server := NewCore(opt)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200136 server.wg = &sync.WaitGroup{}
137 server.wg.Add(1)
138 go server.StartServerActionLoop(&wg)
139 server.serverActionCh <- "start"
140 go server.startMgmtServer(&wg)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900141
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900142 tm := NewTestManager(opt)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900143 m.server = server
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900144 m.testmanager = tm
Matteo Scandolo88e91892018-11-06 16:29:19 -0800145 go func() {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900146 m.Mediate()
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900147 }()
148
149 c := make(chan os.Signal, 1)
150 signal.Notify(c, os.Interrupt)
151 go func() {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800152 defer func() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900153 logger.Debug("SIGINT catcher Done")
154 wg.Done()
155 }()
156 for sig := range c {
157 wg.Add(1)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200158 logger.Debug("SIGINT %v", sig)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900159 close(c)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200160 server.Stop() // Non-blocking
161 tm.Stop() // Non-blocking
162 server.stopMgmtServer()
163 server.wg.Done()
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900164 return
165 }
166 }()
167 wg.Wait()
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200168 server.wg.Wait()
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900169}
170
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200171// Mediate method is invoked on OLT and ONU state change
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900172func (m *mediator) Mediate() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900173 defer logger.Debug("Mediate Done")
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900174 for sr := range m.server.stateRepCh {
175 next := sr.next
176 current := sr.current
177 dev := sr.device
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700178 key := dev.GetDevkey()
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200179 if reflect.TypeOf(dev) == reflect.TypeOf(&device.Olt{}) {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700180 logger.WithFields(log.Fields{
181 "device": dev,
182 }).Debugf("Received OLT Device state change %v Current: %d Next: %d", key, current, next)
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900183 if err := transitOlt(current, next, m.testmanager, m.opt); err != nil {
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900184 logger.Error("%v", err)
185 }
186 } else if reflect.TypeOf(dev) == reflect.TypeOf(&device.Onu{}) {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700187 logger.WithFields(log.Fields{
188 "device": dev,
189 }).Debugf("Received ONU Device state change %v Current: %d Next: %d", key, current, next)
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900190 if err := transitOnu(key, current, next, m.testmanager, m.opt); err != nil {
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900191 logger.Error("%v", err)
192 }
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900193 }
194 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800195}
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900196
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200197func transitOlt(current device.DeviceState, next device.DeviceState, tm *TestManager, o *option) error {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900198 logger.Debug("trnsitOlt called current:%d , next:%d", current, next)
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900199 if current == device.OLT_PREACTIVE && next == device.OLT_ACTIVE {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900200 tm.Start()
Mahir Gunyel639c4f72019-04-26 12:05:32 -0700201 nniup, _ := makeNniName(o.oltid)
202 activateDHCPServer(nniup, o.dhcpservip)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200203 } else if current == device.OLT_ACTIVE && next == device.OLT_PREACTIVE {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900204 tm.Stop()
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200205 } else if current == device.OLT_ACTIVE && next == device.OLT_INACTIVE {
206 // Reboot case
207 // TODO Point of discussion
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900208 }
209 return nil
210}
211
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700212func transitOnu(key device.Devkey, previous device.DeviceState, current device.DeviceState, tm *TestManager, o *option) error {
213 logger.Debug("transitOnu called with key: %v, previous: %s, current: %s", key, device.ONUState[previous], device.ONUState[current])
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900214 if o.Mode == AAA || o.Mode == BOTH {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700215 if previous == device.ONU_ACTIVE && current == device.ONU_OMCIACTIVE {
216 logger.Debug("Starting WPASupplicant for device %v", key)
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900217 t := tm.CreateTester("AAA", o, key, activateWPASupplicant, o.aaawait)
218 if err := tm.StartTester(t); err != nil {
219 logger.Error("Cannot Start AAA Executer error:%v", err)
220 }
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700221 } else if previous == device.ONU_OMCIACTIVE && current == device.ONU_INACTIVE {
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900222 if err := tm.StopTester("AAA", key); err != nil {
223 logger.Error("Cannot Stop AAA Executer error:%v", err)
224 }
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900225 }
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900226 }
227
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200228 if o.Mode == BOTH {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700229 if previous == device.ONU_OMCIACTIVE && current == device.ONU_AUTHENTICATED {
230 logger.Debug("Starting DHCP client for device %v", key)
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900231 t := tm.CreateTester("DHCP", o, key, activateDHCPClient, o.dhcpwait)
232 if err := tm.StartTester(t); err != nil {
233 logger.Error("Cannot Start DHCP Executer error:%v", err)
234 }
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700235 } else if previous == device.ONU_AUTHENTICATED && current == device.ONU_INACTIVE {
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900236 if err := tm.StopTester("DHCP", key); err != nil {
237 logger.Error("Cannot Stop DHCP Executer error:%v", err)
238 }
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900239 }
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900240 }
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900241 return nil
Mahir Gunyel09183342019-01-29 14:26:50 -0800242}