blob: 0f898e86d258bd210f0f8bd2f267a9f46dea901c [file] [log] [blame]
Matteo Scandolo10f965c2019-09-24 10:40:46 -07001/*
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 api
18
19import (
20 "context"
21 "fmt"
22 "github.com/opencord/bbsim/api/bbsim"
Matteo Scandolod7cc6d32020-02-26 16:51:12 -080023 "github.com/opencord/bbsim/internal/bbsim/alarmsim"
Matteo Scandolo10f965c2019-09-24 10:40:46 -070024 "github.com/opencord/bbsim/internal/bbsim/devices"
25 log "github.com/sirupsen/logrus"
26 "google.golang.org/grpc/codes"
27)
28
29func (s BBSimServer) GetONUs(ctx context.Context, req *bbsim.Empty) (*bbsim.ONUs, error) {
30 olt := devices.GetOLT()
31 onus := bbsim.ONUs{
32 Items: []*bbsim.ONU{},
33 }
34
35 for _, pon := range olt.Pons {
36 for _, o := range pon.Onus {
37 onu := bbsim.ONU{
38 ID: int32(o.ID),
39 SerialNumber: o.Sn(),
40 OperState: o.OperState.Current(),
41 InternalState: o.InternalState.Current(),
42 PonPortID: int32(o.PonPortID),
43 STag: int32(o.STag),
44 CTag: int32(o.CTag),
45 HwAddress: o.HwAddress.String(),
Matteo Scandolo27428702019-10-11 16:21:16 -070046 PortNo: int32(o.PortNo),
Matteo Scandolo10f965c2019-09-24 10:40:46 -070047 }
48 onus.Items = append(onus.Items, &onu)
49 }
50 }
51 return &onus, nil
52}
53
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070054func (s BBSimServer) GetONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONU, error) {
55 olt := devices.GetOLT()
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070056 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070057
58 if err != nil {
59 res := bbsim.ONU{}
60 return &res, err
61 }
62
63 res := bbsim.ONU{
64 ID: int32(onu.ID),
65 SerialNumber: onu.Sn(),
66 OperState: onu.OperState.Current(),
67 InternalState: onu.InternalState.Current(),
68 PonPortID: int32(onu.PonPortID),
69 STag: int32(onu.STag),
70 CTag: int32(onu.CTag),
71 HwAddress: onu.HwAddress.String(),
Matteo Scandolo27428702019-10-11 16:21:16 -070072 PortNo: int32(onu.PortNo),
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070073 }
74 return &res, nil
75}
76
Matteo Scandolo10f965c2019-09-24 10:40:46 -070077func (s BBSimServer) ShutdownONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
Anand S Katti09541352020-01-29 15:54:01 +053078 // NOTE this method is now sending a Dying Gasp and then disabling the device (operState: down, adminState: up),
Matteo Scandolo10f965c2019-09-24 10:40:46 -070079 // is this the only way to do? Should we address other cases?
80 // Investigate what happens when:
81 // - a fiber is pulled
82 // - ONU malfunction
83 // - ONU shutdown
84 res := &bbsim.Response{}
85
86 logger.WithFields(log.Fields{
87 "OnuSn": req.SerialNumber,
88 }).Infof("Received request to shutdown ONU")
89
90 olt := devices.GetOLT()
91
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070092 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -070093
94 if err != nil {
95 res.StatusCode = int32(codes.NotFound)
96 res.Message = err.Error()
97 return res, err
98 }
99
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800100 dyingGasp := bbsim.ONUAlarmRequest{
101 AlarmType: "DyingGasp",
102 SerialNumber: onu.Sn(),
103 Status: "on",
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700104 }
105
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800106 if err := alarmsim.SimulateOnuAlarm(context.TODO(), &dyingGasp, olt); err != nil {
107 logger.WithFields(log.Fields{
108 "OnuId": onu.ID,
109 "IntfId": onu.PonPortID,
110 "OnuSn": onu.Sn(),
111 }).Errorf("Cannot send Dying Gasp: %s", err.Error())
112 res.StatusCode = int32(codes.FailedPrecondition)
113 res.Message = err.Error()
114 return res, err
115 }
116
117 losReq := bbsim.ONUAlarmRequest{
118 AlarmType: "LossOfSignal",
119 SerialNumber: onu.Sn(),
120 Status: "on",
121 }
122
123 if err := alarmsim.SimulateOnuAlarm(context.TODO(), &losReq, olt); err != nil {
124 logger.WithFields(log.Fields{
125 "OnuId": onu.ID,
126 "IntfId": onu.PonPortID,
127 "OnuSn": onu.Sn(),
128 }).Errorf("Cannot send LOS: %s", err.Error())
129 res.StatusCode = int32(codes.FailedPrecondition)
130 res.Message = err.Error()
131 return res, err
132 }
133
134 // TODO if it's the last ONU on the PON, then send a PON LOS
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700135
136 if err := onu.InternalState.Event("disable"); err != nil {
137 logger.WithFields(log.Fields{
138 "OnuId": onu.ID,
139 "IntfId": onu.PonPortID,
140 "OnuSn": onu.Sn(),
141 }).Errorf("Cannot shutdown ONU: %s", err.Error())
142 res.StatusCode = int32(codes.FailedPrecondition)
143 res.Message = err.Error()
144 return res, err
145 }
146
147 res.StatusCode = int32(codes.OK)
148 res.Message = fmt.Sprintf("ONU %s successfully shut down.", onu.Sn())
149
150 return res, nil
151}
152
153func (s BBSimServer) PoweronONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
154 res := &bbsim.Response{}
155
156 logger.WithFields(log.Fields{
157 "OnuSn": req.SerialNumber,
158 }).Infof("Received request to poweron ONU")
159
160 olt := devices.GetOLT()
161
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700162 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700163 if err != nil {
164 res.StatusCode = int32(codes.NotFound)
165 res.Message = err.Error()
166 return res, err
167 }
168
Pragya Arya2225f202020-01-29 18:05:01 +0530169 pon, _ := olt.GetPonById(onu.PonPortID)
170 if pon.InternalState.Current() != "enabled" {
171 err := fmt.Errorf("PON port %d not enabled", onu.PonPortID)
172 logger.WithFields(log.Fields{
173 "OnuId": onu.ID,
174 "IntfId": onu.PonPortID,
175 "OnuSn": onu.Sn(),
176 }).Errorf("Cannot poweron ONU: %s", err.Error())
177
178 res.StatusCode = int32(codes.FailedPrecondition)
179 res.Message = err.Error()
180 return res, err
181 }
182
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800183 if onu.InternalState.Current() == "created" || onu.InternalState.Current() == "disabled" {
Pragya Arya2225f202020-01-29 18:05:01 +0530184 if err := onu.InternalState.Event("initialize"); err != nil {
185 logger.WithFields(log.Fields{
186 "OnuId": onu.ID,
187 "IntfId": onu.PonPortID,
188 "OnuSn": onu.Sn(),
189 }).Errorf("Cannot poweron ONU: %s", err.Error())
190 res.StatusCode = int32(codes.FailedPrecondition)
191 res.Message = err.Error()
192 return res, err
193 }
194 }
195
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800196 losReq := bbsim.ONUAlarmRequest{
197 AlarmType: "LossOfSignal",
198 SerialNumber: onu.Sn(),
199 Status: "off",
200 }
201
202 if err := alarmsim.SimulateOnuAlarm(context.TODO(), &losReq, olt); err != nil {
203 logger.WithFields(log.Fields{
204 "OnuId": onu.ID,
205 "IntfId": onu.PonPortID,
206 "OnuSn": onu.Sn(),
207 }).Errorf("Cannot send LOS: %s", err.Error())
208 res.StatusCode = int32(codes.FailedPrecondition)
209 res.Message = err.Error()
210 return res, err
211 }
212
Pragya Arya1cbefa42020-01-13 12:15:29 +0530213 if err := onu.InternalState.Event("discover"); err != nil {
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700214 logger.WithFields(log.Fields{
215 "OnuId": onu.ID,
216 "IntfId": onu.PonPortID,
217 "OnuSn": onu.Sn(),
218 }).Errorf("Cannot poweron ONU: %s", err.Error())
219 res.StatusCode = int32(codes.FailedPrecondition)
220 res.Message = err.Error()
221 return res, err
222 }
223
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800224 if err := onu.InternalState.Event("enable"); err != nil {
225 logger.WithFields(log.Fields{
226 "OnuId": onu.ID,
227 "IntfId": onu.PonPortID,
228 "OnuSn": onu.Sn(),
229 }).Errorf("Cannot enable ONU: %s", err.Error())
230 res.StatusCode = int32(codes.FailedPrecondition)
231 res.Message = err.Error()
232 return res, err
233 }
234
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700235 res.StatusCode = int32(codes.OK)
236 res.Message = fmt.Sprintf("ONU %s successfully powered on.", onu.Sn())
237
238 return res, nil
239}
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700240
Arjun E K57a7fcb2020-01-30 06:44:45 +0000241func (s BBSimServer) ChangeIgmpState(ctx context.Context, req *bbsim.IgmpRequest) (*bbsim.Response, error) {
242 res := &bbsim.Response{}
243
244 logger.WithFields(log.Fields{
245 "OnuSn": req.OnuReq.SerialNumber,
246 "subAction": req.SubActionVal,
247 }).Infof("Received igmp request for ONU")
248
249 olt := devices.GetOLT()
250 onu, err := olt.FindOnuBySn(req.OnuReq.SerialNumber)
251
252 if err != nil {
253 res.StatusCode = int32(codes.NotFound)
254 res.Message = err.Error()
255 fmt.Println("ONU not found for sending igmp packet.")
256 return res, err
257 } else {
258 event := ""
259 switch req.SubActionVal {
260 case bbsim.SubActionTypes_JOIN:
261 event = "igmp_join_start"
262 case bbsim.SubActionTypes_LEAVE:
263 event = "igmp_leave"
Anand S Katti09541352020-01-29 15:54:01 +0530264 case bbsim.SubActionTypes_JOINV3:
265 event = "igmp_join_startv3"
Arjun E K57a7fcb2020-01-30 06:44:45 +0000266 }
267
268 if igmpErr := onu.InternalState.Event(event); igmpErr != nil {
269 logger.WithFields(log.Fields{
270 "OnuId": onu.ID,
271 "IntfId": onu.PonPortID,
272 "OnuSn": onu.Sn(),
273 }).Errorf("IGMP request failed: %s", igmpErr.Error())
274 res.StatusCode = int32(codes.FailedPrecondition)
275 res.Message = err.Error()
276 return res, igmpErr
277 }
278 }
279
280 return res, nil
281}
282
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700283func (s BBSimServer) RestartEapol(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
284 res := &bbsim.Response{}
285
286 logger.WithFields(log.Fields{
287 "OnuSn": req.SerialNumber,
288 }).Infof("Received request to restart authentication ONU")
289
290 olt := devices.GetOLT()
291
292 onu, err := olt.FindOnuBySn(req.SerialNumber)
293
294 if err != nil {
295 res.StatusCode = int32(codes.NotFound)
296 res.Message = err.Error()
297 return res, err
298 }
299
300 if err := onu.InternalState.Event("start_auth"); err != nil {
301 logger.WithFields(log.Fields{
302 "OnuId": onu.ID,
303 "IntfId": onu.PonPortID,
304 "OnuSn": onu.Sn(),
305 }).Errorf("Cannot restart authenticaton for ONU: %s", err.Error())
306 res.StatusCode = int32(codes.FailedPrecondition)
307 res.Message = err.Error()
308 return res, err
309 }
310
311 res.StatusCode = int32(codes.OK)
312 res.Message = fmt.Sprintf("Authentication restarted for ONU %s.", onu.Sn())
313
314 return res, nil
315}
316
317func (s BBSimServer) RestartDhcp(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
318 res := &bbsim.Response{}
319
320 logger.WithFields(log.Fields{
321 "OnuSn": req.SerialNumber,
322 }).Infof("Received request to restart DHCP on ONU")
323
324 olt := devices.GetOLT()
325
326 onu, err := olt.FindOnuBySn(req.SerialNumber)
327
328 if err != nil {
329 res.StatusCode = int32(codes.NotFound)
330 res.Message = err.Error()
331 return res, err
332 }
333
334 if err := onu.InternalState.Event("start_dhcp"); err != nil {
335 logger.WithFields(log.Fields{
336 "OnuId": onu.ID,
337 "IntfId": onu.PonPortID,
338 "OnuSn": onu.Sn(),
339 }).Errorf("Cannot restart DHCP for ONU: %s", err.Error())
340 res.StatusCode = int32(codes.FailedPrecondition)
341 res.Message = err.Error()
342 return res, err
343 }
344
345 res.StatusCode = int32(codes.OK)
346 res.Message = fmt.Sprintf("DHCP restarted for ONU %s.", onu.Sn())
347
348 return res, nil
349}
Anand S Katti09541352020-01-29 15:54:01 +0530350
Pragya Arya8bdb4532020-03-02 17:08:09 +0530351// GetFlows for OLT/ONUs
352func (s BBSimServer) GetFlows(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Flows, error) {
353 logger.WithFields(log.Fields{
354 "OnuSn": req.SerialNumber,
355 }).Info("Received GetFlows request")
356
357 olt := devices.GetOLT()
358 res := &bbsim.Flows{}
359
360 if req.SerialNumber == "" {
361 for flowKey := range olt.Flows {
362 flow := olt.Flows[flowKey]
363 res.Flows = append(res.Flows, &flow)
364 }
365 res.FlowCount = uint32(len(olt.Flows))
366 } else {
367 onu, err := olt.FindOnuBySn(req.SerialNumber)
368 if err != nil {
369 logger.WithFields(log.Fields{
370 "OnuSn": req.SerialNumber,
371 }).Error("Can't get ONU in GetFlows request")
372 return nil, err
373 }
374 for _, flowKey := range onu.Flows {
375 flow := olt.Flows[flowKey]
376 res.Flows = append(res.Flows, &flow)
377 }
378 res.FlowCount = uint32(len(onu.Flows))
379 }
380 return res, nil
381}
382
Anand S Katti09541352020-01-29 15:54:01 +0530383func (s BBSimServer) GetOnuTrafficSchedulers(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONUTrafficSchedulers, error) {
384 olt := devices.GetOLT()
385 ts := bbsim.ONUTrafficSchedulers{}
386
387 onu, err := olt.FindOnuBySn(req.SerialNumber)
388 if err != nil {
389 return &ts, err
390 }
391
392 if onu.TrafficSchedulers != nil {
393 ts.TraffSchedulers = onu.TrafficSchedulers
394 return &ts, nil
395 } else {
396 ts.TraffSchedulers = nil
397 return &ts, nil
398 }
399}