blob: 7ec4ab3ecf20ef7235626a45f839ec41cf89a77e [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"
Pragya Arya1cbefa42020-01-13 12:15:29 +053022
Matteo Scandolo10f965c2019-09-24 10:40:46 -070023 "github.com/opencord/bbsim/api/bbsim"
24 "github.com/opencord/bbsim/internal/bbsim/devices"
25 log "github.com/sirupsen/logrus"
26 "google.golang.org/grpc/codes"
27)
28
29func (s BBSimServer) GetONUs(ctx context.Context, req *bbsim.Empty) (*bbsim.ONUs, error) {
30 olt := devices.GetOLT()
31 onus := bbsim.ONUs{
32 Items: []*bbsim.ONU{},
33 }
34
35 for _, pon := range olt.Pons {
36 for _, o := range pon.Onus {
37 onu := bbsim.ONU{
38 ID: int32(o.ID),
39 SerialNumber: o.Sn(),
40 OperState: o.OperState.Current(),
41 InternalState: o.InternalState.Current(),
42 PonPortID: int32(o.PonPortID),
43 STag: int32(o.STag),
44 CTag: int32(o.CTag),
45 HwAddress: o.HwAddress.String(),
Matteo Scandolo27428702019-10-11 16:21:16 -070046 PortNo: int32(o.PortNo),
Matteo Scandolo10f965c2019-09-24 10:40:46 -070047 }
48 onus.Items = append(onus.Items, &onu)
49 }
50 }
51 return &onus, nil
52}
53
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070054func (s BBSimServer) GetONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONU, error) {
55 olt := devices.GetOLT()
56
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070057 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070058
59 if err != nil {
60 res := bbsim.ONU{}
61 return &res, err
62 }
63
64 res := bbsim.ONU{
65 ID: int32(onu.ID),
66 SerialNumber: onu.Sn(),
67 OperState: onu.OperState.Current(),
68 InternalState: onu.InternalState.Current(),
69 PonPortID: int32(onu.PonPortID),
70 STag: int32(onu.STag),
71 CTag: int32(onu.CTag),
72 HwAddress: onu.HwAddress.String(),
Matteo Scandolo27428702019-10-11 16:21:16 -070073 PortNo: int32(onu.PortNo),
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070074 }
75 return &res, nil
76}
77
Matteo Scandolo10f965c2019-09-24 10:40:46 -070078func (s BBSimServer) ShutdownONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
79 // NOTE this method is now sendying a Dying Gasp and then disabling the device (operState: down, adminState: up),
80 // is this the only way to do? Should we address other cases?
81 // Investigate what happens when:
82 // - a fiber is pulled
83 // - ONU malfunction
84 // - ONU shutdown
85 res := &bbsim.Response{}
86
87 logger.WithFields(log.Fields{
88 "OnuSn": req.SerialNumber,
89 }).Infof("Received request to shutdown ONU")
90
91 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
95 if err != nil {
96 res.StatusCode = int32(codes.NotFound)
97 res.Message = err.Error()
98 return res, err
99 }
100
101 dyingGasp := devices.Message{
102 Type: devices.DyingGaspIndication,
103 Data: devices.DyingGaspIndicationMessage{
104 OnuID: onu.ID,
105 PonPortID: onu.PonPortID,
106 Status: "on", // TODO do we need a type for Dying Gasp Indication?
107 },
108 }
109
110 onu.Channel <- dyingGasp
111
112 if err := onu.InternalState.Event("disable"); err != nil {
113 logger.WithFields(log.Fields{
114 "OnuId": onu.ID,
115 "IntfId": onu.PonPortID,
116 "OnuSn": onu.Sn(),
117 }).Errorf("Cannot shutdown ONU: %s", err.Error())
118 res.StatusCode = int32(codes.FailedPrecondition)
119 res.Message = err.Error()
120 return res, err
121 }
122
123 res.StatusCode = int32(codes.OK)
124 res.Message = fmt.Sprintf("ONU %s successfully shut down.", onu.Sn())
125
126 return res, nil
127}
128
129func (s BBSimServer) PoweronONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
130 res := &bbsim.Response{}
131
132 logger.WithFields(log.Fields{
133 "OnuSn": req.SerialNumber,
134 }).Infof("Received request to poweron ONU")
135
136 olt := devices.GetOLT()
137
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700138 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700139 if err != nil {
140 res.StatusCode = int32(codes.NotFound)
141 res.Message = err.Error()
142 return res, err
143 }
144
Pragya Arya2225f202020-01-29 18:05:01 +0530145 pon, _ := olt.GetPonById(onu.PonPortID)
146 if pon.InternalState.Current() != "enabled" {
147 err := fmt.Errorf("PON port %d not enabled", onu.PonPortID)
148 logger.WithFields(log.Fields{
149 "OnuId": onu.ID,
150 "IntfId": onu.PonPortID,
151 "OnuSn": onu.Sn(),
152 }).Errorf("Cannot poweron ONU: %s", err.Error())
153
154 res.StatusCode = int32(codes.FailedPrecondition)
155 res.Message = err.Error()
156 return res, err
157 }
158
159 if onu.InternalState.Current() == "created" {
160 if err := onu.InternalState.Event("initialize"); err != nil {
161 logger.WithFields(log.Fields{
162 "OnuId": onu.ID,
163 "IntfId": onu.PonPortID,
164 "OnuSn": onu.Sn(),
165 }).Errorf("Cannot poweron ONU: %s", err.Error())
166 res.StatusCode = int32(codes.FailedPrecondition)
167 res.Message = err.Error()
168 return res, err
169 }
170 }
171
Pragya Arya1cbefa42020-01-13 12:15:29 +0530172 if err := onu.InternalState.Event("discover"); err != nil {
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700173 logger.WithFields(log.Fields{
174 "OnuId": onu.ID,
175 "IntfId": onu.PonPortID,
176 "OnuSn": onu.Sn(),
177 }).Errorf("Cannot poweron ONU: %s", err.Error())
178 res.StatusCode = int32(codes.FailedPrecondition)
179 res.Message = err.Error()
180 return res, err
181 }
182
183 res.StatusCode = int32(codes.OK)
184 res.Message = fmt.Sprintf("ONU %s successfully powered on.", onu.Sn())
185
186 return res, nil
187}
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700188
Arjun E K57a7fcb2020-01-30 06:44:45 +0000189func (s BBSimServer) ChangeIgmpState(ctx context.Context, req *bbsim.IgmpRequest) (*bbsim.Response, error) {
190 res := &bbsim.Response{}
191
192 logger.WithFields(log.Fields{
193 "OnuSn": req.OnuReq.SerialNumber,
194 "subAction": req.SubActionVal,
195 }).Infof("Received igmp request for ONU")
196
197 olt := devices.GetOLT()
198 onu, err := olt.FindOnuBySn(req.OnuReq.SerialNumber)
199
200 if err != nil {
201 res.StatusCode = int32(codes.NotFound)
202 res.Message = err.Error()
203 fmt.Println("ONU not found for sending igmp packet.")
204 return res, err
205 } else {
206 event := ""
207 switch req.SubActionVal {
208 case bbsim.SubActionTypes_JOIN:
209 event = "igmp_join_start"
210 case bbsim.SubActionTypes_LEAVE:
211 event = "igmp_leave"
212 }
213
214 if igmpErr := onu.InternalState.Event(event); igmpErr != nil {
215 logger.WithFields(log.Fields{
216 "OnuId": onu.ID,
217 "IntfId": onu.PonPortID,
218 "OnuSn": onu.Sn(),
219 }).Errorf("IGMP request failed: %s", igmpErr.Error())
220 res.StatusCode = int32(codes.FailedPrecondition)
221 res.Message = err.Error()
222 return res, igmpErr
223 }
224 }
225
226 return res, nil
227}
228
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700229func (s BBSimServer) RestartEapol(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
230 res := &bbsim.Response{}
231
232 logger.WithFields(log.Fields{
233 "OnuSn": req.SerialNumber,
234 }).Infof("Received request to restart authentication ONU")
235
236 olt := devices.GetOLT()
237
238 onu, err := olt.FindOnuBySn(req.SerialNumber)
239
240 if err != nil {
241 res.StatusCode = int32(codes.NotFound)
242 res.Message = err.Error()
243 return res, err
244 }
245
246 if err := onu.InternalState.Event("start_auth"); err != nil {
247 logger.WithFields(log.Fields{
248 "OnuId": onu.ID,
249 "IntfId": onu.PonPortID,
250 "OnuSn": onu.Sn(),
251 }).Errorf("Cannot restart authenticaton for ONU: %s", err.Error())
252 res.StatusCode = int32(codes.FailedPrecondition)
253 res.Message = err.Error()
254 return res, err
255 }
256
257 res.StatusCode = int32(codes.OK)
258 res.Message = fmt.Sprintf("Authentication restarted for ONU %s.", onu.Sn())
259
260 return res, nil
261}
262
263func (s BBSimServer) RestartDhcp(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
264 res := &bbsim.Response{}
265
266 logger.WithFields(log.Fields{
267 "OnuSn": req.SerialNumber,
268 }).Infof("Received request to restart DHCP on ONU")
269
270 olt := devices.GetOLT()
271
272 onu, err := olt.FindOnuBySn(req.SerialNumber)
273
274 if err != nil {
275 res.StatusCode = int32(codes.NotFound)
276 res.Message = err.Error()
277 return res, err
278 }
279
280 if err := onu.InternalState.Event("start_dhcp"); err != nil {
281 logger.WithFields(log.Fields{
282 "OnuId": onu.ID,
283 "IntfId": onu.PonPortID,
284 "OnuSn": onu.Sn(),
285 }).Errorf("Cannot restart DHCP for ONU: %s", err.Error())
286 res.StatusCode = int32(codes.FailedPrecondition)
287 res.Message = err.Error()
288 return res, err
289 }
290
291 res.StatusCode = int32(codes.OK)
292 res.Message = fmt.Sprintf("DHCP restarted for ONU %s.", onu.Sn())
293
294 return res, nil
295}