blob: 66840bb06694b81ade6e6e8e1a2f0306b76c3eb4 [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
Zack Williams2abf3932019-08-05 14:07:05 -070028 "github.com/opencord/voltha-bbsim/common/logger"
29 "github.com/opencord/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
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700177 key := dev.GetDevkey()
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200178 if reflect.TypeOf(dev) == reflect.TypeOf(&device.Olt{}) {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700179 logger.WithFields(log.Fields{
180 "device": dev,
181 }).Debugf("Received OLT Device state change %v Current: %d Next: %d", key, current, next)
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900182 if err := transitOlt(current, next, m.testmanager, m.opt); err != nil {
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900183 logger.Error("%v", err)
184 }
185 } else if reflect.TypeOf(dev) == reflect.TypeOf(&device.Onu{}) {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700186 logger.WithFields(log.Fields{
187 "device": dev,
188 }).Debugf("Received ONU Device state change %v Current: %d Next: %d", key, current, next)
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900189 if err := transitOnu(key, current, next, m.testmanager, m.opt); err != nil {
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900190 logger.Error("%v", err)
191 }
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900192 }
193 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800194}
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900195
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200196func transitOlt(current device.DeviceState, next device.DeviceState, tm *TestManager, o *option) error {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900197 logger.Debug("trnsitOlt called current:%d , next:%d", current, next)
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900198 if current == device.OLT_PREACTIVE && next == device.OLT_ACTIVE {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900199 tm.Start()
Mahir Gunyel639c4f72019-04-26 12:05:32 -0700200 nniup, _ := makeNniName(o.oltid)
201 activateDHCPServer(nniup, o.dhcpservip)
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200202 } else if current == device.OLT_ACTIVE && next == device.OLT_PREACTIVE {
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900203 tm.Stop()
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200204 } else if current == device.OLT_ACTIVE && next == device.OLT_INACTIVE {
205 // Reboot case
206 // TODO Point of discussion
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900207 }
208 return nil
209}
210
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700211func transitOnu(key device.Devkey, previous device.DeviceState, current device.DeviceState, tm *TestManager, o *option) error {
212 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 +0900213 if o.Mode == AAA || o.Mode == BOTH {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700214 if previous == device.ONU_ACTIVE && current == device.ONU_OMCIACTIVE {
215 logger.Debug("Starting WPASupplicant for device %v", key)
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900216 t := tm.CreateTester("AAA", o, key, activateWPASupplicant, o.aaawait)
217 if err := tm.StartTester(t); err != nil {
218 logger.Error("Cannot Start AAA Executer error:%v", err)
219 }
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700220 } else if previous == device.ONU_OMCIACTIVE && current == device.ONU_INACTIVE {
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900221 if err := tm.StopTester("AAA", key); err != nil {
222 logger.Error("Cannot Stop AAA Executer error:%v", err)
223 }
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900224 }
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900225 }
226
Zdravko Bozakov7401ff22019-05-28 22:45:12 +0200227 if o.Mode == BOTH {
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700228 if previous == device.ONU_OMCIACTIVE && current == device.ONU_AUTHENTICATED {
229 logger.Debug("Starting DHCP client for device %v", key)
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900230 t := tm.CreateTester("DHCP", o, key, activateDHCPClient, o.dhcpwait)
231 if err := tm.StartTester(t); err != nil {
232 logger.Error("Cannot Start DHCP Executer error:%v", err)
233 }
Matteo Scandolo67add0c2019-08-01 16:41:14 -0700234 } else if previous == device.ONU_AUTHENTICATED && current == device.ONU_INACTIVE {
Keita NISHIMOTO2807c542019-06-04 22:58:32 +0900235 if err := tm.StopTester("DHCP", key); err != nil {
236 logger.Error("Cannot Stop DHCP Executer error:%v", err)
237 }
Keita NISHIMOTOdd9f6732019-02-09 09:41:31 +0900238 }
Keita NISHIMOTO7bce7692019-01-19 09:31:09 +0900239 }
Keita NISHIMOTO3f080622019-01-16 10:21:22 +0900240 return nil
Mahir Gunyel09183342019-01-29 14:26:50 -0800241}