blob: 2bf2c4079ed5a50012877b55278215197439593d [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"
Shad Ansaria5c79892018-11-29 16:32:59 -080029 "gerrit.opencord.org/voltha-bbsim/protos"
Matteo Scandolo88e91892018-11-06 16:29:19 -080030 log "github.com/sirupsen/logrus"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090031)
32
Matteo Scandolo88e91892018-11-06 16:29:19 -080033type option struct {
34 address string
35 port uint32
36 oltid uint32
37 npon uint32
38 nonus uint32
39 aaawait int
40 dhcpwait int
41 dhcpservip string
42 intvl int
43 intvl_test int
44 Mode Mode
45 KafkaBroker string
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090046}
47
48func GetOptions() *option {
49 o := new(option)
50 addressport := flag.String("H", ":50060", "IP address:port")
Matteo Scandolo88e91892018-11-06 16:29:19 -080051 oltid := flag.Int("id", 0, "OLT-ID")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090052 npon := flag.Int("i", 1, "Number of PON-IF ports")
53 nonus := flag.Int("n", 1, "Number of ONUs per PON-IF port")
54 modeopt := flag.String("m", "default", "Emulation mode (default, aaa, both (aaa & dhcp))")
55 aaawait := flag.Int("aw", 30, "Wait time (sec) for activation WPA supplicants")
56 dhcpwait := flag.Int("dw", 50, "Wait time (sec) for activation DHCP clients")
57 dhcpservip := flag.String("s", "182.21.0.1", "DHCP Server IP Address")
58 intvl := flag.Int("v", 1, "Interval each Indication")
59 intvl_test := flag.Int("V", 1, "Interval each Indication")
Matteo Scandolo88e91892018-11-06 16:29:19 -080060 kafkaBroker := flag.String("k", "", "Kafka broker")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090061 o.Mode = DEFAULT
62 flag.Parse()
63 if *modeopt == "aaa" {
64 o.Mode = AAA
65 } else if *modeopt == "both" {
66 o.Mode = BOTH
67 }
68 o.oltid = uint32(*oltid)
69 o.npon = uint32(*npon)
70 o.nonus = uint32(*nonus)
71 o.aaawait = *aaawait
72 o.dhcpwait = *dhcpwait
73 o.dhcpservip = *dhcpservip
74 o.intvl = *intvl
75 o.intvl_test = *intvl_test
Matteo Scandolo88e91892018-11-06 16:29:19 -080076 o.KafkaBroker = *kafkaBroker
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090077 o.address = (strings.Split(*addressport, ":")[0])
78 tmp, _ := strconv.Atoi(strings.Split(*addressport, ":")[1])
79 o.port = uint32(tmp)
80 return o
81}
82
Matteo Scandolo88e91892018-11-06 16:29:19 -080083type stateMachine struct {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090084 handlers []*handler
Matteo Scandolo88e91892018-11-06 16:29:19 -080085 state coreState
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090086}
87
Matteo Scandolo88e91892018-11-06 16:29:19 -080088type handler struct {
89 dst coreState
90 src coreState
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090091 method func(s *Server) error
92}
93
94func (sm *stateMachine) transit(next coreState) func(s *Server) error {
Matteo Scandolo88e91892018-11-06 16:29:19 -080095 for _, handler := range sm.handlers {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090096 if handler.src == sm.state && handler.dst == next {
Matteo Scandolo88e91892018-11-06 16:29:19 -080097 logger.Debug("Hit (src:%d, dst:%d)", handler.src, handler.dst)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090098 sm.state = next
99 return handler.method
100 }
101 }
102 sm.state = next
103 return nil
104}
105
106type mediator struct {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800107 opt *option
108 sm *stateMachine
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900109 server *Server
110 tester *Tester
111}
112
Matteo Scandolo88e91892018-11-06 16:29:19 -0800113func NewMediator(o *option) *mediator {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900114 m := new(mediator)
115 m.opt = o
Matteo Scandolo88e91892018-11-06 16:29:19 -0800116 logger.WithFields(log.Fields{
117 "ip": o.address,
118 "baseport": o.port,
119 "pon_ports": o.npon,
120 "onus": o.nonus,
121 "mode": o.Mode,
122 }).Debug("New mediator")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900123 return m
124}
125
Matteo Scandolo88e91892018-11-06 16:29:19 -0800126func (m *mediator) Start() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900127 var wg sync.WaitGroup
128 opt := m.opt
Shad Ansaria5c79892018-11-29 16:32:59 -0800129 omciOut := make(chan openolt.OmciMsg, 1024)
130 omciIn := make(chan openolt.OmciIndication, 1024)
Shad Ansari70aafb02018-11-14 22:28:17 -0800131 go OmciRun(omciOut, omciIn)
132 server := NewCore(opt, omciOut, omciIn)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900133 wg.Add(1)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800134 go func() {
135 if err := server.Start(); err != nil { //Blocking
Matteo Scandolo2aca22c2018-11-08 14:12:07 -0800136 logger.Error("Start %s", err)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900137 }
138 wg.Done()
139 return
140 }()
141
142 tester := NewTester(opt)
143 m.server = server
144 m.tester = tester
145 m.sm = &stateMachine{
146 state: INACTIVE,
147 handlers: []*handler{
Matteo Scandolo88e91892018-11-06 16:29:19 -0800148 &handler{src: PRE_ACTIVE, dst: ACTIVE, method: m.tester.Start},
149 &handler{src: ACTIVE, dst: PRE_ACTIVE, method: m.tester.Stop},
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900150 },
151 }
Matteo Scandolo88e91892018-11-06 16:29:19 -0800152 go func() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900153 m.Mediate()
154 }()
155
156 c := make(chan os.Signal, 1)
157 signal.Notify(c, os.Interrupt)
158 go func() {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800159 defer func() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900160 logger.Debug("SIGINT catcher Done")
161 wg.Done()
162 }()
163 for sig := range c {
164 wg.Add(1)
165 fmt.Println("SIGINT", sig)
166 close(c)
Matteo Scandolo88e91892018-11-06 16:29:19 -0800167 server.Stop() //Non-blocking
168 tester.Stop(server) //Non-blocking
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900169 return
170 }
171 }()
172 wg.Wait()
173 logger.Debug("Reach to the end line")
174}
175
Matteo Scandolo88e91892018-11-06 16:29:19 -0800176func (m *mediator) Mediate() {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900177 wg := sync.WaitGroup{}
178 defer logger.Debug("Mediate Done")
Matteo Scandolo88e91892018-11-06 16:29:19 -0800179 for corestat := range m.server.stateChan {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900180 logger.Debug("Mediator receives state %d of server", corestat)
181 method := m.sm.transit(corestat)
182 if method != nil {
183 wg.Add(1)
184 defer wg.Done()
185 go func() error {
Matteo Scandolo88e91892018-11-06 16:29:19 -0800186 if err := method(m.server); err != nil { //blocking
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900187 m.server.Stop()
188 return err
189 }
190 return nil
191 }()
192 }
193 }
194 wg.Wait()
Matteo Scandolo88e91892018-11-06 16:29:19 -0800195}