blob: fad0972f6d571f81851f12bf0dd9ad73a80a07da [file] [log] [blame]
Stephane Barbarie35595062018-02-08 08:34:39 -05001package main
2
3import (
4 "context"
5 "flag"
6 "fmt"
7 "github.com/opencord/voltha/ponsim/v2/common"
8 "github.com/opencord/voltha/ponsim/v2/core"
9 "github.com/opencord/voltha/ponsim/v2/grpc"
10 "log"
11 "os"
12 "os/signal"
13 "path"
14)
15
16// TODO: Cleanup logs
17
18const (
19 default_name = "PON"
20 default_grpc_port = 50060
21 default_grpc_addr = ""
22 default_device_type = "OLT"
23 default_api_type = "PONSIM"
24 default_internal_if = "eth0"
25 default_external_if = "eth1"
26 default_onus = 1
27 default_alarm_sim = false
28 default_alarm_freq = 60
29 default_quiet = false
30 default_verbose = false
31 default_no_banner = false
32 default_parent_addr = "olt"
33 default_parent_port = 50060
34 default_vcore_endpoint = "vcore"
35 default_fluentd_host = ""
36
37 default_snapshot_len = 65535
38 default_promiscuous = false
39
40 default_voltha_key = "pki/voltha.key"
41 default_voltha_cert = "pki/voltha.crt"
42 default_voltha_ca = "pki/voltha-CA.pem"
43)
44
45var (
46 voltha_base = os.Getenv("VOLTHA_BASE")
47 certs *grpc.GrpcSecurity
48
49 name string = default_name + "_" + device_type
50 grpc_port int = default_grpc_port
51 grpc_addr string = default_grpc_addr
52 device_type string = default_device_type
53 api_type string = default_api_type
54 internal_if string = default_internal_if
55 external_if string = default_external_if
56 onus int = default_onus
57 alarm_sim bool = default_alarm_sim
58 alarm_freq int = default_alarm_freq
59 quiet bool = default_quiet
60 verbose bool = default_verbose
61 no_banner bool = default_no_banner
62 voltha_key string = default_voltha_key
63 voltha_cert string = default_voltha_cert
64 voltha_ca string = default_voltha_ca
65 parent_addr string = default_parent_addr
66 parent_port int = default_parent_port
67 vcore_endpoint string = default_vcore_endpoint
68 fluentd_host string = default_fluentd_host
69
70 snapshot_len int32 = default_snapshot_len
71 promiscuous bool = default_promiscuous
72)
73
74func init() {
75 parseArgs()
76
77 // Enable fluentd support
78 if fluentd_host != "" {
79 common.Logger().SetFluentd(fluentd_host)
80 }
81
82 // Print banner unless no_banner is specified
83 if !no_banner {
84 printBanner()
85 }
86}
87
88func parseArgs() {
89 var help string
90
91 help = fmt.Sprintf("Name of the PON device")
92 flag.StringVar(&grpc_addr, "name", default_name, help)
93
94 help = fmt.Sprintf("Address used to establish GRPC server connection")
95 flag.StringVar(&grpc_addr, "grpc_addr", default_grpc_addr, help)
96
97 help = fmt.Sprintf("Port used to establish GRPC server connection")
98 flag.IntVar(&grpc_port, "grpc_port", default_grpc_port, help)
99
100 help = fmt.Sprintf("Type of device to simulate (OLT or ONU)")
101 flag.StringVar(&device_type, "device_type", default_device_type, help)
102
103 help = fmt.Sprintf("Type of API used to communicate with devices (PONSIM or BAL)")
104 flag.StringVar(&api_type, "api_type", default_api_type, help)
105
106 help = fmt.Sprintf("Internal Communication Interface for read/write network traffic")
107 flag.StringVar(&internal_if, "internal_if", default_internal_if, help)
108
109 help = fmt.Sprintf("External Communication Interface for read/write network traffic")
110 flag.StringVar(&external_if, "external_if", default_external_if, help)
111
112 help = fmt.Sprintf("Enable promiscuous mode on network interfaces")
113 flag.BoolVar(&promiscuous, "promiscuous", default_promiscuous, help)
114
115 help = fmt.Sprintf("Number of ONUs to simulate")
116 flag.IntVar(&onus, "onus", default_onus, help)
117
118 help = fmt.Sprintf("Suppress debug and info logs")
119 flag.BoolVar(&quiet, "quiet", default_quiet, help)
120
121 help = fmt.Sprintf("Enable verbose logging")
122 flag.BoolVar(&verbose, "verbose", default_verbose, help)
123
124 help = fmt.Sprintf("Omit startup banner log lines")
125 flag.BoolVar(&no_banner, "no_banner", default_no_banner, help)
126
127 help = fmt.Sprintf("Enable generation of simulated alarms")
128 flag.BoolVar(&alarm_sim, "alarm_sim", default_alarm_sim, help)
129
130 help = fmt.Sprintf("Frequency of simulated alarms (in seconds)")
131 flag.IntVar(&alarm_freq, "alarm_freq", default_alarm_freq, help)
132
133 help = fmt.Sprintf("Address of OLT to connect to")
134 flag.StringVar(&parent_addr, "parent_addr", default_parent_addr, help)
135
136 help = fmt.Sprintf("Port of OLT to connect to")
137 flag.IntVar(&parent_port, "parent_port", default_parent_port, help)
138
139 help = fmt.Sprintf("Voltha core endpoint address")
140 flag.StringVar(&vcore_endpoint, "vcore_endpoint", default_vcore_endpoint, help)
141
142 help = fmt.Sprintf("Fluentd host address")
143 flag.StringVar(&fluentd_host, "fluentd", default_fluentd_host, help)
144
145 flag.Parse()
146}
147
148func printBanner() {
149 log.Println(" ____ ____ _ _______ ______ ___")
150 log.Println(" / __ \\/ __ \\/ | / / ___// _/ |/ /")
151 log.Println(" / /_/ / / / / |/ /\\__ \\ / // /|_/ / ")
152 log.Println(" / ____/ /_/ / /| /___/ // // / / / ")
153 log.Println("/_/ \\____/_/ |_//____/___/_/ /_/ ")
154
155 switch device_type {
156 case "OLT":
157 printOltBanner()
158 case "ONU":
159 printOnuBanner()
160 }
161
162 log.Println("(to stop: press Ctrl-C)")
163}
164func printOltBanner() {
165 log.Println(" ____ __ ______")
166 log.Println(" / __ \\/ / /_ __/")
167 log.Println(" / / / / / / / ")
168 log.Println("/ /_/ / /___/ / ")
169 log.Println("\\____/_____/_/ ")
170}
171func printOnuBanner() {
172 log.Println(" ____ _ ____ __")
173 log.Println(" / __ \\/ | / / / / /")
174 log.Println(" / / / / |/ / / / / ")
175 log.Println("/ /_/ / /| / /_/ / ")
176 log.Println("\\____/_/ |_/\\____/ ")
177}
178
179/*
180-----------------------------------------------------------------
181*/
182type PonSimService struct {
183 device core.PonSimInterface
184 server *grpc.GrpcServer
185}
186
187func (s *PonSimService) Start(ctx context.Context) {
188 // GRPC server needs to be secure.
189 // Otherwise communication between adapter and simulator does not occur
190 s.server = grpc.NewGrpcServer(s.device.GetAddress(), s.device.GetPort(), certs, true)
191
192 // Add GRPC services
193 s.server.AddCommonService(s.device)
194 s.server.AddPonSimService(s.device)
195
196 // Add OLT specific services
197 if device_type == core.OLT.String() {
198 s.server.AddOltService(s.device)
199 }
200
201 // Add XPON services unless using BAL
202 if api_type == core.PONSIM.String() {
203 s.server.AddXPonService()
204 } else {
205 s.server.AddBalService()
206 }
207
208 // Start the GRPC server
209 go s.server.Start(ctx)
210
211 // Start the PON device
212 go s.device.Start(ctx)
213}
214
215func (s *PonSimService) Stop(ctx context.Context) {
216 // Stop PON device
217 s.device.Stop(ctx)
218
219 // Stop GRPC server
220 s.server.Stop()
221}
222
223func main() {
224 var device core.PonSimInterface
225
226 // Init based on type of device
227 // Construct OLT/ONU object and pass it down
228 certs = &grpc.GrpcSecurity{
229 CertFile: path.Join(voltha_base, voltha_cert),
230 KeyFile: path.Join(voltha_base, voltha_key),
231 CaFile: path.Join(voltha_base, voltha_ca),
232 }
233
234 // Initialize device with common parameters
235 pon := core.PonSimDevice{
236 Name: name,
237 ExternalIf: external_if,
238 InternalIf: internal_if,
239 Promiscuous: promiscuous,
240 SnapshotLen: snapshot_len,
241 Address: grpc_addr,
242 Port: int32(grpc_port),
243 AlarmsOn: alarm_sim,
244 AlarmsFreq: alarm_freq,
245 Counter: core.NewPonSimMetricCounter(name),
246
247 // TODO: pass certificates
248 //GrpcSecurity: certs,
249 }
250
251 switch device_type {
252 case core.OLT.String():
253 device = core.NewPonSimOltDevice(pon)
254 device.(*core.PonSimOltDevice).MaxOnuCount = onus
255 device.(*core.PonSimOltDevice).VCoreEndpoint = vcore_endpoint
256
257 case core.ONU.String():
258 device = core.NewPonSimOnuDevice(pon)
259 device.(*core.PonSimOnuDevice).ParentAddress = parent_addr
260 device.(*core.PonSimOnuDevice).ParentPort = int32(parent_port)
261
262 default:
263 log.Println("Unknown device type")
264 }
265
266 ps := PonSimService{device: device}
267
268 ctx, cancel := context.WithCancel(context.Background())
269 defer cancel()
270
271 ps.Start(ctx)
272
273 signals := make(chan os.Signal, 1)
274 signal.Notify(signals, os.Interrupt)
275
276 doneCh := make(chan struct{})
277
278 go func() {
279 for {
280 select {
281 case <-signals:
282 log.Println("Interrupt was detected")
283 doneCh <- struct{}{}
284 }
285 }
286 }()
287
288 <-doneCh
289}