blob: 3c843801d03726d8672073f47413b15dacbc8505 [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"
Andrea Campanellabe8e12f2020-12-14 18:43:41 +010022 "github.com/opencord/voltha-protos/v4/go/openolt"
Pragya Arya1d5ffb82020-03-20 18:51:37 +053023
Matteo Scandolo10f965c2019-09-24 10:40:46 -070024 "github.com/opencord/bbsim/api/bbsim"
Matteo Scandolod7cc6d32020-02-26 16:51:12 -080025 "github.com/opencord/bbsim/internal/bbsim/alarmsim"
Matteo Scandolo10f965c2019-09-24 10:40:46 -070026 "github.com/opencord/bbsim/internal/bbsim/devices"
27 log "github.com/sirupsen/logrus"
28 "google.golang.org/grpc/codes"
29)
30
31func (s BBSimServer) GetONUs(ctx context.Context, req *bbsim.Empty) (*bbsim.ONUs, error) {
32 olt := devices.GetOLT()
33 onus := bbsim.ONUs{
34 Items: []*bbsim.ONU{},
35 }
36
37 for _, pon := range olt.Pons {
38 for _, o := range pon.Onus {
39 onu := bbsim.ONU{
40 ID: int32(o.ID),
41 SerialNumber: o.Sn(),
42 OperState: o.OperState.Current(),
43 InternalState: o.InternalState.Current(),
44 PonPortID: int32(o.PonPortID),
Matteo Scandolo27428702019-10-11 16:21:16 -070045 PortNo: int32(o.PortNo),
Matteo Scandolo4a036262020-08-17 15:56:13 -070046 Services: convertBBsimServicesToProtoServices(o.Services),
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),
Matteo Scandolo27428702019-10-11 16:21:16 -070069 PortNo: int32(onu.PortNo),
Matteo Scandolo4a036262020-08-17 15:56:13 -070070 Services: convertBBsimServicesToProtoServices(onu.Services),
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070071 }
72 return &res, nil
73}
74
Pragya Aryabd731ec2020-02-11 16:38:17 +053075// ShutdownONU sends DyingGasp indication for specified ONUs and mark ONUs as disabled.
Matteo Scandolo10f965c2019-09-24 10:40:46 -070076func (s BBSimServer) ShutdownONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
Anand S Katti09541352020-01-29 15:54:01 +053077 // 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 -070078 // is this the only way to do? Should we address other cases?
79 // Investigate what happens when:
80 // - a fiber is pulled
81 // - ONU malfunction
82 // - ONU shutdown
Matteo Scandolo10f965c2019-09-24 10:40:46 -070083 logger.WithFields(log.Fields{
84 "OnuSn": req.SerialNumber,
85 }).Infof("Received request to shutdown ONU")
86
Pragya Aryabd731ec2020-02-11 16:38:17 +053087 res := &bbsim.Response{}
Matteo Scandolo10f965c2019-09-24 10:40:46 -070088 olt := devices.GetOLT()
89
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070090 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -070091 if err != nil {
92 res.StatusCode = int32(codes.NotFound)
93 res.Message = err.Error()
94 return res, err
95 }
96
Pragya Aryabd731ec2020-02-11 16:38:17 +053097 return handleShutdownONU(onu)
98}
Matteo Scandolo10f965c2019-09-24 10:40:46 -070099
Pragya Aryabd731ec2020-02-11 16:38:17 +0530100// ShutdownONUsOnPON sends DyingGasp indication for all ONUs under specified PON port
101func (s BBSimServer) ShutdownONUsOnPON(ctx context.Context, req *bbsim.PONRequest) (*bbsim.Response, error) {
102 logger.WithFields(log.Fields{
103 "IntfId": req.PonPortId,
104 }).Infof("Received request to shutdown all ONUs on PON")
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800105
Pragya Aryabd731ec2020-02-11 16:38:17 +0530106 res := &bbsim.Response{}
107 olt := devices.GetOLT()
108 pon, _ := olt.GetPonById(req.PonPortId)
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800109
Pragya Aryabd731ec2020-02-11 16:38:17 +0530110 go func() {
111 for _, onu := range pon.Onus {
112 res, _ = handleShutdownONU(onu)
113 }
114 }()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700115 res.StatusCode = int32(codes.OK)
Pragya Aryabd731ec2020-02-11 16:38:17 +0530116 res.Message = fmt.Sprintf("Request accepted for shutdown all ONUs on PON port %d", pon.ID)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700117
118 return res, nil
119}
120
Pragya Aryabd731ec2020-02-11 16:38:17 +0530121// ShutdownAllONUs sends DyingGasp indication for all ONUs and mark ONUs as disabled.
122func (s BBSimServer) ShutdownAllONUs(context.Context, *bbsim.Empty) (*bbsim.Response, error) {
123 logger.Infof("Received request to shutdown all ONUs")
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700124 res := &bbsim.Response{}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530125 olt := devices.GetOLT()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700126
Pragya Aryabd731ec2020-02-11 16:38:17 +0530127 go func() {
128 for _, pon := range olt.Pons {
129 for _, onu := range pon.Onus {
130 res, _ = handleShutdownONU(onu)
131 }
132 }
133 }()
134 res.StatusCode = int32(codes.OK)
135 res.Message = fmt.Sprintf("Request Accepted for shutdown all ONUs in OLT %d", olt.ID)
136
137 return res, nil
138}
139
140// PoweronONU simulates ONU power on and start sending discovery indications to VOLTHA
141func (s BBSimServer) PoweronONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700142 logger.WithFields(log.Fields{
143 "OnuSn": req.SerialNumber,
144 }).Infof("Received request to poweron ONU")
145
Pragya Aryabd731ec2020-02-11 16:38:17 +0530146 res := &bbsim.Response{}
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700147 olt := devices.GetOLT()
148
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700149 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700150 if err != nil {
151 res.StatusCode = int32(codes.NotFound)
152 res.Message = err.Error()
153 return res, err
154 }
155
Pragya Arya2225f202020-01-29 18:05:01 +0530156 pon, _ := olt.GetPonById(onu.PonPortID)
157 if pon.InternalState.Current() != "enabled" {
158 err := fmt.Errorf("PON port %d not enabled", onu.PonPortID)
159 logger.WithFields(log.Fields{
160 "OnuId": onu.ID,
161 "IntfId": onu.PonPortID,
162 "OnuSn": onu.Sn(),
163 }).Errorf("Cannot poweron ONU: %s", err.Error())
164
165 res.StatusCode = int32(codes.FailedPrecondition)
166 res.Message = err.Error()
167 return res, err
168 }
169
Pragya Aryabd731ec2020-02-11 16:38:17 +0530170 return handlePoweronONU(onu)
171}
172
173// PoweronONUsOnPON simulates ONU power on for all ONUs under specified PON port
174func (s BBSimServer) PoweronONUsOnPON(ctx context.Context, req *bbsim.PONRequest) (*bbsim.Response, error) {
175 logger.WithFields(log.Fields{
176 "IntfId": req.PonPortId,
177 }).Infof("Received request to poweron all ONUs on PON")
178
179 res := &bbsim.Response{}
180 olt := devices.GetOLT()
181
182 pon, _ := olt.GetPonById(req.PonPortId)
183 if pon.InternalState.Current() != "enabled" {
184 err := fmt.Errorf("PON port %d not enabled", pon.ID)
185 logger.WithFields(log.Fields{
186 "IntfId": pon.ID,
187 }).Errorf("Cannot poweron ONUs on PON: %s", err.Error())
188
189 res.StatusCode = int32(codes.FailedPrecondition)
190 res.Message = err.Error()
191 return res, err
192 }
193
194 go func() {
195 for _, onu := range pon.Onus {
196 res, _ = handlePoweronONU(onu)
Pragya Arya2225f202020-01-29 18:05:01 +0530197 }
Pragya Aryabd731ec2020-02-11 16:38:17 +0530198 }()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700199 res.StatusCode = int32(codes.OK)
Pragya Aryabd731ec2020-02-11 16:38:17 +0530200 res.Message = fmt.Sprintf("Request Accepted for power on all ONUs on PON port %d", pon.ID)
201
202 return res, nil
203}
204
205// PoweronAllONUs simulates ONU power on for all ONUs on all PON ports
206func (s BBSimServer) PoweronAllONUs(context.Context, *bbsim.Empty) (*bbsim.Response, error) {
207 logger.Infof("Received request to poweron all ONUs")
208
209 res := &bbsim.Response{}
210 olt := devices.GetOLT()
211
212 go func() {
213 for _, pon := range olt.Pons {
214 if pon.InternalState.Current() == "enabled" {
215 for _, onu := range pon.Onus {
216 res, _ = handlePoweronONU(onu)
217 }
218 }
219 }
220 }()
221 res.StatusCode = int32(codes.OK)
222 res.Message = fmt.Sprintf("Request Accepted for power on all ONUs in OLT %d", olt.ID)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700223
224 return res, nil
225}
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700226
Arjun E K57a7fcb2020-01-30 06:44:45 +0000227func (s BBSimServer) ChangeIgmpState(ctx context.Context, req *bbsim.IgmpRequest) (*bbsim.Response, error) {
Matteo Scandolo618a6582020-09-09 12:21:29 -0700228
229 // TODO check that the ONU is enabled and the services are initialized before changing the state
230
Arjun E K57a7fcb2020-01-30 06:44:45 +0000231 res := &bbsim.Response{}
232
233 logger.WithFields(log.Fields{
234 "OnuSn": req.OnuReq.SerialNumber,
235 "subAction": req.SubActionVal,
236 }).Infof("Received igmp request for ONU")
237
238 olt := devices.GetOLT()
239 onu, err := olt.FindOnuBySn(req.OnuReq.SerialNumber)
240
241 if err != nil {
242 res.StatusCode = int32(codes.NotFound)
243 res.Message = err.Error()
244 fmt.Println("ONU not found for sending igmp packet.")
245 return res, err
246 } else {
247 event := ""
248 switch req.SubActionVal {
249 case bbsim.SubActionTypes_JOIN:
250 event = "igmp_join_start"
251 case bbsim.SubActionTypes_LEAVE:
252 event = "igmp_leave"
Anand S Katti09541352020-01-29 15:54:01 +0530253 case bbsim.SubActionTypes_JOINV3:
254 event = "igmp_join_startv3"
Arjun E K57a7fcb2020-01-30 06:44:45 +0000255 }
256
Matteo Scandolo618a6582020-09-09 12:21:29 -0700257 errors := []string{}
258 startedOn := []string{}
259 success := true
260
261 for _, s := range onu.Services {
262 service := s.(*devices.Service)
263 if service.NeedsIgmp {
264
265 logger.WithFields(log.Fields{
266 "OnuId": onu.ID,
267 "IntfId": onu.PonPortID,
268 "OnuSn": onu.Sn(),
269 "Service": service.Name,
270 }).Debugf("Sending %s event on Service %s", event, service.Name)
271
272 if err := service.IGMPState.Event(event); err != nil {
273 logger.WithFields(log.Fields{
274 "OnuId": onu.ID,
275 "IntfId": onu.PonPortID,
276 "OnuSn": onu.Sn(),
277 "Service": service.Name,
278 }).Errorf("IGMP request failed: %s", err.Error())
279 errors = append(errors, fmt.Sprintf("%s: %s", service.Name, err.Error()))
280 success = false
281 }
282 startedOn = append(startedOn, service.Name)
283 }
284 }
285
286 if success {
287 res.StatusCode = int32(codes.OK)
288 res.Message = fmt.Sprintf("Authentication restarted on Services %s for ONU %s.",
289 fmt.Sprintf("%v", startedOn), onu.Sn())
290 } else {
Arjun E K57a7fcb2020-01-30 06:44:45 +0000291 res.StatusCode = int32(codes.FailedPrecondition)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700292 res.Message = fmt.Sprintf("%v", errors)
Arjun E K57a7fcb2020-01-30 06:44:45 +0000293 }
294 }
295
296 return res, nil
297}
298
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700299func (s BBSimServer) RestartEapol(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
300 res := &bbsim.Response{}
301
302 logger.WithFields(log.Fields{
303 "OnuSn": req.SerialNumber,
304 }).Infof("Received request to restart authentication ONU")
305
306 olt := devices.GetOLT()
307
308 onu, err := olt.FindOnuBySn(req.SerialNumber)
309
310 if err != nil {
311 res.StatusCode = int32(codes.NotFound)
312 res.Message = err.Error()
313 return res, err
314 }
315
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700316 errors := []string{}
Matteo Scandolo618a6582020-09-09 12:21:29 -0700317 startedOn := []string{}
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700318 success := true
319
320 for _, s := range onu.Services {
321 service := s.(*devices.Service)
322 if service.NeedsEapol {
323 if err := service.EapolState.Event("start_auth"); err != nil {
324 logger.WithFields(log.Fields{
325 "OnuId": onu.ID,
326 "IntfId": onu.PonPortID,
327 "OnuSn": onu.Sn(),
328 "Service": service.Name,
329 }).Errorf("Cannot restart authenticaton for Service: %s", err.Error())
330 errors = append(errors, fmt.Sprintf("%s: %s", service.Name, err.Error()))
331 success = false
332 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700333 startedOn = append(startedOn, service.Name)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700334 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700335 }
336
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700337 if success {
338 res.StatusCode = int32(codes.OK)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700339 res.Message = fmt.Sprintf("Authentication restarted on Services %s for ONU %s.",
340 fmt.Sprintf("%v", startedOn), onu.Sn())
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700341 } else {
342 res.StatusCode = int32(codes.FailedPrecondition)
343 res.Message = fmt.Sprintf("%v", errors)
344 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700345
346 return res, nil
347}
348
349func (s BBSimServer) RestartDhcp(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
350 res := &bbsim.Response{}
351
352 logger.WithFields(log.Fields{
353 "OnuSn": req.SerialNumber,
354 }).Infof("Received request to restart DHCP on ONU")
355
356 olt := devices.GetOLT()
357
358 onu, err := olt.FindOnuBySn(req.SerialNumber)
359
360 if err != nil {
361 res.StatusCode = int32(codes.NotFound)
362 res.Message = err.Error()
363 return res, err
364 }
365
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700366 errors := []string{}
Matteo Scandolo618a6582020-09-09 12:21:29 -0700367 startedOn := []string{}
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700368 success := true
369
370 for _, s := range onu.Services {
371 service := s.(*devices.Service)
372 if service.NeedsDhcp {
373
374 if err := service.DHCPState.Event("start_dhcp"); err != nil {
375 logger.WithFields(log.Fields{
376 "OnuId": onu.ID,
377 "IntfId": onu.PonPortID,
378 "OnuSn": onu.Sn(),
379 "Service": service.Name,
380 }).Errorf("Cannot restart DHCP for Service: %s", err.Error())
381 errors = append(errors, fmt.Sprintf("%s: %s", service.Name, err.Error()))
382 success = false
383 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700384 startedOn = append(startedOn, service.Name)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700385 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700386 }
387
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700388 if success {
389 res.StatusCode = int32(codes.OK)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700390 res.Message = fmt.Sprintf("DHCP restarted on Services %s for ONU %s.",
391 fmt.Sprintf("%v", startedOn), onu.Sn())
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700392 } else {
393 res.StatusCode = int32(codes.FailedPrecondition)
394 res.Message = fmt.Sprintf("%v", errors)
395 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700396
397 return res, nil
398}
Anand S Katti09541352020-01-29 15:54:01 +0530399
Pragya Arya8bdb4532020-03-02 17:08:09 +0530400// GetFlows for OLT/ONUs
401func (s BBSimServer) GetFlows(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Flows, error) {
402 logger.WithFields(log.Fields{
403 "OnuSn": req.SerialNumber,
404 }).Info("Received GetFlows request")
405
406 olt := devices.GetOLT()
407 res := &bbsim.Flows{}
408
409 if req.SerialNumber == "" {
Andrea Campanellabe8e12f2020-12-14 18:43:41 +0100410 olt.Flows.Range(func(flowKey, flow interface{}) bool {
411 flowObj := flow.(openolt.Flow)
412 res.Flows = append(res.Flows, &flowObj)
413 return true
414 })
415 res.FlowCount = uint32(len(res.Flows))
Pragya Arya8bdb4532020-03-02 17:08:09 +0530416 } else {
417 onu, err := olt.FindOnuBySn(req.SerialNumber)
418 if err != nil {
419 logger.WithFields(log.Fields{
420 "OnuSn": req.SerialNumber,
421 }).Error("Can't get ONU in GetFlows request")
422 return nil, err
423 }
424 for _, flowKey := range onu.Flows {
Andrea Campanellabe8e12f2020-12-14 18:43:41 +0100425 flow, _ := olt.Flows.Load(flowKey)
426 flowObj := flow.(openolt.Flow)
427 res.Flows = append(res.Flows, &flowObj)
Pragya Arya8bdb4532020-03-02 17:08:09 +0530428 }
429 res.FlowCount = uint32(len(onu.Flows))
430 }
431 return res, nil
432}
433
Anand S Katti09541352020-01-29 15:54:01 +0530434func (s BBSimServer) GetOnuTrafficSchedulers(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONUTrafficSchedulers, error) {
435 olt := devices.GetOLT()
436 ts := bbsim.ONUTrafficSchedulers{}
437
438 onu, err := olt.FindOnuBySn(req.SerialNumber)
439 if err != nil {
440 return &ts, err
441 }
442
443 if onu.TrafficSchedulers != nil {
444 ts.TraffSchedulers = onu.TrafficSchedulers
445 return &ts, nil
446 } else {
447 ts.TraffSchedulers = nil
448 return &ts, nil
449 }
450}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530451
452func handlePoweronONU(onu *devices.Onu) (*bbsim.Response, error) {
453 res := &bbsim.Response{}
454 olt := devices.GetOLT()
455 intitalState := onu.InternalState.Current()
456 if onu.InternalState.Current() == "created" || onu.InternalState.Current() == "disabled" {
457 if err := onu.InternalState.Event("initialize"); err != nil {
458 logger.WithFields(log.Fields{
459 "OnuId": onu.ID,
460 "IntfId": onu.PonPortID,
461 "OnuSn": onu.Sn(),
462 }).Errorf("Cannot poweron ONU: %s", err.Error())
463 res.StatusCode = int32(codes.FailedPrecondition)
464 res.Message = err.Error()
465 return res, err
466 }
467 }
468
469 losReq := bbsim.ONUAlarmRequest{
Pragya Arya1d5ffb82020-03-20 18:51:37 +0530470 AlarmType: "ONU_ALARM_LOS",
Pragya Aryabd731ec2020-02-11 16:38:17 +0530471 SerialNumber: onu.Sn(),
472 Status: "off",
473 }
474
475 if err := alarmsim.SimulateOnuAlarm(context.TODO(), &losReq, olt); err != nil {
476 logger.WithFields(log.Fields{
477 "OnuId": onu.ID,
478 "IntfId": onu.PonPortID,
479 "OnuSn": onu.Sn(),
480 }).Errorf("Cannot send LOS: %s", err.Error())
481 res.StatusCode = int32(codes.FailedPrecondition)
482 res.Message = err.Error()
483 return res, err
484 }
485
486 if err := onu.InternalState.Event("discover"); err != nil {
487 logger.WithFields(log.Fields{
488 "OnuId": onu.ID,
489 "IntfId": onu.PonPortID,
490 "OnuSn": onu.Sn(),
491 }).Errorf("Cannot poweron ONU: %s", err.Error())
492 res.StatusCode = int32(codes.FailedPrecondition)
493 res.Message = err.Error()
494 return res, err
495 }
496 // move onu directly to enable state only when its a powercycle case
497 // in case of first time onu poweron onu will be moved to enable on
498 // receiving ActivateOnu request from openolt adapter
499 if intitalState == "disabled" {
500 if err := onu.InternalState.Event("enable"); err != nil {
501 logger.WithFields(log.Fields{
502 "OnuId": onu.ID,
503 "IntfId": onu.PonPortID,
504 "OnuSn": onu.Sn(),
505 }).Errorf("Cannot enable ONU: %s", err.Error())
506 res.StatusCode = int32(codes.FailedPrecondition)
507 res.Message = err.Error()
508 return res, err
509 }
510 }
511
512 res.StatusCode = int32(codes.OK)
513 res.Message = fmt.Sprintf("ONU %s successfully powered on.", onu.Sn())
514
515 return res, nil
516}
517
518func handleShutdownONU(onu *devices.Onu) (*bbsim.Response, error) {
519 res := &bbsim.Response{}
520 olt := devices.GetOLT()
521
522 dyingGasp := bbsim.ONUAlarmRequest{
Pragya Arya1d5ffb82020-03-20 18:51:37 +0530523 AlarmType: "DYING_GASP",
Pragya Aryabd731ec2020-02-11 16:38:17 +0530524 SerialNumber: onu.Sn(),
525 Status: "on",
526 }
527
528 if err := alarmsim.SimulateOnuAlarm(context.TODO(), &dyingGasp, olt); err != nil {
529 logger.WithFields(log.Fields{
530 "OnuId": onu.ID,
531 "IntfId": onu.PonPortID,
532 "OnuSn": onu.Sn(),
533 }).Errorf("Cannot send Dying Gasp: %s", err.Error())
534 res.StatusCode = int32(codes.FailedPrecondition)
535 res.Message = err.Error()
536 return res, err
537 }
538
539 losReq := bbsim.ONUAlarmRequest{
Pragya Arya1d5ffb82020-03-20 18:51:37 +0530540 AlarmType: "ONU_ALARM_LOS",
Pragya Aryabd731ec2020-02-11 16:38:17 +0530541 SerialNumber: onu.Sn(),
542 Status: "on",
543 }
544
545 if err := alarmsim.SimulateOnuAlarm(context.TODO(), &losReq, olt); err != nil {
546 logger.WithFields(log.Fields{
547 "OnuId": onu.ID,
548 "IntfId": onu.PonPortID,
549 "OnuSn": onu.Sn(),
550 }).Errorf("Cannot send LOS: %s", err.Error())
551 res.StatusCode = int32(codes.FailedPrecondition)
552 res.Message = err.Error()
553 return res, err
554 }
555
556 // TODO if it's the last ONU on the PON, then send a PON LOS
557
558 if err := onu.InternalState.Event("disable"); err != nil {
559 logger.WithFields(log.Fields{
560 "OnuId": onu.ID,
561 "IntfId": onu.PonPortID,
562 "OnuSn": onu.Sn(),
563 }).Errorf("Cannot shutdown ONU: %s", err.Error())
564 res.StatusCode = int32(codes.FailedPrecondition)
565 res.Message = err.Error()
566 return res, err
567 }
568
569 res.StatusCode = int32(codes.OK)
570 res.Message = fmt.Sprintf("ONU %s successfully shut down.", onu.Sn())
571
572 return res, nil
573}