blob: 496621ae56f534ca10738c9da7f4bfe283773259 [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 (
20 "sync"
21 "gerrit.opencord.org/voltha-bbsim/common"
22 "os"
23 "os/signal"
24 "fmt"
25 "flag"
26 "strings"
27 "strconv"
28)
29
30type option struct{
31 address string
32 port uint32
33 oltid uint32
34 npon uint32
35 nonus uint32
36 aaawait int
37 dhcpwait int
38 dhcpservip string
39 intvl int
40 intvl_test int
41 Mode Mode
42}
43
44func GetOptions() *option {
45 o := new(option)
46 addressport := flag.String("H", ":50060", "IP address:port")
47 oltid :=flag.Int("id", 0, "OLT-ID")
48 npon := flag.Int("i", 1, "Number of PON-IF ports")
49 nonus := flag.Int("n", 1, "Number of ONUs per PON-IF port")
50 modeopt := flag.String("m", "default", "Emulation mode (default, aaa, both (aaa & dhcp))")
51 aaawait := flag.Int("aw", 30, "Wait time (sec) for activation WPA supplicants")
52 dhcpwait := flag.Int("dw", 50, "Wait time (sec) for activation DHCP clients")
53 dhcpservip := flag.String("s", "182.21.0.1", "DHCP Server IP Address")
54 intvl := flag.Int("v", 1, "Interval each Indication")
55 intvl_test := flag.Int("V", 1, "Interval each Indication")
56 o.Mode = DEFAULT
57 flag.Parse()
58 if *modeopt == "aaa" {
59 o.Mode = AAA
60 } else if *modeopt == "both" {
61 o.Mode = BOTH
62 }
63 o.oltid = uint32(*oltid)
64 o.npon = uint32(*npon)
65 o.nonus = uint32(*nonus)
66 o.aaawait = *aaawait
67 o.dhcpwait = *dhcpwait
68 o.dhcpservip = *dhcpservip
69 o.intvl = *intvl
70 o.intvl_test = *intvl_test
71 o.address = (strings.Split(*addressport, ":")[0])
72 tmp, _ := strconv.Atoi(strings.Split(*addressport, ":")[1])
73 o.port = uint32(tmp)
74 return o
75}
76
77type stateMachine struct{
78 handlers []*handler
79 state coreState
80}
81
82type handler struct{
83 dst coreState
84 src coreState
85 method func(s *Server) error
86}
87
88func (sm *stateMachine) transit(next coreState) func(s *Server) error {
89 for _, handler := range sm.handlers{
90 if handler.src == sm.state && handler.dst == next {
91 logger.Debug("Hit (src:%d, dst:%d)",handler.src, handler.dst)
92 sm.state = next
93 return handler.method
94 }
95 }
96 sm.state = next
97 return nil
98}
99
100type mediator struct {
101 opt *option
102 sm *stateMachine
103 server *Server
104 tester *Tester
105}
106
107func NewMediator(o *option) *mediator{
108 m := new(mediator)
109 m.opt = o
110 logger.Debug("ip:%s, baseport:%d, npon:%d, nonus:%d, mode:%d\n", o.address, o.port, o.npon, o.nonus, o.Mode)
111 return m
112}
113
114func (m *mediator) Start(){
115 var wg sync.WaitGroup
116 opt := m.opt
117 server := NewCore(opt)
118 wg.Add(1)
119 go func(){
120 if err:= server.Start(); err != nil { //Blocking
121 logger.Error("%s", err)
122 }
123 wg.Done()
124 return
125 }()
126
127 tester := NewTester(opt)
128 m.server = server
129 m.tester = tester
130 m.sm = &stateMachine{
131 state: INACTIVE,
132 handlers: []*handler{
133 &handler{src: PRE_ACTIVE,dst: ACTIVE, method: m.tester.Start},
134 &handler{src: ACTIVE,dst: PRE_ACTIVE, method: m.tester.Stop},
135 },
136 }
137 go func(){
138 m.Mediate()
139 }()
140
141 c := make(chan os.Signal, 1)
142 signal.Notify(c, os.Interrupt)
143 go func() {
144 defer func(){
145 logger.Debug("SIGINT catcher Done")
146 wg.Done()
147 }()
148 for sig := range c {
149 wg.Add(1)
150 fmt.Println("SIGINT", sig)
151 close(c)
152 server.Stop() //Non-blocking
153 tester.Stop(server) //Non-blocking
154 return
155 }
156 }()
157 wg.Wait()
158 logger.Debug("Reach to the end line")
159}
160
161func (m *mediator) Mediate(){
162 wg := sync.WaitGroup{}
163 defer logger.Debug("Mediate Done")
164 for corestat := range m.server.stateChan {
165 logger.Debug("Mediator receives state %d of server", corestat)
166 method := m.sm.transit(corestat)
167 if method != nil {
168 wg.Add(1)
169 defer wg.Done()
170 go func() error {
171 if err := method(m.server); err != nil{ //blocking
172 m.server.Stop()
173 return err
174 }
175 return nil
176 }()
177 }
178 }
179 wg.Wait()
180}