blob: 91a107d96db6a212f0157802c5117d3d28bfafd3 [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"
Matteo Scandolof9d43412021-01-12 11:11:34 -080022 "github.com/opencord/bbsim/internal/bbsim/types"
Andrea Campanellabe8e12f2020-12-14 18:43:41 +010023 "github.com/opencord/voltha-protos/v4/go/openolt"
Nitin Subramanian150f1bb2021-08-02 12:04:05 -070024 "strconv"
Pragya Arya1d5ffb82020-03-20 18:51:37 +053025
Matteo Scandolo10f965c2019-09-24 10:40:46 -070026 "github.com/opencord/bbsim/api/bbsim"
27 "github.com/opencord/bbsim/internal/bbsim/devices"
28 log "github.com/sirupsen/logrus"
29 "google.golang.org/grpc/codes"
30)
31
32func (s BBSimServer) GetONUs(ctx context.Context, req *bbsim.Empty) (*bbsim.ONUs, error) {
33 olt := devices.GetOLT()
34 onus := bbsim.ONUs{
35 Items: []*bbsim.ONU{},
36 }
37
38 for _, pon := range olt.Pons {
39 for _, o := range pon.Onus {
40 onu := bbsim.ONU{
Matteo Scandolocedde462021-03-09 17:37:16 -080041 ID: int32(o.ID),
42 SerialNumber: o.Sn(),
43 OperState: o.OperState.Current(),
44 InternalState: o.InternalState.Current(),
45 PonPortID: int32(o.PonPortID),
Matteo Scandolocedde462021-03-09 17:37:16 -080046 ImageSoftwareReceivedSections: int32(o.ImageSoftwareReceivedSections),
47 ImageSoftwareExpectedSections: int32(o.ImageSoftwareExpectedSections),
48 ActiveImageEntityId: int32(o.ActiveImageEntityId),
49 CommittedImageEntityId: int32(o.CommittedImageEntityId),
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070050 Unis: convertBBsimUniPortsToProtoUniPorts(o.UniPorts),
Matteo Scandolo10f965c2019-09-24 10:40:46 -070051 }
52 onus.Items = append(onus.Items, &onu)
53 }
54 }
55 return &onus, nil
56}
57
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070058func (s BBSimServer) GetONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONU, error) {
59 olt := devices.GetOLT()
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070060 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070061
62 if err != nil {
63 res := bbsim.ONU{}
64 return &res, err
65 }
66
67 res := bbsim.ONU{
68 ID: int32(onu.ID),
69 SerialNumber: onu.Sn(),
70 OperState: onu.OperState.Current(),
71 InternalState: onu.InternalState.Current(),
72 PonPortID: int32(onu.PonPortID),
Matteo Scandoloef4e8f82021-05-17 11:20:49 -070073 Unis: convertBBsimUniPortsToProtoUniPorts(onu.UniPorts),
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070074 }
75 return &res, nil
76}
77
Pragya Aryabd731ec2020-02-11 16:38:17 +053078// ShutdownONU sends DyingGasp indication for specified ONUs and mark ONUs as disabled.
Matteo Scandolo10f965c2019-09-24 10:40:46 -070079func (s BBSimServer) ShutdownONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
Anand S Katti09541352020-01-29 15:54:01 +053080 // 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 -070081 // is this the only way to do? Should we address other cases?
82 // Investigate what happens when:
83 // - a fiber is pulled
84 // - ONU malfunction
85 // - ONU shutdown
Matteo Scandolo10f965c2019-09-24 10:40:46 -070086 logger.WithFields(log.Fields{
87 "OnuSn": req.SerialNumber,
88 }).Infof("Received request to shutdown ONU")
89
Pragya Aryabd731ec2020-02-11 16:38:17 +053090 res := &bbsim.Response{}
Matteo Scandolo10f965c2019-09-24 10:40:46 -070091 olt := devices.GetOLT()
92
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070093 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -070094 if err != nil {
95 res.StatusCode = int32(codes.NotFound)
96 res.Message = err.Error()
97 return res, err
98 }
99
Pragya Aryabd731ec2020-02-11 16:38:17 +0530100 return handleShutdownONU(onu)
101}
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700102
Pragya Aryabd731ec2020-02-11 16:38:17 +0530103// ShutdownONUsOnPON sends DyingGasp indication for all ONUs under specified PON port
104func (s BBSimServer) ShutdownONUsOnPON(ctx context.Context, req *bbsim.PONRequest) (*bbsim.Response, error) {
105 logger.WithFields(log.Fields{
106 "IntfId": req.PonPortId,
107 }).Infof("Received request to shutdown all ONUs on PON")
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800108
Pragya Aryabd731ec2020-02-11 16:38:17 +0530109 res := &bbsim.Response{}
110 olt := devices.GetOLT()
111 pon, _ := olt.GetPonById(req.PonPortId)
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800112
Pragya Aryabd731ec2020-02-11 16:38:17 +0530113 go func() {
114 for _, onu := range pon.Onus {
115 res, _ = handleShutdownONU(onu)
116 }
117 }()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700118 res.StatusCode = int32(codes.OK)
Pragya Aryabd731ec2020-02-11 16:38:17 +0530119 res.Message = fmt.Sprintf("Request accepted for shutdown all ONUs on PON port %d", pon.ID)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700120
121 return res, nil
122}
123
Pragya Aryabd731ec2020-02-11 16:38:17 +0530124// ShutdownAllONUs sends DyingGasp indication for all ONUs and mark ONUs as disabled.
125func (s BBSimServer) ShutdownAllONUs(context.Context, *bbsim.Empty) (*bbsim.Response, error) {
126 logger.Infof("Received request to shutdown all ONUs")
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700127 res := &bbsim.Response{}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530128 olt := devices.GetOLT()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700129
Pragya Aryabd731ec2020-02-11 16:38:17 +0530130 go func() {
131 for _, pon := range olt.Pons {
132 for _, onu := range pon.Onus {
133 res, _ = handleShutdownONU(onu)
134 }
135 }
136 }()
137 res.StatusCode = int32(codes.OK)
138 res.Message = fmt.Sprintf("Request Accepted for shutdown all ONUs in OLT %d", olt.ID)
139
140 return res, nil
141}
142
143// PoweronONU simulates ONU power on and start sending discovery indications to VOLTHA
144func (s BBSimServer) PoweronONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700145 logger.WithFields(log.Fields{
146 "OnuSn": req.SerialNumber,
147 }).Infof("Received request to poweron ONU")
148
Pragya Aryabd731ec2020-02-11 16:38:17 +0530149 res := &bbsim.Response{}
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700150 olt := devices.GetOLT()
151
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700152 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700153 if err != nil {
154 res.StatusCode = int32(codes.NotFound)
155 res.Message = err.Error()
156 return res, err
157 }
158
Pragya Arya2225f202020-01-29 18:05:01 +0530159 pon, _ := olt.GetPonById(onu.PonPortID)
160 if pon.InternalState.Current() != "enabled" {
161 err := fmt.Errorf("PON port %d not enabled", onu.PonPortID)
162 logger.WithFields(log.Fields{
163 "OnuId": onu.ID,
164 "IntfId": onu.PonPortID,
165 "OnuSn": onu.Sn(),
166 }).Errorf("Cannot poweron ONU: %s", err.Error())
167
168 res.StatusCode = int32(codes.FailedPrecondition)
169 res.Message = err.Error()
170 return res, err
171 }
172
Pragya Aryabd731ec2020-02-11 16:38:17 +0530173 return handlePoweronONU(onu)
174}
175
176// PoweronONUsOnPON simulates ONU power on for all ONUs under specified PON port
177func (s BBSimServer) PoweronONUsOnPON(ctx context.Context, req *bbsim.PONRequest) (*bbsim.Response, error) {
178 logger.WithFields(log.Fields{
179 "IntfId": req.PonPortId,
180 }).Infof("Received request to poweron all ONUs on PON")
181
182 res := &bbsim.Response{}
183 olt := devices.GetOLT()
184
185 pon, _ := olt.GetPonById(req.PonPortId)
186 if pon.InternalState.Current() != "enabled" {
187 err := fmt.Errorf("PON port %d not enabled", pon.ID)
188 logger.WithFields(log.Fields{
189 "IntfId": pon.ID,
190 }).Errorf("Cannot poweron ONUs on PON: %s", err.Error())
191
192 res.StatusCode = int32(codes.FailedPrecondition)
193 res.Message = err.Error()
194 return res, err
195 }
196
197 go func() {
198 for _, onu := range pon.Onus {
199 res, _ = handlePoweronONU(onu)
Pragya Arya2225f202020-01-29 18:05:01 +0530200 }
Pragya Aryabd731ec2020-02-11 16:38:17 +0530201 }()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700202 res.StatusCode = int32(codes.OK)
Pragya Aryabd731ec2020-02-11 16:38:17 +0530203 res.Message = fmt.Sprintf("Request Accepted for power on all ONUs on PON port %d", pon.ID)
204
205 return res, nil
206}
207
208// PoweronAllONUs simulates ONU power on for all ONUs on all PON ports
209func (s BBSimServer) PoweronAllONUs(context.Context, *bbsim.Empty) (*bbsim.Response, error) {
210 logger.Infof("Received request to poweron all ONUs")
211
212 res := &bbsim.Response{}
213 olt := devices.GetOLT()
214
215 go func() {
216 for _, pon := range olt.Pons {
217 if pon.InternalState.Current() == "enabled" {
218 for _, onu := range pon.Onus {
219 res, _ = handlePoweronONU(onu)
220 }
221 }
222 }
223 }()
224 res.StatusCode = int32(codes.OK)
225 res.Message = fmt.Sprintf("Request Accepted for power on all ONUs in OLT %d", olt.ID)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700226
227 return res, nil
228}
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700229
Arjun E K57a7fcb2020-01-30 06:44:45 +0000230func (s BBSimServer) ChangeIgmpState(ctx context.Context, req *bbsim.IgmpRequest) (*bbsim.Response, error) {
Matteo Scandolo618a6582020-09-09 12:21:29 -0700231
Matteo Scandolo8a574812021-05-20 15:18:53 -0700232 // NOTE this API will change the IGMP state for all UNIs on the requested ONU
233 // TODO a new API needs to be created to individually manage the UNIs
Matteo Scandolo618a6582020-09-09 12:21:29 -0700234
Arjun E K57a7fcb2020-01-30 06:44:45 +0000235 res := &bbsim.Response{}
236
237 logger.WithFields(log.Fields{
Onur Kalinagac9f9faca2021-01-21 14:04:34 +0000238 "OnuSn": req.OnuReq.SerialNumber,
239 "subAction": req.SubActionVal,
240 "GroupAddress": req.GroupAddress,
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800241 }).Info("Received igmp request for ONU")
Arjun E K57a7fcb2020-01-30 06:44:45 +0000242
243 olt := devices.GetOLT()
244 onu, err := olt.FindOnuBySn(req.OnuReq.SerialNumber)
245
246 if err != nil {
247 res.StatusCode = int32(codes.NotFound)
248 res.Message = err.Error()
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800249 logger.WithFields(log.Fields{
250 "OnuSn": req.OnuReq.SerialNumber,
251 "subAction": req.SubActionVal,
252 "GroupAddress": req.GroupAddress,
253 }).Warn("ONU not found for sending igmp packet.")
Arjun E K57a7fcb2020-01-30 06:44:45 +0000254 return res, err
255 } else {
256 event := ""
257 switch req.SubActionVal {
258 case bbsim.SubActionTypes_JOIN:
259 event = "igmp_join_start"
260 case bbsim.SubActionTypes_LEAVE:
261 event = "igmp_leave"
Anand S Katti09541352020-01-29 15:54:01 +0530262 case bbsim.SubActionTypes_JOINV3:
263 event = "igmp_join_startv3"
Arjun E K57a7fcb2020-01-30 06:44:45 +0000264 }
265
Matteo Scandolo618a6582020-09-09 12:21:29 -0700266 errors := []string{}
267 startedOn := []string{}
268 success := true
269
Matteo Scandolo8a574812021-05-20 15:18:53 -0700270 for _, u := range onu.UniPorts {
271 uni := u.(*devices.UniPort)
272 if !uni.OperState.Is(devices.UniStateUp) {
273 // if the UNI is disabled, ignore it
274 continue
275 }
276 for _, s := range uni.Services {
277 service := s.(*devices.Service)
278 serviceKey := fmt.Sprintf("uni[%d]%s", uni.ID, service.Name)
279 if service.NeedsIgmp {
280 if !service.InternalState.Is(devices.ServiceStateInitialized) {
281 logger.WithFields(log.Fields{
282 "OnuId": onu.ID,
283 "UniId": uni.ID,
284 "IntfId": onu.PonPortID,
285 "OnuSn": onu.Sn(),
286 "Service": service.Name,
287 }).Warn("service-not-initialized-skipping-event")
288 continue
289 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700290 logger.WithFields(log.Fields{
291 "OnuId": onu.ID,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700292 "UniId": uni.ID,
Matteo Scandolo618a6582020-09-09 12:21:29 -0700293 "IntfId": onu.PonPortID,
294 "OnuSn": onu.Sn(),
295 "Service": service.Name,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700296 "Uni": uni.ID,
297 }).Debugf("Sending %s event on Service %s", event, service.Name)
298
299 if err := service.IGMPState.Event(event, types.IgmpMessage{GroupAddress: req.GroupAddress}); err != nil {
300 logger.WithFields(log.Fields{
301 "OnuId": onu.ID,
302 "UniId": uni.ID,
303 "IntfId": onu.PonPortID,
304 "OnuSn": onu.Sn(),
305 "Service": service.Name,
306 }).Errorf("IGMP request failed: %s", err.Error())
307 errors = append(errors, fmt.Sprintf("%s: %s", serviceKey, err.Error()))
308 success = false
309 }
310 startedOn = append(startedOn, serviceKey)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700311 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700312 }
313 }
314
315 if success {
316 res.StatusCode = int32(codes.OK)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800317 if len(startedOn) > 0 {
318 res.Message = fmt.Sprintf("IGMP %s sent on Services %s for ONU %s.",
319 event, fmt.Sprintf("%v", startedOn), onu.Sn())
320 } else {
321 res.Message = "No service requires IGMP"
322 }
323 logger.WithFields(log.Fields{
324 "OnuSn": req.OnuReq.SerialNumber,
325 "subAction": req.SubActionVal,
326 "GroupAddress": req.GroupAddress,
327 "Message": res.Message,
328 }).Info("Processed IGMP request for ONU")
Matteo Scandolo618a6582020-09-09 12:21:29 -0700329 } else {
Arjun E K57a7fcb2020-01-30 06:44:45 +0000330 res.StatusCode = int32(codes.FailedPrecondition)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700331 res.Message = fmt.Sprintf("%v", errors)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800332 logger.WithFields(log.Fields{
333 "OnuSn": req.OnuReq.SerialNumber,
334 "subAction": req.SubActionVal,
335 "GroupAddress": req.GroupAddress,
336 "Message": res.Message,
337 }).Error("Error while processing IGMP request for ONU")
Arjun E K57a7fcb2020-01-30 06:44:45 +0000338 }
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800339
Arjun E K57a7fcb2020-01-30 06:44:45 +0000340 }
341
342 return res, nil
343}
344
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700345func (s BBSimServer) RestartEapol(ctx context.Context, req *bbsim.UNIRequest) (*bbsim.Response, error) {
346 // NOTE this API will change the EAPOL state for all UNIs on the requested ONU if no UNI is specified
347 // Otherwise, it will change the EAPOL state for only the specified UNI on the ONU
Matteo Scandolo8a574812021-05-20 15:18:53 -0700348
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700349 res := &bbsim.Response{}
350
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700351 if req.UniID == "" {
352 logger.WithFields(log.Fields{
353 "OnuSn": req.OnuSerialNumber,
354 }).Infof("Received request to restart authentication for all UNIs on the ONU")
355 } else {
356 logger.WithFields(log.Fields{
357 "OnuSn": req.OnuSerialNumber,
358 "UniId": req.UniID,
359 }).Infof("Received request to restart authentication on UNI")
360 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700361
362 olt := devices.GetOLT()
363
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700364 onu, err := olt.FindOnuBySn(req.OnuSerialNumber)
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700365
366 if err != nil {
367 res.StatusCode = int32(codes.NotFound)
368 res.Message = err.Error()
369 return res, err
370 }
371
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700372 errors := []string{}
Matteo Scandolo618a6582020-09-09 12:21:29 -0700373 startedOn := []string{}
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700374 success := true
375
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700376 uniIDint, err := strconv.Atoi(req.UniID)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700377 for _, u := range onu.UniPorts {
378 uni := u.(*devices.UniPort)
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700379 //if a specific uni is specified, only restart it
380 if err == nil && req.UniID != "" && uni.ID != uint32(uniIDint) {
381 continue
382 }
Matteo Scandolo8a574812021-05-20 15:18:53 -0700383 if !uni.OperState.Is(devices.UniStateUp) {
384 // if the UNI is disabled, ignore it
385 continue
386 }
387 for _, s := range uni.Services {
388 service := s.(*devices.Service)
389 serviceKey := fmt.Sprintf("uni[%d]%s", uni.ID, service.Name)
390 if service.NeedsEapol {
391 if !service.InternalState.Is(devices.ServiceStateInitialized) {
392 logger.WithFields(log.Fields{
393 "OnuId": onu.ID,
394 "UniId": uni.ID,
395 "IntfId": onu.PonPortID,
396 "OnuSn": onu.Sn(),
397 "Service": service.Name,
398 }).Warn("service-not-initialized-skipping-event")
399 continue
400 }
401 if err := service.EapolState.Event("start_auth"); err != nil {
402 logger.WithFields(log.Fields{
403 "OnuId": onu.ID,
404 "IntfId": onu.PonPortID,
405 "OnuSn": onu.Sn(),
406 "UniId": uni.ID,
407 "Service": service.Name,
408 }).Errorf("Cannot restart authenticaton for Service: %s", err.Error())
409 errors = append(errors, fmt.Sprintf("%s: %s", serviceKey, err.Error()))
410 success = false
411 }
412 startedOn = append(startedOn, serviceKey)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700413 }
414 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700415 }
416
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700417 if success {
418 res.StatusCode = int32(codes.OK)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800419 if len(startedOn) > 0 {
420 res.Message = fmt.Sprintf("Authentication restarted on Services %s for ONU %s.",
421 fmt.Sprintf("%v", startedOn), onu.Sn())
422 } else {
423 res.Message = "No service requires EAPOL"
424 }
425
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700426 if req.UniID == "" {
427 logger.WithFields(log.Fields{
428 "OnuSn": req.OnuSerialNumber,
429 "Message": res.Message,
430 }).Info("Processed EAPOL restart request for all UNIs on the ONU")
431 } else {
432 logger.WithFields(log.Fields{
433 "OnuSn": req.OnuSerialNumber,
434 "Message": res.Message,
435 "UniId": req.UniID,
436 }).Info("Processed EAPOL restart request on UNI")
437 }
438
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700439 } else {
440 res.StatusCode = int32(codes.FailedPrecondition)
441 res.Message = fmt.Sprintf("%v", errors)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800442 logger.WithFields(log.Fields{
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700443 "OnuSn": req.OnuSerialNumber,
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800444 "Message": res.Message,
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700445 }).Error("Error while processing EAPOL restart request for ONU")
446
447 if req.UniID == "" {
448 logger.WithFields(log.Fields{
449 "OnuSn": req.OnuSerialNumber,
450 "Message": res.Message,
451 }).Error("Error while processing EAPOL restart request for all UNIs on the ONU")
452 } else {
453 logger.WithFields(log.Fields{
454 "OnuSn": req.OnuSerialNumber,
455 "Message": res.Message,
456 "UniId": req.UniID,
457 }).Error("Error while processing EAPOL restart request on UNI")
458 }
459
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700460 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700461
462 return res, nil
463}
464
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700465func (s BBSimServer) RestartDhcp(ctx context.Context, req *bbsim.UNIRequest) (*bbsim.Response, error) {
466 // NOTE this API will change the DHCP state for all UNIs on the requested ONU if no UNI is specified
467 // Otherwise, it will change the DHCP state for only the specified UNI on the ONU
Matteo Scandolo8a574812021-05-20 15:18:53 -0700468
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700469 res := &bbsim.Response{}
470
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700471 if req.UniID == "" {
472 logger.WithFields(log.Fields{
473 "OnuSn": req.OnuSerialNumber,
474 }).Infof("Received request to restart authentication for all UNIs on the ONU")
475 } else {
476 logger.WithFields(log.Fields{
477 "OnuSn": req.OnuSerialNumber,
478 "UniId": req.UniID,
479 }).Infof("Received request to restart authentication on UNI")
480 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700481
482 olt := devices.GetOLT()
483
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700484 onu, err := olt.FindOnuBySn(req.OnuSerialNumber)
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700485
486 if err != nil {
487 res.StatusCode = int32(codes.NotFound)
488 res.Message = err.Error()
489 return res, err
490 }
491
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700492 errors := []string{}
Matteo Scandolo618a6582020-09-09 12:21:29 -0700493 startedOn := []string{}
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700494 success := true
495
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700496 uniIDint, err := strconv.Atoi(req.UniID)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700497 for _, u := range onu.UniPorts {
498 uni := u.(*devices.UniPort)
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700499 //if a specific uni is specified, only restart it
500 if err == nil && req.UniID != "" && uni.ID != uint32(uniIDint) {
501 continue
502 }
Matteo Scandolo8a574812021-05-20 15:18:53 -0700503 if !uni.OperState.Is(devices.UniStateUp) {
504 // if the UNI is disabled, ignore it
505 continue
506 }
507 for _, s := range uni.Services {
508 service := s.(*devices.Service)
509 serviceKey := fmt.Sprintf("uni[%d]%s", uni.ID, service.Name)
510 if service.NeedsDhcp {
Matteo Scandolo8a574812021-05-20 15:18:53 -0700511 if err := service.DHCPState.Event("start_dhcp"); err != nil {
512 logger.WithFields(log.Fields{
513 "OnuId": onu.ID,
514 "IntfId": onu.PonPortID,
515 "OnuSn": onu.Sn(),
516 "UniId": uni.ID,
517 "Service": service.Name,
518 }).Errorf("Cannot restart DHCP for Service: %s", err.Error())
519 errors = append(errors, fmt.Sprintf("%s: %s", serviceKey, err.Error()))
520 success = false
521 }
522 startedOn = append(startedOn, serviceKey)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700523 }
524 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700525 }
526
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700527 if success {
528 res.StatusCode = int32(codes.OK)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800529 if len(startedOn) > 0 {
530 res.Message = fmt.Sprintf("DHCP restarted on Services %s for ONU %s.",
531 fmt.Sprintf("%v", startedOn), onu.Sn())
532
533 } else {
534 res.Message = "No service requires DHCP"
535 }
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700536
537 if req.UniID == "" {
538 logger.WithFields(log.Fields{
539 "OnuSn": req.OnuSerialNumber,
540 "Message": res.Message,
541 }).Info("Processed DHCP restart request for all UNIs on the ONU")
542 } else {
543 logger.WithFields(log.Fields{
544 "OnuSn": req.OnuSerialNumber,
545 "Message": res.Message,
546 "UniId": req.UniID,
547 }).Info("Processed DHCP restart request on UNI")
548 }
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700549 } else {
550 res.StatusCode = int32(codes.FailedPrecondition)
551 res.Message = fmt.Sprintf("%v", errors)
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700552
553 if req.UniID == "" {
554 logger.WithFields(log.Fields{
555 "OnuSn": req.OnuSerialNumber,
556 "Message": res.Message,
557 }).Error("Error while processing DHCP restart request for all UNIs on the ONU")
558 } else {
559 logger.WithFields(log.Fields{
560 "OnuSn": req.OnuSerialNumber,
561 "Message": res.Message,
562 "UniId": req.UniID,
563 }).Error("Error while processing DHCP restart request on UNI")
564 }
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700565 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700566
567 return res, nil
568}
Anand S Katti09541352020-01-29 15:54:01 +0530569
Pragya Arya8bdb4532020-03-02 17:08:09 +0530570// GetFlows for OLT/ONUs
571func (s BBSimServer) GetFlows(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Flows, error) {
572 logger.WithFields(log.Fields{
573 "OnuSn": req.SerialNumber,
574 }).Info("Received GetFlows request")
575
576 olt := devices.GetOLT()
577 res := &bbsim.Flows{}
578
579 if req.SerialNumber == "" {
Andrea Campanellabe8e12f2020-12-14 18:43:41 +0100580 olt.Flows.Range(func(flowKey, flow interface{}) bool {
581 flowObj := flow.(openolt.Flow)
582 res.Flows = append(res.Flows, &flowObj)
583 return true
584 })
585 res.FlowCount = uint32(len(res.Flows))
Pragya Arya8bdb4532020-03-02 17:08:09 +0530586 } else {
587 onu, err := olt.FindOnuBySn(req.SerialNumber)
588 if err != nil {
589 logger.WithFields(log.Fields{
590 "OnuSn": req.SerialNumber,
591 }).Error("Can't get ONU in GetFlows request")
592 return nil, err
593 }
594 for _, flowKey := range onu.Flows {
Andrea Campanellabe8e12f2020-12-14 18:43:41 +0100595 flow, _ := olt.Flows.Load(flowKey)
596 flowObj := flow.(openolt.Flow)
597 res.Flows = append(res.Flows, &flowObj)
Pragya Arya8bdb4532020-03-02 17:08:09 +0530598 }
599 res.FlowCount = uint32(len(onu.Flows))
600 }
601 return res, nil
602}
603
Anand S Katti09541352020-01-29 15:54:01 +0530604func (s BBSimServer) GetOnuTrafficSchedulers(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONUTrafficSchedulers, error) {
605 olt := devices.GetOLT()
606 ts := bbsim.ONUTrafficSchedulers{}
607
608 onu, err := olt.FindOnuBySn(req.SerialNumber)
609 if err != nil {
610 return &ts, err
611 }
612
613 if onu.TrafficSchedulers != nil {
614 ts.TraffSchedulers = onu.TrafficSchedulers
615 return &ts, nil
616 } else {
617 ts.TraffSchedulers = nil
618 return &ts, nil
619 }
620}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530621
622func handlePoweronONU(onu *devices.Onu) (*bbsim.Response, error) {
623 res := &bbsim.Response{}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530624
Matteo Scandolof9d43412021-01-12 11:11:34 -0800625 if err := onu.HandlePowerOnONU(); err != nil {
Pragya Aryabd731ec2020-02-11 16:38:17 +0530626 res.StatusCode = int32(codes.FailedPrecondition)
627 res.Message = err.Error()
628 return res, err
629 }
630
Pragya Aryabd731ec2020-02-11 16:38:17 +0530631 res.StatusCode = int32(codes.OK)
632 res.Message = fmt.Sprintf("ONU %s successfully powered on.", onu.Sn())
633
634 return res, nil
635}
636
637func handleShutdownONU(onu *devices.Onu) (*bbsim.Response, error) {
638 res := &bbsim.Response{}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530639
Matteo Scandolof9d43412021-01-12 11:11:34 -0800640 if err := onu.HandleShutdownONU(); err != nil {
Pragya Aryabd731ec2020-02-11 16:38:17 +0530641 res.StatusCode = int32(codes.FailedPrecondition)
642 res.Message = err.Error()
643 return res, err
644 }
645
646 res.StatusCode = int32(codes.OK)
647 res.Message = fmt.Sprintf("ONU %s successfully shut down.", onu.Sn())
648
649 return res, nil
650}
Nitin Subramanianb0a333a2021-07-08 15:01:41 -0700651
652func (s BBSimServer) GetUnis(ctx context.Context, req *bbsim.Empty) (*bbsim.UNIs, error) {
653 onus, err := s.GetONUs(ctx, req)
654
655 if err != nil {
656 return nil, err
657 }
658 unis := []*bbsim.UNI{}
659 for _, onu := range onus.Items {
660 unis = append(unis, onu.Unis...)
661 }
662 unis_ret := bbsim.UNIs{
663 Items: unis,
664 }
665 return &unis_ret, nil
666}