blob: 975b4261db3455c063ac81618d5cf5845412e9e7 [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()
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070056 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070057
58 if err != nil {
59 res := bbsim.ONU{}
60 return &res, err
61 }
62
63 res := bbsim.ONU{
64 ID: int32(onu.ID),
65 SerialNumber: onu.Sn(),
66 OperState: onu.OperState.Current(),
67 InternalState: onu.InternalState.Current(),
68 PonPortID: int32(onu.PonPortID),
69 STag: int32(onu.STag),
70 CTag: int32(onu.CTag),
71 HwAddress: onu.HwAddress.String(),
Matteo Scandolo27428702019-10-11 16:21:16 -070072 PortNo: int32(onu.PortNo),
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070073 }
74 return &res, nil
75}
76
Matteo Scandolo10f965c2019-09-24 10:40:46 -070077func (s BBSimServer) ShutdownONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
Anand S Katti09541352020-01-29 15:54:01 +053078 // 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 -070079 // is this the only way to do? Should we address other cases?
80 // Investigate what happens when:
81 // - a fiber is pulled
82 // - ONU malfunction
83 // - ONU shutdown
84 res := &bbsim.Response{}
85
86 logger.WithFields(log.Fields{
87 "OnuSn": req.SerialNumber,
88 }).Infof("Received request to shutdown ONU")
89
90 olt := devices.GetOLT()
91
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070092 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -070093
94 if err != nil {
95 res.StatusCode = int32(codes.NotFound)
96 res.Message = err.Error()
97 return res, err
98 }
99
100 dyingGasp := devices.Message{
101 Type: devices.DyingGaspIndication,
102 Data: devices.DyingGaspIndicationMessage{
103 OnuID: onu.ID,
104 PonPortID: onu.PonPortID,
105 Status: "on", // TODO do we need a type for Dying Gasp Indication?
106 },
107 }
108
109 onu.Channel <- dyingGasp
110
111 if err := onu.InternalState.Event("disable"); err != nil {
112 logger.WithFields(log.Fields{
113 "OnuId": onu.ID,
114 "IntfId": onu.PonPortID,
115 "OnuSn": onu.Sn(),
116 }).Errorf("Cannot shutdown ONU: %s", err.Error())
117 res.StatusCode = int32(codes.FailedPrecondition)
118 res.Message = err.Error()
119 return res, err
120 }
121
122 res.StatusCode = int32(codes.OK)
123 res.Message = fmt.Sprintf("ONU %s successfully shut down.", onu.Sn())
124
125 return res, nil
126}
127
128func (s BBSimServer) PoweronONU(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
129 res := &bbsim.Response{}
130
131 logger.WithFields(log.Fields{
132 "OnuSn": req.SerialNumber,
133 }).Infof("Received request to poweron ONU")
134
135 olt := devices.GetOLT()
136
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700137 onu, err := olt.FindOnuBySn(req.SerialNumber)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700138 if err != nil {
139 res.StatusCode = int32(codes.NotFound)
140 res.Message = err.Error()
141 return res, err
142 }
143
Pragya Arya2225f202020-01-29 18:05:01 +0530144 pon, _ := olt.GetPonById(onu.PonPortID)
145 if pon.InternalState.Current() != "enabled" {
146 err := fmt.Errorf("PON port %d not enabled", onu.PonPortID)
147 logger.WithFields(log.Fields{
148 "OnuId": onu.ID,
149 "IntfId": onu.PonPortID,
150 "OnuSn": onu.Sn(),
151 }).Errorf("Cannot poweron ONU: %s", err.Error())
152
153 res.StatusCode = int32(codes.FailedPrecondition)
154 res.Message = err.Error()
155 return res, err
156 }
157
158 if onu.InternalState.Current() == "created" {
159 if err := onu.InternalState.Event("initialize"); err != nil {
160 logger.WithFields(log.Fields{
161 "OnuId": onu.ID,
162 "IntfId": onu.PonPortID,
163 "OnuSn": onu.Sn(),
164 }).Errorf("Cannot poweron ONU: %s", err.Error())
165 res.StatusCode = int32(codes.FailedPrecondition)
166 res.Message = err.Error()
167 return res, err
168 }
169 }
170
Pragya Arya1cbefa42020-01-13 12:15:29 +0530171 if err := onu.InternalState.Event("discover"); err != nil {
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700172 logger.WithFields(log.Fields{
173 "OnuId": onu.ID,
174 "IntfId": onu.PonPortID,
175 "OnuSn": onu.Sn(),
176 }).Errorf("Cannot poweron ONU: %s", err.Error())
177 res.StatusCode = int32(codes.FailedPrecondition)
178 res.Message = err.Error()
179 return res, err
180 }
181
182 res.StatusCode = int32(codes.OK)
183 res.Message = fmt.Sprintf("ONU %s successfully powered on.", onu.Sn())
184
185 return res, nil
186}
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700187
Arjun E K57a7fcb2020-01-30 06:44:45 +0000188func (s BBSimServer) ChangeIgmpState(ctx context.Context, req *bbsim.IgmpRequest) (*bbsim.Response, error) {
189 res := &bbsim.Response{}
190
191 logger.WithFields(log.Fields{
192 "OnuSn": req.OnuReq.SerialNumber,
193 "subAction": req.SubActionVal,
194 }).Infof("Received igmp request for ONU")
195
196 olt := devices.GetOLT()
197 onu, err := olt.FindOnuBySn(req.OnuReq.SerialNumber)
198
199 if err != nil {
200 res.StatusCode = int32(codes.NotFound)
201 res.Message = err.Error()
202 fmt.Println("ONU not found for sending igmp packet.")
203 return res, err
204 } else {
205 event := ""
206 switch req.SubActionVal {
207 case bbsim.SubActionTypes_JOIN:
208 event = "igmp_join_start"
209 case bbsim.SubActionTypes_LEAVE:
210 event = "igmp_leave"
Anand S Katti09541352020-01-29 15:54:01 +0530211 case bbsim.SubActionTypes_JOINV3:
212 event = "igmp_join_startv3"
Arjun E K57a7fcb2020-01-30 06:44:45 +0000213 }
214
215 if igmpErr := onu.InternalState.Event(event); igmpErr != nil {
216 logger.WithFields(log.Fields{
217 "OnuId": onu.ID,
218 "IntfId": onu.PonPortID,
219 "OnuSn": onu.Sn(),
220 }).Errorf("IGMP request failed: %s", igmpErr.Error())
221 res.StatusCode = int32(codes.FailedPrecondition)
222 res.Message = err.Error()
223 return res, igmpErr
224 }
225 }
226
227 return res, nil
228}
229
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700230func (s BBSimServer) RestartEapol(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
231 res := &bbsim.Response{}
232
233 logger.WithFields(log.Fields{
234 "OnuSn": req.SerialNumber,
235 }).Infof("Received request to restart authentication ONU")
236
237 olt := devices.GetOLT()
238
239 onu, err := olt.FindOnuBySn(req.SerialNumber)
240
241 if err != nil {
242 res.StatusCode = int32(codes.NotFound)
243 res.Message = err.Error()
244 return res, err
245 }
246
247 if err := onu.InternalState.Event("start_auth"); err != nil {
248 logger.WithFields(log.Fields{
249 "OnuId": onu.ID,
250 "IntfId": onu.PonPortID,
251 "OnuSn": onu.Sn(),
252 }).Errorf("Cannot restart authenticaton for ONU: %s", err.Error())
253 res.StatusCode = int32(codes.FailedPrecondition)
254 res.Message = err.Error()
255 return res, err
256 }
257
258 res.StatusCode = int32(codes.OK)
259 res.Message = fmt.Sprintf("Authentication restarted for ONU %s.", onu.Sn())
260
261 return res, nil
262}
263
264func (s BBSimServer) RestartDhcp(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Response, error) {
265 res := &bbsim.Response{}
266
267 logger.WithFields(log.Fields{
268 "OnuSn": req.SerialNumber,
269 }).Infof("Received request to restart DHCP on ONU")
270
271 olt := devices.GetOLT()
272
273 onu, err := olt.FindOnuBySn(req.SerialNumber)
274
275 if err != nil {
276 res.StatusCode = int32(codes.NotFound)
277 res.Message = err.Error()
278 return res, err
279 }
280
281 if err := onu.InternalState.Event("start_dhcp"); err != nil {
282 logger.WithFields(log.Fields{
283 "OnuId": onu.ID,
284 "IntfId": onu.PonPortID,
285 "OnuSn": onu.Sn(),
286 }).Errorf("Cannot restart DHCP for ONU: %s", err.Error())
287 res.StatusCode = int32(codes.FailedPrecondition)
288 res.Message = err.Error()
289 return res, err
290 }
291
292 res.StatusCode = int32(codes.OK)
293 res.Message = fmt.Sprintf("DHCP restarted for ONU %s.", onu.Sn())
294
295 return res, nil
296}
Anand S Katti09541352020-01-29 15:54:01 +0530297
Pragya Arya8bdb4532020-03-02 17:08:09 +0530298// GetFlows for OLT/ONUs
299func (s BBSimServer) GetFlows(ctx context.Context, req *bbsim.ONURequest) (*bbsim.Flows, error) {
300 logger.WithFields(log.Fields{
301 "OnuSn": req.SerialNumber,
302 }).Info("Received GetFlows request")
303
304 olt := devices.GetOLT()
305 res := &bbsim.Flows{}
306
307 if req.SerialNumber == "" {
308 for flowKey := range olt.Flows {
309 flow := olt.Flows[flowKey]
310 res.Flows = append(res.Flows, &flow)
311 }
312 res.FlowCount = uint32(len(olt.Flows))
313 } else {
314 onu, err := olt.FindOnuBySn(req.SerialNumber)
315 if err != nil {
316 logger.WithFields(log.Fields{
317 "OnuSn": req.SerialNumber,
318 }).Error("Can't get ONU in GetFlows request")
319 return nil, err
320 }
321 for _, flowKey := range onu.Flows {
322 flow := olt.Flows[flowKey]
323 res.Flows = append(res.Flows, &flow)
324 }
325 res.FlowCount = uint32(len(onu.Flows))
326 }
327 return res, nil
328}
329
Anand S Katti09541352020-01-29 15:54:01 +0530330func (s BBSimServer) GetOnuTrafficSchedulers(ctx context.Context, req *bbsim.ONURequest) (*bbsim.ONUTrafficSchedulers, error) {
331 olt := devices.GetOLT()
332 ts := bbsim.ONUTrafficSchedulers{}
333
334 onu, err := olt.FindOnuBySn(req.SerialNumber)
335 if err != nil {
336 return &ts, err
337 }
338
339 if onu.TrafficSchedulers != nil {
340 ts.TraffSchedulers = onu.TrafficSchedulers
341 return &ts, nil
342 } else {
343 ts.TraffSchedulers = nil
344 return &ts, nil
345 }
346}