blob: 44e1d2099e49991af757ebc258b8cc89d0e20e5f [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"
27
28 "gerrit.opencord.org/voltha-bbsim/common/logger"
Keita NISHIMOTO3f080622019-01-16 10:21:22 +090029 "gerrit.opencord.org/voltha-bbsim/device"
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020030 log "github.com/sirupsen/logrus"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090031)
32
Keita NISHIMOTO2807c542019-06-04 22:58:32 +090033const (
34 DEFAULT Mode = iota
35 AAA
36 BOTH
37)
38
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020039// Store emulation mode
Keita NISHIMOTO2807c542019-06-04 22:58:32 +090040type Mode int
41
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020042// AutoONUActivate is flag for Auto ONU Add on/off.
43var AutoONUActivate int
44
Matteo Scandolo88e91892018-11-06 16:29:19 -080045type option struct {
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020046 address string
47 port uint32
48 mgmtGrpcPort uint32
49 mgmtRestPort uint32
50 oltid uint32
51 npon uint32
52 nonus uint32
53 aaawait int
54 dhcpwait int
55 dhcpservip string
56 intvl int
57 interactiveOnuActivation bool
58 Mode Mode
59 KafkaBroker string
60 Debuglvl string
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090061}
62
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +020063// GetOptions receives command line options and stores them in option structure
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090064func GetOptions() *option {
65 o := new(option)
66 addressport := flag.String("H", ":50060", "IP address:port")
Matteo Scandolo88e91892018-11-06 16:29:19 -080067 oltid := flag.Int("id", 0, "OLT-ID")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090068 npon := flag.Int("i", 1, "Number of PON-IF ports")
69 nonus := flag.Int("n", 1, "Number of ONUs per PON-IF port")
70 modeopt := flag.String("m", "default", "Emulation mode (default, aaa, both (aaa & dhcp))")
Keita NISHIMOTO2807c542019-06-04 22:58:32 +090071 aaawait := flag.Int("aw", 2, "Wait time (sec) for activation WPA supplicants after EAPOL flow entry installed")
72 dhcpwait := flag.Int("dw", 2, "Wait time (sec) for activation DHCP clients after DHCP flow entry installed")
Keita NISHIMOTO2f8a6a42019-02-08 09:47:07 +090073 dhcpservip := flag.String("s", "182.21.0.128", "DHCP Server IP Address")
Keita NISHIMOTOd502e662019-03-01 12:02:51 +090074 intvl := flag.Int("v", 1000, "Interval each Indication (ms)")
Matteo Scandolo88e91892018-11-06 16:29:19 -080075 kafkaBroker := flag.String("k", "", "Kafka broker")
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020076 interactiveOnuActivation := flag.Bool("ia", false, "Enable interactive activation of ONUs")
77 mgmtGrpcPort := flag.Int("grpc", 50061, "BBSim API server gRPC port")
78 mgmtRestPort := flag.Int("rest", 50062, "BBSim API server REST port")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090079 o.Mode = DEFAULT
Mahir Gunyel09183342019-01-29 14:26:50 -080080 debg := flag.String("d", "DEBUG", "Debug Level(TRACE DEBUG INFO WARN ERROR)")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090081 flag.Parse()
82 if *modeopt == "aaa" {
83 o.Mode = AAA
84 } else if *modeopt == "both" {
85 o.Mode = BOTH
86 }
Mahir Gunyel09183342019-01-29 14:26:50 -080087 o.Debuglvl = *debg
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090088 o.oltid = uint32(*oltid)
89 o.npon = uint32(*npon)
90 o.nonus = uint32(*nonus)
91 o.aaawait = *aaawait
92 o.dhcpwait = *dhcpwait
93 o.dhcpservip = *dhcpservip
94 o.intvl = *intvl
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020095 o.interactiveOnuActivation = *interactiveOnuActivation
Matteo Scandolo88e91892018-11-06 16:29:19 -080096 o.KafkaBroker = *kafkaBroker
Zdravko Bozakov7401ff22019-05-28 22:45:12 +020097 o.address = strings.Split(*addressport, ":")[0]
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090098 tmp, _ := strconv.Atoi(strings.Split(*addressport, ":")[1])
99 o.port = uint32(tmp)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200100 o.mgmtGrpcPort = uint32(*mgmtGrpcPort)
101 o.mgmtRestPort = uint32(*mgmtRestPort)
102
103 if o.interactiveOnuActivation == true {
104 log.Info("Automatic ONU activation disabled: use BBSim API to activate ONUs")
105 }
106
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900107 return o
108}
109
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900110type mediator struct {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900111 opt *option
112 server *Server
113 testmanager *TestManager
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900114}
115
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200116// NewMediator returns a new mediator object
Matteo Scandolo88e91892018-11-06 16:29:19 -0800117func NewMediator(o *option) *mediator {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900118 m := new(mediator)
119 m.opt = o
Matteo Scandolo88e91892018-11-06 16:29:19 -0800120 logger.WithFields(log.Fields{
121 "ip": o.address,
122 "baseport": o.port,
123 "pon_ports": o.npon,
124 "onus": o.nonus,
125 "mode": o.Mode,
126 }).Debug("New mediator")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900127 return m
128}
129
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200130// Start mediator
Matteo Scandolo88e91892018-11-06 16:29:19 -0800131func (m *mediator) Start() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900132 var wg sync.WaitGroup
133 opt := m.opt
Keita NISHIMOTO3af86da2018-12-12 10:34:43 +0900134 server := NewCore(opt)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200135 server.wg = &sync.WaitGroup{}
136 server.wg.Add(1)
137 go server.StartServerActionLoop(&wg)
138 server.serverActionCh <- "start"
139 go server.startMgmtServer(&wg)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900140
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900141 tm := NewTestManager(opt)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900142 m.server = server
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900143 m.testmanager = tm
Matteo Scandolo88e91892018-11-06 16:29:19 -0800144 go func() {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900145 m.Mediate()
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900146 }()
147
148 c := make(chan os.Signal, 1)
149 signal.Notify(c, os.Interrupt)
150 go func() {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800151 defer func() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900152 logger.Debug("SIGINT catcher Done")
153 wg.Done()
154 }()
155 for sig := range c {
156 wg.Add(1)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200157 logger.Debug("SIGINT %v", sig)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900158 close(c)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200159 server.Stop() // Non-blocking
160 tm.Stop() // Non-blocking
161 server.stopMgmtServer()
162 server.wg.Done()
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900163 return
164 }
165 }()
166 wg.Wait()
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200167 server.wg.Wait()
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900168}
169
Zdravko Bozakov8b9328c2019-05-15 05:13:34 +0200170// Mediate method is invoked on OLT and ONU state change
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900171func (m *mediator) Mediate() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900172 defer logger.Debug("Mediate Done")
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900173 for sr := range m.server.stateRepCh {
174 next := sr.next
175 current := sr.current
176 dev := sr.device
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200177 if reflect.TypeOf(dev) == reflect.TypeOf(&device.Olt{}) {
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900178 logger.Debug("Received OLT Device %v Current: %d Next: %d", dev, current, next)
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900179 if err := transitOlt(current, next, m.testmanager, m.opt); err != nil {
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900180 logger.Error("%v", err)
181 }
182 } else if reflect.TypeOf(dev) == reflect.TypeOf(&device.Onu{}) {
183 logger.Debug("Received ONU Device %v Current: %d Next: %d", dev, current, next)
184 key := dev.GetDevkey()
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900185 if err := transitOnu(key, current, next, m.testmanager, m.opt); err != nil {
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900186 logger.Error("%v", err)
187 }
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900188 }
189 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800190}
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900191
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200192func transitOlt(current device.DeviceState, next device.DeviceState, tm *TestManager, o *option) error {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900193 logger.Debug("trnsitOlt called current:%d , next:%d", current, next)
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900194 if current == device.OLT_PREACTIVE && next == device.OLT_ACTIVE {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900195 tm.Start()
Mahir Gunyel639c4f72019-04-26 12:05:32 -0700196 nniup, _ := makeNniName(o.oltid)
197 activateDHCPServer(nniup, o.dhcpservip)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200198 } else if current == device.OLT_ACTIVE && next == device.OLT_PREACTIVE {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900199 tm.Stop()
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200200 } else if current == device.OLT_ACTIVE && next == device.OLT_INACTIVE {
201 // Reboot case
202 // TODO Point of discussion
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900203 }
204 return nil
205}
206
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200207func transitOnu(key device.Devkey, current device.DeviceState, next device.DeviceState, tm *TestManager, o *option) error {
Zack Williamsb85f5932019-05-10 16:21:35 -0700208 logger.Debug("trnsitOnu called with key: %v, current: %d, next: %d", key, current, next)
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900209 if o.Mode == AAA || o.Mode == BOTH {
210 if current == device.ONU_ACTIVE && next == device.ONU_OMCIACTIVE {
211 t := tm.CreateTester("AAA", o, key, activateWPASupplicant, o.aaawait)
212 if err := tm.StartTester(t); err != nil {
213 logger.Error("Cannot Start AAA Executer error:%v", err)
214 }
215 } else if current == device.ONU_OMCIACTIVE && next == device.ONU_INACTIVE {
216 if err := tm.StopTester("AAA", key); err != nil {
217 logger.Error("Cannot Stop AAA Executer error:%v", err)
218 }
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900219 }
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900220 }
221
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200222 if o.Mode == BOTH {
Kailash95bb5ac2019-07-01 20:56:37 -0700223 if current == device.ONU_OMCIACTIVE {
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900224 t := tm.CreateTester("DHCP", o, key, activateDHCPClient, o.dhcpwait)
225 if err := tm.StartTester(t); err != nil {
226 logger.Error("Cannot Start DHCP Executer error:%v", err)
227 }
228 } else if current == device.ONU_AUTHENTICATED && next == device.ONU_INACTIVE {
229 if err := tm.StopTester("DHCP", key); err != nil {
230 logger.Error("Cannot Stop DHCP Executer error:%v", err)
231 }
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900232 }
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900233 }
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900234 return nil
Mahir Gunyel09183342019-01-29 14:26:50 -0800235}