blob: 9bf481e83e199e53e93d520a3062e19c4b95fec8 [file] [log] [blame]
Matteo Scandolo10f965c2019-09-24 10:40:46 -07001/*
Joey Armstrong2c039362024-02-04 18:51:52 -05002 * Copyright 2018-2024 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
David K. Bainbridgec415efe2021-08-19 13:05:21 +000024 "github.com/opencord/voltha-protos/v5/go/openolt"
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"
Baris Ertas0ce2f7c2023-04-11 11:44:24 +030028 "github.com/opencord/bbsim/internal/bbsim/responders/igmp"
Matteo Scandolo10f965c2019-09-24 10:40:46 -070029 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
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{
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300238 "OnuSn": req.OnuSerialNumber,
239 "UniId": req.UniID,
Onur Kalinagac9f9faca2021-01-21 14:04:34 +0000240 "subAction": req.SubActionVal,
241 "GroupAddress": req.GroupAddress,
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300242 "VLAN": req.VLAN,
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800243 }).Info("Received igmp request for ONU")
Arjun E K57a7fcb2020-01-30 06:44:45 +0000244
245 olt := devices.GetOLT()
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300246 onu, err := olt.FindOnuBySn(req.OnuSerialNumber)
Arjun E K57a7fcb2020-01-30 06:44:45 +0000247 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{
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300251 "OnuSn": req.OnuSerialNumber,
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800252 "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
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300267 if int(req.UniID) >= len(onu.UniPorts) {
268 res.StatusCode = int32(codes.InvalidArgument)
269 err := fmt.Errorf("invalid uni no given")
270 return res, err
271 }
272 if req.VLAN > 0xFFF || req.VLAN < 0 {
273 res.StatusCode = int32(codes.InvalidArgument)
274 err := fmt.Errorf("invalid vlan given")
275 return res, err
276 }
277 uni := onu.UniPorts[req.UniID].(*devices.UniPort)
278 if !uni.OperState.Is(devices.UniStateUp) {
279 // if the UNI is disabled, ignore it
280 err := fmt.Errorf("given uni is currently disabled")
281 return res, err
282 }
283 for _, s := range uni.Services {
284 service := s.(*devices.Service)
285 if service.NeedsIgmp {
286 if !service.InternalState.Is(devices.ServiceStateInitialized) {
Matteo Scandolo618a6582020-09-09 12:21:29 -0700287 logger.WithFields(log.Fields{
288 "OnuId": onu.ID,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700289 "UniId": uni.ID,
Matteo Scandolo618a6582020-09-09 12:21:29 -0700290 "IntfId": onu.PonPortID,
291 "OnuSn": onu.Sn(),
292 "Service": service.Name,
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300293 }).Trace("service-not-initialized-skipping-event")
294 continue
295 }
Matteo Scandolo8a574812021-05-20 15:18:53 -0700296
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300297 ctag := service.CTag
298 if req.VLAN != 0 {
299 ctag = int(req.VLAN)
300 }
301
302 logger.WithFields(log.Fields{
303 "OnuId": onu.ID,
304 "UniId": uni.ID,
305 "IntfId": onu.PonPortID,
306 "OnuSn": onu.Sn(),
307 "Service": service.Name,
308 "Uni": uni.ID,
309 "Vlan": ctag,
310 }).Debugf("Sending %s event on Service %s", event, service.Name)
311
312 switch req.SubActionVal {
313 case bbsim.SubActionTypes_JOIN:
Baris Ertas53ab13c2023-05-25 16:31:48 +0300314 service.AddGroupAddress(req.GroupAddress, ctag)
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300315 go func() {
316 _ = igmp.SendIGMPMembershipReportV2(service.UniPort.Onu.PonPortID, service.UniPort.Onu.ID, service.UniPort.Onu.Sn(),
317 service.UniPort.PortNo, service.UniPort.ID, service.GemPort, service.HwAddress, ctag,
318 service.UsPonCTagPriority, service.Stream, req.GroupAddress)
319 }()
320 case bbsim.SubActionTypes_LEAVE:
Baris Ertas53ab13c2023-05-25 16:31:48 +0300321 service.RemoveGroupAddress(req.GroupAddress)
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300322 go func() {
323 _ = igmp.SendIGMPLeaveGroupV2(service.UniPort.Onu.PonPortID, service.UniPort.Onu.ID, service.UniPort.Onu.Sn(),
324 service.UniPort.PortNo, service.UniPort.ID, service.GemPort, service.HwAddress, ctag,
325 service.UsPonCTagPriority, service.Stream, req.GroupAddress)
326 }()
327 case bbsim.SubActionTypes_JOINV3:
Baris Ertas53ab13c2023-05-25 16:31:48 +0300328 service.AddGroupAddress(req.GroupAddress, ctag)
Baris Ertas0ce2f7c2023-04-11 11:44:24 +0300329 go func() {
330 _ = igmp.SendIGMPMembershipReportV3(service.UniPort.Onu.PonPortID, service.UniPort.Onu.ID, service.UniPort.Onu.Sn(),
331 service.UniPort.PortNo, service.UniPort.ID, service.GemPort, service.HwAddress, ctag,
332 service.UsPonCTagPriority, service.Stream, req.GroupAddress)
333 }()
Matteo Scandolo618a6582020-09-09 12:21:29 -0700334 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700335 }
336 }
Arjun E K57a7fcb2020-01-30 06:44:45 +0000337 }
Arjun E K57a7fcb2020-01-30 06:44:45 +0000338 return res, nil
339}
340
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700341func (s BBSimServer) RestartEapol(ctx context.Context, req *bbsim.UNIRequest) (*bbsim.Response, error) {
342 // NOTE this API will change the EAPOL state for all UNIs on the requested ONU if no UNI is specified
343 // Otherwise, it will change the EAPOL state for only the specified UNI on the ONU
Matteo Scandolo8a574812021-05-20 15:18:53 -0700344
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700345 res := &bbsim.Response{}
346
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700347 if req.UniID == "" {
348 logger.WithFields(log.Fields{
349 "OnuSn": req.OnuSerialNumber,
350 }).Infof("Received request to restart authentication for all UNIs on the ONU")
351 } else {
352 logger.WithFields(log.Fields{
353 "OnuSn": req.OnuSerialNumber,
354 "UniId": req.UniID,
355 }).Infof("Received request to restart authentication on UNI")
356 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700357
358 olt := devices.GetOLT()
359
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700360 onu, err := olt.FindOnuBySn(req.OnuSerialNumber)
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700361
362 if err != nil {
363 res.StatusCode = int32(codes.NotFound)
364 res.Message = err.Error()
365 return res, err
366 }
367
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700368 errors := []string{}
Matteo Scandolo618a6582020-09-09 12:21:29 -0700369 startedOn := []string{}
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700370 success := true
371
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700372 uniIDint, err := strconv.Atoi(req.UniID)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700373 for _, u := range onu.UniPorts {
374 uni := u.(*devices.UniPort)
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700375 //if a specific uni is specified, only restart it
376 if err == nil && req.UniID != "" && uni.ID != uint32(uniIDint) {
377 continue
378 }
Matteo Scandolo8a574812021-05-20 15:18:53 -0700379 if !uni.OperState.Is(devices.UniStateUp) {
380 // if the UNI is disabled, ignore it
381 continue
382 }
383 for _, s := range uni.Services {
384 service := s.(*devices.Service)
385 serviceKey := fmt.Sprintf("uni[%d]%s", uni.ID, service.Name)
386 if service.NeedsEapol {
387 if !service.InternalState.Is(devices.ServiceStateInitialized) {
388 logger.WithFields(log.Fields{
389 "OnuId": onu.ID,
390 "UniId": uni.ID,
391 "IntfId": onu.PonPortID,
392 "OnuSn": onu.Sn(),
393 "Service": service.Name,
394 }).Warn("service-not-initialized-skipping-event")
395 continue
396 }
397 if err := service.EapolState.Event("start_auth"); err != nil {
398 logger.WithFields(log.Fields{
399 "OnuId": onu.ID,
400 "IntfId": onu.PonPortID,
401 "OnuSn": onu.Sn(),
402 "UniId": uni.ID,
403 "Service": service.Name,
404 }).Errorf("Cannot restart authenticaton for Service: %s", err.Error())
405 errors = append(errors, fmt.Sprintf("%s: %s", serviceKey, err.Error()))
406 success = false
407 }
408 startedOn = append(startedOn, serviceKey)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700409 }
410 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700411 }
412
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700413 if success {
414 res.StatusCode = int32(codes.OK)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800415 if len(startedOn) > 0 {
416 res.Message = fmt.Sprintf("Authentication restarted on Services %s for ONU %s.",
417 fmt.Sprintf("%v", startedOn), onu.Sn())
418 } else {
419 res.Message = "No service requires EAPOL"
420 }
421
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700422 if req.UniID == "" {
423 logger.WithFields(log.Fields{
424 "OnuSn": req.OnuSerialNumber,
425 "Message": res.Message,
426 }).Info("Processed EAPOL restart request for all UNIs on the ONU")
427 } else {
428 logger.WithFields(log.Fields{
429 "OnuSn": req.OnuSerialNumber,
430 "Message": res.Message,
431 "UniId": req.UniID,
432 }).Info("Processed EAPOL restart request on UNI")
433 }
434
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700435 } else {
436 res.StatusCode = int32(codes.FailedPrecondition)
437 res.Message = fmt.Sprintf("%v", errors)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800438 logger.WithFields(log.Fields{
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700439 "OnuSn": req.OnuSerialNumber,
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800440 "Message": res.Message,
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700441 }).Error("Error while processing EAPOL restart request for ONU")
442
443 if req.UniID == "" {
444 logger.WithFields(log.Fields{
445 "OnuSn": req.OnuSerialNumber,
446 "Message": res.Message,
447 }).Error("Error while processing EAPOL restart request for all UNIs on the ONU")
448 } else {
449 logger.WithFields(log.Fields{
450 "OnuSn": req.OnuSerialNumber,
451 "Message": res.Message,
452 "UniId": req.UniID,
453 }).Error("Error while processing EAPOL restart request on UNI")
454 }
455
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700456 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700457
458 return res, nil
459}
460
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700461func (s BBSimServer) RestartDhcp(ctx context.Context, req *bbsim.UNIRequest) (*bbsim.Response, error) {
462 // NOTE this API will change the DHCP state for all UNIs on the requested ONU if no UNI is specified
463 // Otherwise, it will change the DHCP state for only the specified UNI on the ONU
Matteo Scandolo8a574812021-05-20 15:18:53 -0700464
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700465 res := &bbsim.Response{}
466
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700467 if req.UniID == "" {
468 logger.WithFields(log.Fields{
469 "OnuSn": req.OnuSerialNumber,
470 }).Infof("Received request to restart authentication for all UNIs on the ONU")
471 } else {
472 logger.WithFields(log.Fields{
473 "OnuSn": req.OnuSerialNumber,
474 "UniId": req.UniID,
475 }).Infof("Received request to restart authentication on UNI")
476 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700477
478 olt := devices.GetOLT()
479
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700480 onu, err := olt.FindOnuBySn(req.OnuSerialNumber)
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700481
482 if err != nil {
483 res.StatusCode = int32(codes.NotFound)
484 res.Message = err.Error()
485 return res, err
486 }
487
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700488 errors := []string{}
Matteo Scandolo618a6582020-09-09 12:21:29 -0700489 startedOn := []string{}
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700490 success := true
491
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700492 uniIDint, err := strconv.Atoi(req.UniID)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700493 for _, u := range onu.UniPorts {
494 uni := u.(*devices.UniPort)
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700495 //if a specific uni is specified, only restart it
496 if err == nil && req.UniID != "" && uni.ID != uint32(uniIDint) {
497 continue
498 }
Matteo Scandolo8a574812021-05-20 15:18:53 -0700499 if !uni.OperState.Is(devices.UniStateUp) {
500 // if the UNI is disabled, ignore it
501 continue
502 }
503 for _, s := range uni.Services {
504 service := s.(*devices.Service)
505 serviceKey := fmt.Sprintf("uni[%d]%s", uni.ID, service.Name)
506 if service.NeedsDhcp {
Matteo Scandolo8a574812021-05-20 15:18:53 -0700507 if err := service.DHCPState.Event("start_dhcp"); err != nil {
508 logger.WithFields(log.Fields{
509 "OnuId": onu.ID,
510 "IntfId": onu.PonPortID,
511 "OnuSn": onu.Sn(),
512 "UniId": uni.ID,
513 "Service": service.Name,
514 }).Errorf("Cannot restart DHCP for Service: %s", err.Error())
515 errors = append(errors, fmt.Sprintf("%s: %s", serviceKey, err.Error()))
516 success = false
517 }
518 startedOn = append(startedOn, serviceKey)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700519 }
520 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700521 }
522
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700523 if success {
524 res.StatusCode = int32(codes.OK)
Matteo Scandoloc08a6082021-02-05 11:12:01 -0800525 if len(startedOn) > 0 {
526 res.Message = fmt.Sprintf("DHCP restarted on Services %s for ONU %s.",
527 fmt.Sprintf("%v", startedOn), onu.Sn())
528
529 } else {
530 res.Message = "No service requires DHCP"
531 }
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700532
533 if req.UniID == "" {
534 logger.WithFields(log.Fields{
535 "OnuSn": req.OnuSerialNumber,
536 "Message": res.Message,
537 }).Info("Processed DHCP restart request for all UNIs on the ONU")
538 } else {
539 logger.WithFields(log.Fields{
540 "OnuSn": req.OnuSerialNumber,
541 "Message": res.Message,
542 "UniId": req.UniID,
543 }).Info("Processed DHCP restart request on UNI")
544 }
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700545 } else {
546 res.StatusCode = int32(codes.FailedPrecondition)
547 res.Message = fmt.Sprintf("%v", errors)
Nitin Subramanian150f1bb2021-08-02 12:04:05 -0700548
549 if req.UniID == "" {
550 logger.WithFields(log.Fields{
551 "OnuSn": req.OnuSerialNumber,
552 "Message": res.Message,
553 }).Error("Error while processing DHCP restart request for all UNIs on the ONU")
554 } else {
555 logger.WithFields(log.Fields{
556 "OnuSn": req.OnuSerialNumber,
557 "Message": res.Message,
558 "UniId": req.UniID,
559 }).Error("Error while processing DHCP restart request on UNI")
560 }
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700561 }
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700562
563 return res, nil
564}
Anand S Katti09541352020-01-29 15:54:01 +0530565
Pragya Arya8bdb4532020-03-02 17:08:09 +0530566// GetFlows for OLT/ONUs
567func (s BBSimServer) GetFlows(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Flows, error) {
568 logger.WithFields(log.Fields{
569 "OnuSn": req.SerialNumber,
570 }).Info("Received GetFlows request")
571
572 olt := devices.GetOLT()
573 res := &bbsim.Flows{}
574
575 if req.SerialNumber == "" {
Andrea Campanellacc9b1662022-01-26 17:47:48 +0100576 olt.Flows.Range(func(flowKey, flow interface{}) bool {
Andrea Campanellabe8e12f2020-12-14 18:43:41 +0100577 flowObj := flow.(openolt.Flow)
578 res.Flows = append(res.Flows, &flowObj)
579 return true
580 })
581 res.FlowCount = uint32(len(res.Flows))
Pragya Arya8bdb4532020-03-02 17:08:09 +0530582 } else {
583 onu, err := olt.FindOnuBySn(req.SerialNumber)
584 if err != nil {
585 logger.WithFields(log.Fields{
586 "OnuSn": req.SerialNumber,
587 }).Error("Can't get ONU in GetFlows request")
588 return nil, err
589 }
Andrea Campanellacc9b1662022-01-26 17:47:48 +0100590 for _, flowKey := range onu.Flows {
591 flow, _ := olt.Flows.Load(flowKey)
Andrea Campanellabe8e12f2020-12-14 18:43:41 +0100592 flowObj := flow.(openolt.Flow)
593 res.Flows = append(res.Flows, &flowObj)
Pragya Arya8bdb4532020-03-02 17:08:09 +0530594 }
Andrea Campanellacc9b1662022-01-26 17:47:48 +0100595 res.FlowCount = uint32(len(onu.Flows))
Pragya Arya8bdb4532020-03-02 17:08:09 +0530596 }
597 return res, nil
598}
599
Anand S Katti09541352020-01-29 15:54:01 +0530600func (s BBSimServer) GetOnuTrafficSchedulers(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONUTrafficSchedulers, error) {
601 olt := devices.GetOLT()
602 ts := bbsim.ONUTrafficSchedulers{}
603
604 onu, err := olt.FindOnuBySn(req.SerialNumber)
605 if err != nil {
606 return &ts, err
607 }
608
609 if onu.TrafficSchedulers != nil {
610 ts.TraffSchedulers = onu.TrafficSchedulers
611 return &ts, nil
612 } else {
613 ts.TraffSchedulers = nil
614 return &ts, nil
615 }
616}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530617
618func handlePoweronONU(onu *devices.Onu) (*bbsim.Response, error) {
619 res := &bbsim.Response{}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530620
Matteo Scandolof9d43412021-01-12 11:11:34 -0800621 if err := onu.HandlePowerOnONU(); err != nil {
Pragya Aryabd731ec2020-02-11 16:38:17 +0530622 res.StatusCode = int32(codes.FailedPrecondition)
623 res.Message = err.Error()
624 return res, err
625 }
626
Pragya Aryabd731ec2020-02-11 16:38:17 +0530627 res.StatusCode = int32(codes.OK)
628 res.Message = fmt.Sprintf("ONU %s successfully powered on.", onu.Sn())
629
630 return res, nil
631}
632
633func handleShutdownONU(onu *devices.Onu) (*bbsim.Response, error) {
634 res := &bbsim.Response{}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530635
Matteo Scandolof9d43412021-01-12 11:11:34 -0800636 if err := onu.HandleShutdownONU(); err != nil {
Pragya Aryabd731ec2020-02-11 16:38:17 +0530637 res.StatusCode = int32(codes.FailedPrecondition)
638 res.Message = err.Error()
639 return res, err
640 }
641
642 res.StatusCode = int32(codes.OK)
643 res.Message = fmt.Sprintf("ONU %s successfully shut down.", onu.Sn())
644
645 return res, nil
646}
Nitin Subramanianb0a333a2021-07-08 15:01:41 -0700647
648func (s BBSimServer) GetUnis(ctx context.Context, req *bbsim.Empty) (*bbsim.UNIs, error) {
649 onus, err := s.GetONUs(ctx, req)
650
651 if err != nil {
652 return nil, err
653 }
654 unis := []*bbsim.UNI{}
655 for _, onu := range onus.Items {
656 unis = append(unis, onu.Unis...)
657 }
658 unis_ret := bbsim.UNIs{
659 Items: unis,
660 }
661 return &unis_ret, nil
662}
Elia Battistonfe017662022-01-05 11:43:16 +0100663
664// Invalidate the MDS counter of the ONU
665func (s BBSimServer) InvalidateMds(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
666 logger.WithFields(log.Fields{
667 "OnuSn": req.SerialNumber,
668 }).Infof("Received request to invalidate the MDS counter of the ONU")
669
670 res := &bbsim.Response{}
671 olt := devices.GetOLT()
672
673 onu, err := olt.FindOnuBySn(req.SerialNumber)
674 if err != nil {
675 res.StatusCode = int32(codes.NotFound)
676 res.Message = err.Error()
677 return res, err
678 }
679
680 previous := onu.MibDataSync
681 onu.InvalidateMibDataSync()
682
683 res.StatusCode = int32(codes.OK)
684 res.Message = fmt.Sprintf("MDS counter of ONU %s was %d, set to %d).", onu.Sn(), previous, onu.MibDataSync)
685
686 return res, nil
687}