blob: ee25264f3dff1bb0bfa43b7230e02588c79ce0ff [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"
21 "fmt"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090022 "os"
23 "os/signal"
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"
29 log "github.com/sirupsen/logrus"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090030)
31
Matteo Scandolo88e91892018-11-06 16:29:19 -080032type option struct {
33 address string
34 port uint32
35 oltid uint32
36 npon uint32
37 nonus uint32
38 aaawait int
39 dhcpwait int
40 dhcpservip string
41 intvl int
42 intvl_test int
43 Mode Mode
44 KafkaBroker string
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090045}
46
47func GetOptions() *option {
48 o := new(option)
49 addressport := flag.String("H", ":50060", "IP address:port")
Matteo Scandolo88e91892018-11-06 16:29:19 -080050 oltid := flag.Int("id", 0, "OLT-ID")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090051 npon := flag.Int("i", 1, "Number of PON-IF ports")
52 nonus := flag.Int("n", 1, "Number of ONUs per PON-IF port")
53 modeopt := flag.String("m", "default", "Emulation mode (default, aaa, both (aaa & dhcp))")
54 aaawait := flag.Int("aw", 30, "Wait time (sec) for activation WPA supplicants")
55 dhcpwait := flag.Int("dw", 50, "Wait time (sec) for activation DHCP clients")
56 dhcpservip := flag.String("s", "182.21.0.1", "DHCP Server IP Address")
57 intvl := flag.Int("v", 1, "Interval each Indication")
58 intvl_test := flag.Int("V", 1, "Interval each Indication")
Matteo Scandolo88e91892018-11-06 16:29:19 -080059 kafkaBroker := flag.String("k", "", "Kafka broker")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090060 o.Mode = DEFAULT
61 flag.Parse()
62 if *modeopt == "aaa" {
63 o.Mode = AAA
64 } else if *modeopt == "both" {
65 o.Mode = BOTH
66 }
67 o.oltid = uint32(*oltid)
68 o.npon = uint32(*npon)
69 o.nonus = uint32(*nonus)
70 o.aaawait = *aaawait
71 o.dhcpwait = *dhcpwait
72 o.dhcpservip = *dhcpservip
73 o.intvl = *intvl
74 o.intvl_test = *intvl_test
Matteo Scandolo88e91892018-11-06 16:29:19 -080075 o.KafkaBroker = *kafkaBroker
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090076 o.address = (strings.Split(*addressport, ":")[0])
77 tmp, _ := strconv.Atoi(strings.Split(*addressport, ":")[1])
78 o.port = uint32(tmp)
79 return o
80}
81
Matteo Scandolo88e91892018-11-06 16:29:19 -080082type stateMachine struct {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090083 handlers []*handler
Matteo Scandolo88e91892018-11-06 16:29:19 -080084 state coreState
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090085}
86
Matteo Scandolo88e91892018-11-06 16:29:19 -080087type handler struct {
88 dst coreState
89 src coreState
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090090 method func(s *Server) error
91}
92
93func (sm *stateMachine) transit(next coreState) func(s *Server) error {
Matteo Scandolo88e91892018-11-06 16:29:19 -080094 for _, handler := range sm.handlers {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090095 if handler.src == sm.state && handler.dst == next {
Matteo Scandolo88e91892018-11-06 16:29:19 -080096 logger.Debug("Hit (src:%d, dst:%d)", handler.src, handler.dst)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090097 sm.state = next
98 return handler.method
99 }
100 }
101 sm.state = next
102 return nil
103}
104
105type mediator struct {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800106 opt *option
107 sm *stateMachine
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900108 server *Server
109 tester *Tester
110}
111
Matteo Scandolo88e91892018-11-06 16:29:19 -0800112func NewMediator(o *option) *mediator {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900113 m := new(mediator)
114 m.opt = o
Matteo Scandolo88e91892018-11-06 16:29:19 -0800115 logger.WithFields(log.Fields{
116 "ip": o.address,
117 "baseport": o.port,
118 "pon_ports": o.npon,
119 "onus": o.nonus,
120 "mode": o.Mode,
121 }).Debug("New mediator")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900122 return m
123}
124
Matteo Scandolo88e91892018-11-06 16:29:19 -0800125func (m *mediator) Start() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900126 var wg sync.WaitGroup
127 opt := m.opt
128 server := NewCore(opt)
129 wg.Add(1)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800130 go func() {
131 if err := server.Start(); err != nil { //Blocking
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800132 logger.Error("Start %s", err)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900133 }
134 wg.Done()
135 return
136 }()
137
138 tester := NewTester(opt)
139 m.server = server
140 m.tester = tester
141 m.sm = &stateMachine{
142 state: INACTIVE,
143 handlers: []*handler{
Matteo Scandolo88e91892018-11-06 16:29:19 -0800144 &handler{src: PRE_ACTIVE, dst: ACTIVE, method: m.tester.Start},
145 &handler{src: ACTIVE, dst: PRE_ACTIVE, method: m.tester.Stop},
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900146 },
147 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800148 go func() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900149 m.Mediate()
150 }()
151
152 c := make(chan os.Signal, 1)
153 signal.Notify(c, os.Interrupt)
154 go func() {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800155 defer func() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900156 logger.Debug("SIGINT catcher Done")
157 wg.Done()
158 }()
159 for sig := range c {
160 wg.Add(1)
161 fmt.Println("SIGINT", sig)
162 close(c)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800163 server.Stop() //Non-blocking
164 tester.Stop(server) //Non-blocking
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900165 return
166 }
167 }()
168 wg.Wait()
169 logger.Debug("Reach to the end line")
170}
171
Matteo Scandolo88e91892018-11-06 16:29:19 -0800172func (m *mediator) Mediate() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900173 wg := sync.WaitGroup{}
174 defer logger.Debug("Mediate Done")
Matteo Scandolo88e91892018-11-06 16:29:19 -0800175 for corestat := range m.server.stateChan {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900176 logger.Debug("Mediator receives state %d of server", corestat)
177 method := m.sm.transit(corestat)
178 if method != nil {
179 wg.Add(1)
180 defer wg.Done()
181 go func() error {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800182 if err := method(m.server); err != nil { //blocking
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900183 m.server.Stop()
184 return err
185 }
186 return nil
187 }()
188 }
189 }
190 wg.Wait()
Matteo Scandolo88e91892018-11-06 16:29:19 -0800191}