blob: 29c52acc5d59053bbad043af0c3dcc7bda7ca64a [file] [log] [blame]
Matteo Scandolo10f965c2019-09-24 10:40:46 -07001/*
Joey Armstrong14628cd2023-01-10 08:38:31 -05002 * Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
Matteo Scandolo10f965c2019-09-24 10:40:46 -07003
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"
Elia Battistonfe017662022-01-05 11:43:16 +010022 "strconv"
23
Matteo Scandolof9d43412021-01-12 11:11:34 -080024 "github.com/opencord/bbsim/internal/bbsim/types"
David K. Bainbridgec415efe2021-08-19 13:05:21 +000025 "github.com/opencord/voltha-protos/v5/go/openolt"
Pragya Arya1d5ffb82020-03-20 18:51:37 +053026
Matteo Scandolo10f965c2019-09-24 10:40:46 -070027 "github.com/opencord/bbsim/api/bbsim"
28 "github.com/opencord/bbsim/internal/bbsim/devices"
29 log "github.com/sirupsen/logrus"
30 "google.golang.org/grpc/codes"
31)
32
33func (s BBSimServer) GetONUs(ctx context.Context, req *bbsim.Empty) (*bbsim.ONUs, error) {
34 olt := devices.GetOLT()
35 onus := bbsim.ONUs{
36 Items: []*bbsim.ONU{},
37 }
38
39 for _, pon := range olt.Pons {
40 for _, o := range pon.Onus {
41 onu := bbsim.ONU{
Matteo Scandolocedde462021-03-09 17:37:16 -080042 ID: int32(o.ID),
43 SerialNumber: o.Sn(),
44 OperState: o.OperState.Current(),
45 InternalState: o.InternalState.Current(),
46 PonPortID: int32(o.PonPortID),
Matteo Scandolocedde462021-03-09 17:37:16 -080047 ImageSoftwareReceivedSections: int32(o.ImageSoftwareReceivedSections),
48 ImageSoftwareExpectedSections: int32(o.ImageSoftwareExpectedSections),
49 ActiveImageEntityId: int32(o.ActiveImageEntityId),
50 CommittedImageEntityId: int32(o.CommittedImageEntityId),
Elia Battistonac63b112022-01-12 18:40:49 +010051 Unis: append(convertBBsimUniPortsToProtoUniPorts(o.UniPorts), convertBBsimPotsPortsToProtoUniPorts(o.PotsPorts)...),
Matteo Scandolo10f965c2019-09-24 10:40:46 -070052 }
53 onus.Items = append(onus.Items, &onu)
54 }
55 }
56 return &onus, nil
57}
58
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070059func (s BBSimServer) GetONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONU, error) {
60 olt := devices.GetOLT()
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070061 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070062
63 if err != nil {
64 res := bbsim.ONU{}
65 return &res, err
66 }
67
68 res := bbsim.ONU{
69 ID: int32(onu.ID),
70 SerialNumber: onu.Sn(),
71 OperState: onu.OperState.Current(),
72 InternalState: onu.InternalState.Current(),
73 PonPortID: int32(onu.PonPortID),
Elia Battistonac63b112022-01-12 18:40:49 +010074 Unis: append(convertBBsimUniPortsToProtoUniPorts(onu.UniPorts), convertBBsimPotsPortsToProtoUniPorts(onu.PotsPorts)...),
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070075 }
76 return &res, nil
77}
78
Pragya Aryabd731ec2020-02-11 16:38:17 +053079// ShutdownONU sends DyingGasp indication for specified ONUs and mark ONUs as disabled.
Matteo Scandolo10f965c2019-09-24 10:40:46 -070080func (s BBSimServer) ShutdownONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
Anand S Katti09541352020-01-29 15:54:01 +053081 // 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 -070082 // is this the only way to do? Should we address other cases?
83 // Investigate what happens when:
84 // - a fiber is pulled
85 // - ONU malfunction
86 // - ONU shutdown
Matteo Scandolo10f965c2019-09-24 10:40:46 -070087 logger.WithFields(log.Fields{
88 "OnuSn": req.SerialNumber,
89 }).Infof("Received request to shutdown ONU")
90
Pragya Aryabd731ec2020-02-11 16:38:17 +053091 res := &bbsim.Response{}
Matteo Scandolo10f965c2019-09-24 10:40:46 -070092 olt := devices.GetOLT()
93
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070094 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -070095 if err != nil {
96 res.StatusCode = int32(codes.NotFound)
97 res.Message = err.Error()
98 return res, err
99 }
100
Pragya Aryabd731ec2020-02-11 16:38:17 +0530101 return handleShutdownONU(onu)
102}
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700103
Pragya Aryabd731ec2020-02-11 16:38:17 +0530104// ShutdownONUsOnPON sends DyingGasp indication for all ONUs under specified PON port
105func (s BBSimServer) ShutdownONUsOnPON(ctx context.Context, req *bbsim.PONRequest) (*bbsim.Response, error) {
106 logger.WithFields(log.Fields{
107 "IntfId": req.PonPortId,
108 }).Infof("Received request to shutdown all ONUs on PON")
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800109
Pragya Aryabd731ec2020-02-11 16:38:17 +0530110 res := &bbsim.Response{}
111 olt := devices.GetOLT()
112 pon, _ := olt.GetPonById(req.PonPortId)
Matteo Scandolod7cc6d32020-02-26 16:51:12 -0800113
Pragya Aryabd731ec2020-02-11 16:38:17 +0530114 go func() {
115 for _, onu := range pon.Onus {
116 res, _ = handleShutdownONU(onu)
117 }
118 }()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700119 res.StatusCode = int32(codes.OK)
Pragya Aryabd731ec2020-02-11 16:38:17 +0530120 res.Message = fmt.Sprintf("Request accepted for shutdown all ONUs on PON port %d", pon.ID)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700121
122 return res, nil
123}
124
Pragya Aryabd731ec2020-02-11 16:38:17 +0530125// ShutdownAllONUs sends DyingGasp indication for all ONUs and mark ONUs as disabled.
126func (s BBSimServer) ShutdownAllONUs(context.Context, *bbsim.Empty) (*bbsim.Response, error) {
127 logger.Infof("Received request to shutdown all ONUs")
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700128 res := &bbsim.Response{}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530129 olt := devices.GetOLT()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700130
Pragya Aryabd731ec2020-02-11 16:38:17 +0530131 go func() {
132 for _, pon := range olt.Pons {
133 for _, onu := range pon.Onus {
134 res, _ = handleShutdownONU(onu)
135 }
136 }
137 }()
138 res.StatusCode = int32(codes.OK)
139 res.Message = fmt.Sprintf("Request Accepted for shutdown all ONUs in OLT %d", olt.ID)
140
141 return res, nil
142}
143
144// PoweronONU simulates ONU power on and start sending discovery indications to VOLTHA
145func (s BBSimServer) PoweronONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700146 logger.WithFields(log.Fields{
147 "OnuSn": req.SerialNumber,
148 }).Infof("Received request to poweron ONU")
149
Pragya Aryabd731ec2020-02-11 16:38:17 +0530150 res := &bbsim.Response{}
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700151 olt := devices.GetOLT()
152
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700153 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700154 if err != nil {
155 res.StatusCode = int32(codes.NotFound)
156 res.Message = err.Error()
157 return res, err
158 }
159
Pragya Arya2225f202020-01-29 18:05:01 +0530160 pon, _ := olt.GetPonById(onu.PonPortID)
161 if pon.InternalState.Current() != "enabled" {
162 err := fmt.Errorf("PON port %d not enabled", onu.PonPortID)
163 logger.WithFields(log.Fields{
164 "OnuId": onu.ID,
165 "IntfId": onu.PonPortID,
166 "OnuSn": onu.Sn(),
167 }).Errorf("Cannot poweron ONU: %s", err.Error())
168
169 res.StatusCode = int32(codes.FailedPrecondition)
170 res.Message = err.Error()
171 return res, err
172 }
173
Pragya Aryabd731ec2020-02-11 16:38:17 +0530174 return handlePoweronONU(onu)
175}
176
177// PoweronONUsOnPON simulates ONU power on for all ONUs under specified PON port
178func (s BBSimServer) PoweronONUsOnPON(ctx context.Context, req *bbsim.PONRequest) (*bbsim.Response, error) {
179 logger.WithFields(log.Fields{
180 "IntfId": req.PonPortId,
181 }).Infof("Received request to poweron all ONUs on PON")
182
183 res := &bbsim.Response{}
184 olt := devices.GetOLT()
185
186 pon, _ := olt.GetPonById(req.PonPortId)
187 if pon.InternalState.Current() != "enabled" {
188 err := fmt.Errorf("PON port %d not enabled", pon.ID)
189 logger.WithFields(log.Fields{
190 "IntfId": pon.ID,
191 }).Errorf("Cannot poweron ONUs on PON: %s", err.Error())
192
193 res.StatusCode = int32(codes.FailedPrecondition)
194 res.Message = err.Error()
195 return res, err
196 }
197
198 go func() {
199 for _, onu := range pon.Onus {
200 res, _ = handlePoweronONU(onu)
Pragya Arya2225f202020-01-29 18:05:01 +0530201 }
Pragya Aryabd731ec2020-02-11 16:38:17 +0530202 }()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700203 res.StatusCode = int32(codes.OK)
Pragya Aryabd731ec2020-02-11 16:38:17 +0530204 res.Message = fmt.Sprintf("Request Accepted for power on all ONUs on PON port %d", pon.ID)
205
206 return res, nil
207}
208
209// PoweronAllONUs simulates ONU power on for all ONUs on all PON ports
210func (s BBSimServer) PoweronAllONUs(context.Context, *bbsim.Empty) (*bbsim.Response, error) {
211 logger.Infof("Received request to poweron all ONUs")
212
213 res := &bbsim.Response{}
214 olt := devices.GetOLT()
215
216 go func() {
217 for _, pon := range olt.Pons {
218 if pon.InternalState.Current() == "enabled" {
219 for _, onu := range pon.Onus {
220 res, _ = handlePoweronONU(onu)
221 }
222 }
223 }
224 }()
225 res.StatusCode = int32(codes.OK)
226 res.Message = fmt.Sprintf("Request Accepted for power on all ONUs in OLT %d", olt.ID)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700227
228 return res, nil
229}
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700230
Arjun E K57a7fcb2020-01-30 06:44:45 +0000231func (s BBSimServer) ChangeIgmpState(ctx context.Context, req *bbsim.IgmpRequest) (*bbsim.Response, error) {
Matteo Scandolo618a6582020-09-09 12:21:29 -0700232
Matteo Scandolo8a574812021-05-20 15:18:53 -0700233 // NOTE this API will change the IGMP state for all UNIs on the requested ONU
234 // TODO a new API needs to be created to individually manage the UNIs
Matteo Scandolo618a6582020-09-09 12:21:29 -0700235
Arjun E K57a7fcb2020-01-30 06:44:45 +0000236 res := &bbsim.Response{}
237
238 logger.WithFields(log.Fields{
Onur Kalinagac9f9faca2021-01-21 14:04:34 +0000239 "OnuSn": req.OnuReq.SerialNumber,
240 "subAction": req.SubActionVal,
241 "GroupAddress": req.GroupAddress,
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800242 }).Info("Received igmp request for ONU")
Arjun E K57a7fcb2020-01-30 06:44:45 +0000243
244 olt := devices.GetOLT()
245 onu, err := olt.FindOnuBySn(req.OnuReq.SerialNumber)
246
247 if err != nil {
248 res.StatusCode = int32(codes.NotFound)
249 res.Message = err.Error()
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800250 logger.WithFields(log.Fields{
251 "OnuSn": req.OnuReq.SerialNumber,
252 "subAction": req.SubActionVal,
253 "GroupAddress": req.GroupAddress,
254 }).Warn("ONU not found for sending igmp packet.")
Arjun E K57a7fcb2020-01-30 06:44:45 +0000255 return res, err
256 } else {
257 event := ""
258 switch req.SubActionVal {
259 case bbsim.SubActionTypes_JOIN:
260 event = "igmp_join_start"
261 case bbsim.SubActionTypes_LEAVE:
262 event = "igmp_leave"
Anand S Katti09541352020-01-29 15:54:01 +0530263 case bbsim.SubActionTypes_JOINV3:
264 event = "igmp_join_startv3"
Arjun E K57a7fcb2020-01-30 06:44:45 +0000265 }
266
Matteo Scandolo618a6582020-09-09 12:21:29 -0700267 errors := []string{}
268 startedOn := []string{}
269 success := true
270
Matteo Scandolo8a574812021-05-20 15:18:53 -0700271 for _, u := range onu.UniPorts {
272 uni := u.(*devices.UniPort)
273 if !uni.OperState.Is(devices.UniStateUp) {
274 // if the UNI is disabled, ignore it
275 continue
276 }
277 for _, s := range uni.Services {
278 service := s.(*devices.Service)
279 serviceKey := fmt.Sprintf("uni[%d]%s", uni.ID, service.Name)
280 if service.NeedsIgmp {
281 if !service.InternalState.Is(devices.ServiceStateInitialized) {
282 logger.WithFields(log.Fields{
283 "OnuId": onu.ID,
284 "UniId": uni.ID,
285 "IntfId": onu.PonPortID,
286 "OnuSn": onu.Sn(),
287 "Service": service.Name,
288 }).Warn("service-not-initialized-skipping-event")
289 continue
290 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700291 logger.WithFields(log.Fields{
292 "OnuId": onu.ID,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700293 "UniId": uni.ID,
Matteo Scandolo618a6582020-09-09 12:21:29 -0700294 "IntfId": onu.PonPortID,
295 "OnuSn": onu.Sn(),
296 "Service": service.Name,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700297 "Uni": uni.ID,
298 }).Debugf("Sending %s event on Service %s", event, service.Name)
299
300 if err := service.IGMPState.Event(event, types.IgmpMessage{GroupAddress: req.GroupAddress}); err != nil {
301 logger.WithFields(log.Fields{
302 "OnuId": onu.ID,
303 "UniId": uni.ID,
304 "IntfId": onu.PonPortID,
305 "OnuSn": onu.Sn(),
306 "Service": service.Name,
307 }).Errorf("IGMP request failed: %s", err.Error())
308 errors = append(errors, fmt.Sprintf("%s: %s", serviceKey, err.Error()))
309 success = false
310 }
311 startedOn = append(startedOn, serviceKey)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700312 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700313 }
314 }
315
316 if success {
317 res.StatusCode = int32(codes.OK)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800318 if len(startedOn) > 0 {
319 res.Message = fmt.Sprintf("IGMP %s sent on Services %s for ONU %s.",
320 event, fmt.Sprintf("%v", startedOn), onu.Sn())
321 } else {
322 res.Message = "No service requires IGMP"
323 }
324 logger.WithFields(log.Fields{
325 "OnuSn": req.OnuReq.SerialNumber,
326 "subAction": req.SubActionVal,
327 "GroupAddress": req.GroupAddress,
328 "Message": res.Message,
329 }).Info("Processed IGMP request for ONU")
Matteo Scandolo618a6582020-09-09 12:21:29 -0700330 } else {
Arjun E K57a7fcb2020-01-30 06:44:45 +0000331 res.StatusCode = int32(codes.FailedPrecondition)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700332 res.Message = fmt.Sprintf("%v", errors)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800333 logger.WithFields(log.Fields{
334 "OnuSn": req.OnuReq.SerialNumber,
335 "subAction": req.SubActionVal,
336 "GroupAddress": req.GroupAddress,
337 "Message": res.Message,
338 }).Error("Error while processing IGMP request for ONU")
Arjun E K57a7fcb2020-01-30 06:44:45 +0000339 }
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800340
Arjun E K57a7fcb2020-01-30 06:44:45 +0000341 }
342
343 return res, nil
344}
345
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700346func (s BBSimServer) RestartEapol(ctx context.Context, req *bbsim.UNIRequest) (*bbsim.Response, error) {
347 // NOTE this API will change the EAPOL state for all UNIs on the requested ONU if no UNI is specified
348 // Otherwise, it will change the EAPOL state for only the specified UNI on the ONU
Matteo Scandolo8a574812021-05-20 15:18:53 -0700349
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700350 res := &bbsim.Response{}
351
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700352 if req.UniID == "" {
353 logger.WithFields(log.Fields{
354 "OnuSn": req.OnuSerialNumber,
355 }).Infof("Received request to restart authentication for all UNIs on the ONU")
356 } else {
357 logger.WithFields(log.Fields{
358 "OnuSn": req.OnuSerialNumber,
359 "UniId": req.UniID,
360 }).Infof("Received request to restart authentication on UNI")
361 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700362
363 olt := devices.GetOLT()
364
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700365 onu, err := olt.FindOnuBySn(req.OnuSerialNumber)
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700366
367 if err != nil {
368 res.StatusCode = int32(codes.NotFound)
369 res.Message = err.Error()
370 return res, err
371 }
372
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700373 errors := []string{}
Matteo Scandolo618a6582020-09-09 12:21:29 -0700374 startedOn := []string{}
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700375 success := true
376
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700377 uniIDint, err := strconv.Atoi(req.UniID)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700378 for _, u := range onu.UniPorts {
379 uni := u.(*devices.UniPort)
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700380 //if a specific uni is specified, only restart it
381 if err == nil && req.UniID != "" && uni.ID != uint32(uniIDint) {
382 continue
383 }
Matteo Scandolo8a574812021-05-20 15:18:53 -0700384 if !uni.OperState.Is(devices.UniStateUp) {
385 // if the UNI is disabled, ignore it
386 continue
387 }
388 for _, s := range uni.Services {
389 service := s.(*devices.Service)
390 serviceKey := fmt.Sprintf("uni[%d]%s", uni.ID, service.Name)
391 if service.NeedsEapol {
392 if !service.InternalState.Is(devices.ServiceStateInitialized) {
393 logger.WithFields(log.Fields{
394 "OnuId": onu.ID,
395 "UniId": uni.ID,
396 "IntfId": onu.PonPortID,
397 "OnuSn": onu.Sn(),
398 "Service": service.Name,
399 }).Warn("service-not-initialized-skipping-event")
400 continue
401 }
402 if err := service.EapolState.Event("start_auth"); err != nil {
403 logger.WithFields(log.Fields{
404 "OnuId": onu.ID,
405 "IntfId": onu.PonPortID,
406 "OnuSn": onu.Sn(),
407 "UniId": uni.ID,
408 "Service": service.Name,
409 }).Errorf("Cannot restart authenticaton for Service: %s", err.Error())
410 errors = append(errors, fmt.Sprintf("%s: %s", serviceKey, err.Error()))
411 success = false
412 }
413 startedOn = append(startedOn, serviceKey)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700414 }
415 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700416 }
417
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700418 if success {
419 res.StatusCode = int32(codes.OK)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800420 if len(startedOn) > 0 {
421 res.Message = fmt.Sprintf("Authentication restarted on Services %s for ONU %s.",
422 fmt.Sprintf("%v", startedOn), onu.Sn())
423 } else {
424 res.Message = "No service requires EAPOL"
425 }
426
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700427 if req.UniID == "" {
428 logger.WithFields(log.Fields{
429 "OnuSn": req.OnuSerialNumber,
430 "Message": res.Message,
431 }).Info("Processed EAPOL restart request for all UNIs on the ONU")
432 } else {
433 logger.WithFields(log.Fields{
434 "OnuSn": req.OnuSerialNumber,
435 "Message": res.Message,
436 "UniId": req.UniID,
437 }).Info("Processed EAPOL restart request on UNI")
438 }
439
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700440 } else {
441 res.StatusCode = int32(codes.FailedPrecondition)
442 res.Message = fmt.Sprintf("%v", errors)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800443 logger.WithFields(log.Fields{
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700444 "OnuSn": req.OnuSerialNumber,
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800445 "Message": res.Message,
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700446 }).Error("Error while processing EAPOL restart request for ONU")
447
448 if req.UniID == "" {
449 logger.WithFields(log.Fields{
450 "OnuSn": req.OnuSerialNumber,
451 "Message": res.Message,
452 }).Error("Error while processing EAPOL restart request for all UNIs on the ONU")
453 } else {
454 logger.WithFields(log.Fields{
455 "OnuSn": req.OnuSerialNumber,
456 "Message": res.Message,
457 "UniId": req.UniID,
458 }).Error("Error while processing EAPOL restart request on UNI")
459 }
460
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700461 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700462
463 return res, nil
464}
465
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700466func (s BBSimServer) RestartDhcp(ctx context.Context, req *bbsim.UNIRequest) (*bbsim.Response, error) {
467 // NOTE this API will change the DHCP state for all UNIs on the requested ONU if no UNI is specified
468 // Otherwise, it will change the DHCP state for only the specified UNI on the ONU
Matteo Scandolo8a574812021-05-20 15:18:53 -0700469
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700470 res := &bbsim.Response{}
471
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700472 if req.UniID == "" {
473 logger.WithFields(log.Fields{
474 "OnuSn": req.OnuSerialNumber,
475 }).Infof("Received request to restart authentication for all UNIs on the ONU")
476 } else {
477 logger.WithFields(log.Fields{
478 "OnuSn": req.OnuSerialNumber,
479 "UniId": req.UniID,
480 }).Infof("Received request to restart authentication on UNI")
481 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700482
483 olt := devices.GetOLT()
484
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700485 onu, err := olt.FindOnuBySn(req.OnuSerialNumber)
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700486
487 if err != nil {
488 res.StatusCode = int32(codes.NotFound)
489 res.Message = err.Error()
490 return res, err
491 }
492
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700493 errors := []string{}
Matteo Scandolo618a6582020-09-09 12:21:29 -0700494 startedOn := []string{}
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700495 success := true
496
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700497 uniIDint, err := strconv.Atoi(req.UniID)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700498 for _, u := range onu.UniPorts {
499 uni := u.(*devices.UniPort)
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700500 //if a specific uni is specified, only restart it
501 if err == nil && req.UniID != "" && uni.ID != uint32(uniIDint) {
502 continue
503 }
Matteo Scandolo8a574812021-05-20 15:18:53 -0700504 if !uni.OperState.Is(devices.UniStateUp) {
505 // if the UNI is disabled, ignore it
506 continue
507 }
508 for _, s := range uni.Services {
509 service := s.(*devices.Service)
510 serviceKey := fmt.Sprintf("uni[%d]%s", uni.ID, service.Name)
511 if service.NeedsDhcp {
Matteo Scandolo8a574812021-05-20 15:18:53 -0700512 if err := service.DHCPState.Event("start_dhcp"); err != nil {
513 logger.WithFields(log.Fields{
514 "OnuId": onu.ID,
515 "IntfId": onu.PonPortID,
516 "OnuSn": onu.Sn(),
517 "UniId": uni.ID,
518 "Service": service.Name,
519 }).Errorf("Cannot restart DHCP for Service: %s", err.Error())
520 errors = append(errors, fmt.Sprintf("%s: %s", serviceKey, err.Error()))
521 success = false
522 }
523 startedOn = append(startedOn, serviceKey)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700524 }
525 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700526 }
527
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700528 if success {
529 res.StatusCode = int32(codes.OK)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800530 if len(startedOn) > 0 {
531 res.Message = fmt.Sprintf("DHCP restarted on Services %s for ONU %s.",
532 fmt.Sprintf("%v", startedOn), onu.Sn())
533
534 } else {
535 res.Message = "No service requires DHCP"
536 }
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700537
538 if req.UniID == "" {
539 logger.WithFields(log.Fields{
540 "OnuSn": req.OnuSerialNumber,
541 "Message": res.Message,
542 }).Info("Processed DHCP restart request for all UNIs on the ONU")
543 } else {
544 logger.WithFields(log.Fields{
545 "OnuSn": req.OnuSerialNumber,
546 "Message": res.Message,
547 "UniId": req.UniID,
548 }).Info("Processed DHCP restart request on UNI")
549 }
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700550 } else {
551 res.StatusCode = int32(codes.FailedPrecondition)
552 res.Message = fmt.Sprintf("%v", errors)
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700553
554 if req.UniID == "" {
555 logger.WithFields(log.Fields{
556 "OnuSn": req.OnuSerialNumber,
557 "Message": res.Message,
558 }).Error("Error while processing DHCP restart request for all UNIs on the ONU")
559 } else {
560 logger.WithFields(log.Fields{
561 "OnuSn": req.OnuSerialNumber,
562 "Message": res.Message,
563 "UniId": req.UniID,
564 }).Error("Error while processing DHCP restart request on UNI")
565 }
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700566 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700567
568 return res, nil
569}
Anand S Katti09541352020-01-29 15:54:01 +0530570
Pragya Arya8bdb4532020-03-02 17:08:09 +0530571// GetFlows for OLT/ONUs
572func (s BBSimServer) GetFlows(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Flows, error) {
573 logger.WithFields(log.Fields{
574 "OnuSn": req.SerialNumber,
575 }).Info("Received GetFlows request")
576
577 olt := devices.GetOLT()
578 res := &bbsim.Flows{}
579
580 if req.SerialNumber == "" {
Andrea Campanellacc9b1662022-01-26 17:47:48 +0100581 olt.Flows.Range(func(flowKey, flow interface{}) bool {
Andrea Campanellabe8e12f2020-12-14 18:43:41 +0100582 flowObj := flow.(openolt.Flow)
583 res.Flows = append(res.Flows, &flowObj)
584 return true
585 })
586 res.FlowCount = uint32(len(res.Flows))
Pragya Arya8bdb4532020-03-02 17:08:09 +0530587 } else {
588 onu, err := olt.FindOnuBySn(req.SerialNumber)
589 if err != nil {
590 logger.WithFields(log.Fields{
591 "OnuSn": req.SerialNumber,
592 }).Error("Can't get ONU in GetFlows request")
593 return nil, err
594 }
Andrea Campanellacc9b1662022-01-26 17:47:48 +0100595 for _, flowKey := range onu.Flows {
596 flow, _ := olt.Flows.Load(flowKey)
Andrea Campanellabe8e12f2020-12-14 18:43:41 +0100597 flowObj := flow.(openolt.Flow)
598 res.Flows = append(res.Flows, &flowObj)
Pragya Arya8bdb4532020-03-02 17:08:09 +0530599 }
Andrea Campanellacc9b1662022-01-26 17:47:48 +0100600 res.FlowCount = uint32(len(onu.Flows))
Pragya Arya8bdb4532020-03-02 17:08:09 +0530601 }
602 return res, nil
603}
604
Anand S Katti09541352020-01-29 15:54:01 +0530605func (s BBSimServer) GetOnuTrafficSchedulers(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONUTrafficSchedulers, error) {
606 olt := devices.GetOLT()
607 ts := bbsim.ONUTrafficSchedulers{}
608
609 onu, err := olt.FindOnuBySn(req.SerialNumber)
610 if err != nil {
611 return &ts, err
612 }
613
614 if onu.TrafficSchedulers != nil {
615 ts.TraffSchedulers = onu.TrafficSchedulers
616 return &ts, nil
617 } else {
618 ts.TraffSchedulers = nil
619 return &ts, nil
620 }
621}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530622
623func handlePoweronONU(onu *devices.Onu) (*bbsim.Response, error) {
624 res := &bbsim.Response{}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530625
Matteo Scandolof9d43412021-01-12 11:11:34 -0800626 if err := onu.HandlePowerOnONU(); err != nil {
Pragya Aryabd731ec2020-02-11 16:38:17 +0530627 res.StatusCode = int32(codes.FailedPrecondition)
628 res.Message = err.Error()
629 return res, err
630 }
631
Pragya Aryabd731ec2020-02-11 16:38:17 +0530632 res.StatusCode = int32(codes.OK)
633 res.Message = fmt.Sprintf("ONU %s successfully powered on.", onu.Sn())
634
635 return res, nil
636}
637
638func handleShutdownONU(onu *devices.Onu) (*bbsim.Response, error) {
639 res := &bbsim.Response{}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530640
Matteo Scandolof9d43412021-01-12 11:11:34 -0800641 if err := onu.HandleShutdownONU(); err != nil {
Pragya Aryabd731ec2020-02-11 16:38:17 +0530642 res.StatusCode = int32(codes.FailedPrecondition)
643 res.Message = err.Error()
644 return res, err
645 }
646
647 res.StatusCode = int32(codes.OK)
648 res.Message = fmt.Sprintf("ONU %s successfully shut down.", onu.Sn())
649
650 return res, nil
651}
Nitin Subramanianb0a333a2021-07-08 15:01:41 -0700652
653func (s BBSimServer) GetUnis(ctx context.Context, req *bbsim.Empty) (*bbsim.UNIs, error) {
654 onus, err := s.GetONUs(ctx, req)
655
656 if err != nil {
657 return nil, err
658 }
659 unis := []*bbsim.UNI{}
660 for _, onu := range onus.Items {
661 unis = append(unis, onu.Unis...)
662 }
663 unis_ret := bbsim.UNIs{
664 Items: unis,
665 }
666 return &unis_ret, nil
667}
Elia Battistonfe017662022-01-05 11:43:16 +0100668
669// Invalidate the MDS counter of the ONU
670func (s BBSimServer) InvalidateMds(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
671 logger.WithFields(log.Fields{
672 "OnuSn": req.SerialNumber,
673 }).Infof("Received request to invalidate the MDS counter of the ONU")
674
675 res := &bbsim.Response{}
676 olt := devices.GetOLT()
677
678 onu, err := olt.FindOnuBySn(req.SerialNumber)
679 if err != nil {
680 res.StatusCode = int32(codes.NotFound)
681 res.Message = err.Error()
682 return res, err
683 }
684
685 previous := onu.MibDataSync
686 onu.InvalidateMibDataSync()
687
688 res.StatusCode = int32(codes.OK)
689 res.Message = fmt.Sprintf("MDS counter of ONU %s was %d, set to %d).", onu.Sn(), previous, onu.MibDataSync)
690
691 return res, nil
692}