blob: 66abe147f36f6a2951ff9a157032df0c090ee0d2 [file] [log] [blame]
Matteo Scandolo11006992019-08-28 11:29: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
Matteo Scandolo4747d292019-08-05 11:50:18 -070017package devices
18
19import (
20 "context"
21 "errors"
22 "fmt"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070023 bbsim "github.com/opencord/bbsim/internal/bbsim/types"
24 "github.com/google/gopacket"
25 "github.com/google/gopacket/layers"
Matteo Scandolo4747d292019-08-05 11:50:18 -070026 "github.com/looplab/fsm"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070027 "github.com/opencord/voltha-protos/go/openolt"
Matteo Scandolod54283a2019-08-13 16:22:31 -070028 "github.com/opencord/voltha-protos/go/tech_profile"
Matteo Scandolo4747d292019-08-05 11:50:18 -070029 log "github.com/sirupsen/logrus"
30 "google.golang.org/grpc"
31 "net"
32 "sync"
33)
34
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070035var oltLogger = log.WithFields(log.Fields{
Matteo Scandolo84f7d482019-08-08 19:00:47 -070036 "module": "OLT",
37})
38
Matteo Scandolo4747d292019-08-05 11:50:18 -070039func init() {
40 //log.SetReportCaller(true)
41 log.SetLevel(log.DebugLevel)
42}
43
Matteo Scandolo84f7d482019-08-08 19:00:47 -070044var olt = OltDevice{}
45
46func GetOLT() OltDevice {
47 return olt
48}
49
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070050func CreateOLT(seq int, nni int, pon int, onuPerPon int, oltDoneChannel *chan bool, apiDoneChannel *chan bool, group *sync.WaitGroup) OltDevice {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070051 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -070052 "ID": seq,
53 "NumNni":nni,
54 "NumPon":pon,
55 "NumOnuPerPon":onuPerPon,
56 }).Debug("CreateOLT")
57
Matteo Scandolo84f7d482019-08-08 19:00:47 -070058 olt = OltDevice{
Matteo Scandolo4747d292019-08-05 11:50:18 -070059 ID: seq,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070060 OperState: getOperStateFSM(func(e *fsm.Event) {
61 oltLogger.Debugf("Changing OLT OperState from %s to %s", e.Src, e.Dst)
62 }),
Matteo Scandolo4747d292019-08-05 11:50:18 -070063 NumNni:nni,
64 NumPon:pon,
65 NumOnuPerPon:onuPerPon,
66 Pons: []PonPort{},
67 Nnis: []NniPort{},
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070068 channel: make(chan Message),
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070069 oltDoneChannel: oltDoneChannel,
70 apiDoneChannel: apiDoneChannel,
Matteo Scandolo4747d292019-08-05 11:50:18 -070071 }
72
73 // OLT State machine
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070074 // NOTE do we need 2 state machines for the OLT? (InternalState and OperState)
Matteo Scandolo4747d292019-08-05 11:50:18 -070075 olt.InternalState = fsm.NewFSM(
76 "created",
77 fsm.Events{
78 {Name: "enable", Src: []string{"created"}, Dst: "enabled"},
79 {Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
80 },
81 fsm.Callbacks{
82 "enter_state": func(e *fsm.Event) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070083 oltLogger.Debugf("Changing OLT InternalState from %s to %s", e.Src, e.Dst)
Matteo Scandolo4747d292019-08-05 11:50:18 -070084 },
85 },
86 )
87
88 // create NNI Port
89 nniPort := NniPort{
90 ID: uint32(0),
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070091 OperState: getOperStateFSM(func(e *fsm.Event) {
92 oltLogger.Debugf("Changing NNI OperState from %s to %s", e.Src, e.Dst)
93 }),
Matteo Scandolo4747d292019-08-05 11:50:18 -070094 Type: "nni",
95 }
96 olt.Nnis = append(olt.Nnis, nniPort)
97
98 // create PON ports
Matteo Scandolo3bc73742019-08-20 14:04:04 -070099 //onuId := 1
Matteo Scandolo4747d292019-08-05 11:50:18 -0700100 for i := 0; i < pon; i++ {
101 p := PonPort{
102 NumOnu: olt.NumOnuPerPon,
103 ID: uint32(i),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700104 Type: "pon",
105 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700106 p.OperState = getOperStateFSM(func(e *fsm.Event) {
107 oltLogger.WithFields(log.Fields{
108 "ID": p.ID,
109 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
110 })
Matteo Scandolo4747d292019-08-05 11:50:18 -0700111
112 // create ONU devices
113 for j := 0; j < onuPerPon; j++ {
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700114 //o := CreateONU(olt, p, uint32(onuId))
115 o := CreateONU(olt, p, uint32(j + 1))
Matteo Scandolo4747d292019-08-05 11:50:18 -0700116 p.Onus = append(p.Onus, o)
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700117 //onuId = onuId + 1
Matteo Scandolo4747d292019-08-05 11:50:18 -0700118 }
119
120 olt.Pons = append(olt.Pons, p)
121 }
122
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700123 newOltServer(olt)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700124
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700125 group.Done()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700126 return olt
127}
128
129func newOltServer(o OltDevice) error {
130 // TODO make configurable
131 address := "0.0.0.0:50060"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700132 lis, err := net.Listen("tcp", address)
133 if err != nil {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700134 oltLogger.Fatalf("OLT failed to listen: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700135 }
136 grpcServer := grpc.NewServer()
137 openolt.RegisterOpenoltServer(grpcServer, o)
138
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700139 wg := sync.WaitGroup{}
140 wg.Add(1)
141
Matteo Scandolo4747d292019-08-05 11:50:18 -0700142 go grpcServer.Serve(lis)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700143 oltLogger.Debugf("OLT Listening on: %v", address)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700144
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700145 for {
146 _, ok := <- *o.oltDoneChannel
147 if !ok {
148 // if the olt channel is closed, stop the gRPC server
149 log.Warnf("Stopping OLT gRPC server")
150 grpcServer.Stop()
151 wg.Done()
152 break
153 }
154 }
155
156 wg.Wait()
157
Matteo Scandolo4747d292019-08-05 11:50:18 -0700158 return nil
159}
160
161// Device Methods
162
163func (o OltDevice) Enable (stream openolt.Openolt_EnableIndicationServer) error {
164
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700165 oltLogger.Debug("Enable OLT called")
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700166
Matteo Scandolo4747d292019-08-05 11:50:18 -0700167 wg := sync.WaitGroup{}
168 wg.Add(1)
169
170 // create a channel for all the OLT events
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700171 go o.processOltMessages(stream)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700172
173 // enable the OLT
174 olt_msg := Message{
175 Type: OltIndication,
176 Data: OltIndicationMessage{
177 OperState: UP,
178 },
179 }
180 o.channel <- olt_msg
181
182 // send NNI Port Indications
183 for _, nni := range o.Nnis {
184 msg := Message{
185 Type: NniIndication,
186 Data: NniIndicationMessage{
187 OperState: UP,
188 NniPortID: nni.ID,
189 },
190 }
191 o.channel <- msg
192 }
193
194 // send PON Port indications
195 for _, pon := range o.Pons {
196 msg := Message{
197 Type: PonIndication,
198 Data: PonIndicationMessage{
199 OperState: UP,
200 PonPortID: pon.ID,
201 },
202 }
203 o.channel <- msg
204
205 for _, onu := range pon.Onus {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700206 go onu.processOnuMessages(stream)
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700207 go onu.processOmciMessages(stream)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700208 msg := Message{
209 Type: OnuDiscIndication,
210 Data: OnuDiscIndicationMessage{
211 Onu: onu,
212 OperState: UP,
213 },
214 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700215 onu.channel <- msg
Matteo Scandolo4747d292019-08-05 11:50:18 -0700216 }
217 }
218
219 wg.Wait()
220 return nil
221}
222
223// Helpers method
224
225func (o OltDevice) getPonById(id uint32) (*PonPort, error) {
226 for _, pon := range o.Pons {
227 if pon.ID == id {
228 return &pon, nil
229 }
230 }
231 return nil, errors.New(fmt.Sprintf("Cannot find PonPort with id %d in OLT %d", id, o.ID))
232}
233
234func (o OltDevice) getNniById(id uint32) (*NniPort, error) {
235 for _, nni := range o.Nnis {
236 if nni.ID == id {
237 return &nni, nil
238 }
239 }
240 return nil, errors.New(fmt.Sprintf("Cannot find NniPort with id %d in OLT %d", id, o.ID))
241}
242
Matteo Scandolo4747d292019-08-05 11:50:18 -0700243func (o OltDevice) sendOltIndication(msg OltIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
244 data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: msg.OperState.String()}}
245 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700246 oltLogger.Errorf("Failed to send Indication_OltInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700247 }
248
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700249 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700250 "OperState": msg.OperState,
251 }).Debug("Sent Indication_OltInd")
252}
253
254func (o OltDevice) sendNniIndication(msg NniIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
255 nni, _ := o.getNniById(msg.NniPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700256 nni.OperState.Event("enable")
257 // NOTE Operstate may need to be an integer
Matteo Scandolo4747d292019-08-05 11:50:18 -0700258 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
259 Type: nni.Type,
260 IntfId: nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700261 OperState: nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700262 }}
263
264 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700265 oltLogger.Errorf("Failed to send Indication_IntfOperInd for NNI: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700266 }
267
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700268 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700269 "Type": nni.Type,
270 "IntfId": nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700271 "OperState": nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700272 }).Debug("Sent Indication_IntfOperInd for NNI")
273}
274
275func (o OltDevice) sendPonIndication(msg PonIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
276 pon, _ := o.getPonById(msg.PonPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700277 pon.OperState.Event("enable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700278 discoverData := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{
279 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700280 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700281 }}
282
283 if err := stream.Send(&openolt.Indication{Data: discoverData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700284 oltLogger.Errorf("Failed to send Indication_IntfInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700285 }
286
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700287 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700288 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700289 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700290 }).Debug("Sent Indication_IntfInd")
291
292 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
293 Type: pon.Type,
294 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700295 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700296 }}
297
298 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700299 oltLogger.Errorf("Failed to send Indication_IntfOperInd for PON: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700300 }
301
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700302 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700303 "Type": pon.Type,
304 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700305 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700306 }).Debug("Sent Indication_IntfOperInd for PON")
307}
308
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700309func (o OltDevice) processOltMessages(stream openolt.Openolt_EnableIndicationServer) {
310 oltLogger.Debug("Started OLT Indication Channel")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700311 for message := range o.channel {
312
Matteo Scandolo4747d292019-08-05 11:50:18 -0700313
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700314 oltLogger.WithFields(log.Fields{
315 "oltId": o.ID,
316 "messageType": message.Type,
317 }).Trace("Received message")
318
319 switch message.Type {
320 case OltIndication:
321 msg, _ := message.Data.(OltIndicationMessage)
322 if msg.OperState == UP {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700323 o.InternalState.Event("enable")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700324 o.OperState.Event("enable")
325 } else if msg.OperState == DOWN {
326 o.InternalState.Event("disable")
327 o.OperState.Event("disable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700328 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700329 o.sendOltIndication(msg, stream)
330 case NniIndication:
331 msg, _ := message.Data.(NniIndicationMessage)
332 o.sendNniIndication(msg, stream)
333 case PonIndication:
334 msg, _ := message.Data.(PonIndicationMessage)
335 o.sendPonIndication(msg, stream)
336 default:
337 oltLogger.Warnf("Received unknown message data %v for type %v in OLT channel", message.Data, message.Type)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700338 }
339
340 }
341}
342
343// GRPC Endpoints
344
345func (o OltDevice) ActivateOnu(context context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700346 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700347 "onuSerialNumber": onu.SerialNumber,
348 }).Info("Received ActivateOnu call from VOLTHA")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700349
350 pon, _ := o.getPonById(onu.IntfId)
351 _onu, _ := pon.getOnuBySn(onu.SerialNumber)
352
353 // NOTE we need to immediately activate the ONU or the OMCI state machine won't start
Matteo Scandolo4747d292019-08-05 11:50:18 -0700354 msg := Message{
355 Type: OnuIndication,
356 Data: OnuIndicationMessage{
357 OnuSN: onu.SerialNumber,
358 PonPortID: onu.IntfId,
359 OperState: UP,
360 },
361 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700362 _onu.channel <- msg
Matteo Scandolo4747d292019-08-05 11:50:18 -0700363 return new(openolt.Empty) , nil
364}
365
366func (o OltDevice) DeactivateOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700367 oltLogger.Error("DeactivateOnu not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700368 return new(openolt.Empty) , nil
369}
370
371func (o OltDevice) DeleteOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700372 oltLogger.Error("DeleteOnu not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700373 return new(openolt.Empty) , nil
374}
375
376func (o OltDevice) DisableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700377 // NOTE when we disable the OLT should we disable NNI, PONs and ONUs altogether?
378 olt_msg := Message{
379 Type: OltIndication,
380 Data: OltIndicationMessage{
381 OperState: DOWN,
382 },
383 }
384 o.channel <- olt_msg
Matteo Scandolo4747d292019-08-05 11:50:18 -0700385 return new(openolt.Empty) , nil
386}
387
388func (o OltDevice) DisablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700389 oltLogger.Error("DisablePonIf not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700390 return new(openolt.Empty) , nil
391}
392
393func (o OltDevice) EnableIndication(_ *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700394 oltLogger.WithField("oltId", o.ID).Info("OLT receives EnableIndication call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700395 o.Enable(stream)
396 return nil
397}
398
399func (o OltDevice) EnablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700400 oltLogger.Error("EnablePonIf not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700401 return new(openolt.Empty) , nil
402}
403
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700404func (o OltDevice) FlowAdd(ctx context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
405 oltLogger.WithFields(log.Fields{
406 "IntfId": flow.AccessIntfId,
407 "OnuId": flow.OnuId,
408 "EthType": fmt.Sprintf("%x", flow.Classifier.EthType),
409 "InnerVlan": flow.Classifier.IVid,
410 "OuterVlan": flow.Classifier.OVid,
411 "FlowType": flow.FlowType,
412 "FlowId": flow.FlowId,
413 "UniID": flow.UniId,
414 "PortNo": flow.PortNo,
415 }).Infof("OLT receives Flow")
416 // TODO optionally store flows somewhere
417
418 if flow.AccessIntfId == -1 {
419 oltLogger.WithFields(log.Fields{
420 "FlowId": flow.FlowId,
421 }).Debugf("This is an OLT flow")
422 } else {
423 pon, _ := o.getPonById(uint32(flow.AccessIntfId))
424 onu, _ := pon.getOnuById(uint32(flow.OnuId))
425
426 msg := Message{
427 Type: FlowUpdate,
428 Data: OnuFlowUpdateMessage{
429 PonPortID: pon.ID,
430 OnuID: onu.ID,
431 Flow: flow,
432 },
433 }
434 onu.channel <- msg
435 }
436
Matteo Scandolo4747d292019-08-05 11:50:18 -0700437 return new(openolt.Empty) , nil
438}
439
440func (o OltDevice) FlowRemove(context.Context, *openolt.Flow) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700441 oltLogger.Info("received FlowRemove")
442 // TODO store flows somewhere
Matteo Scandolo4747d292019-08-05 11:50:18 -0700443 return new(openolt.Empty) , nil
444}
445
446func (o OltDevice) HeartbeatCheck(context.Context, *openolt.Empty) (*openolt.Heartbeat, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700447 oltLogger.Error("HeartbeatCheck not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700448 return new(openolt.Heartbeat) , nil
449}
450
451func (o OltDevice) GetDeviceInfo(context.Context, *openolt.Empty) (*openolt.DeviceInfo, error) {
452
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700453 oltLogger.WithFields(log.Fields{
454 "oltId": o.ID,
455 "PonPorts": o.NumPon,
456 }).Info("OLT receives GetDeviceInfo call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700457 devinfo := new(openolt.DeviceInfo)
458 devinfo.Vendor = "BBSim"
459 devinfo.Model = "asfvolt16"
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700460 devinfo.HardwareVersion = "emulated"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700461 devinfo.FirmwareVersion = ""
462 devinfo.Technology = "xgspon"
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700463 devinfo.PonPorts = uint32(o.NumPon)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700464 devinfo.OnuIdStart = 1
465 devinfo.OnuIdEnd = 255
466 devinfo.AllocIdStart = 1024
467 devinfo.AllocIdEnd = 16383
468 devinfo.GemportIdStart = 1024
469 devinfo.GemportIdEnd = 65535
470 devinfo.FlowIdStart = 1
471 devinfo.FlowIdEnd = 16383
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700472 devinfo.DeviceSerialNumber = fmt.Sprintf("BBSIM_OLT_%d", o.ID)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700473
474 return devinfo, nil
475}
476
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700477func (o OltDevice) OmciMsgOut(ctx context.Context, omci_msg *openolt.OmciMsg) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700478 pon, _ := o.getPonById(omci_msg.IntfId)
479 onu, _ := pon.getOnuById(omci_msg.OnuId)
480 msg := Message{
481 Type: OMCI,
482 Data: OmciMessage{
483 OnuSN: onu.SerialNumber,
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700484 OnuID: onu.ID,
485 omciMsg: omci_msg,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700486 },
487 }
488 onu.channel <- msg
Matteo Scandolo4747d292019-08-05 11:50:18 -0700489 return new(openolt.Empty) , nil
490}
491
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700492func (o OltDevice) OnuPacketOut(ctx context.Context, onuPkt *openolt.OnuPacket) (*openolt.Empty, error) {
493 pon, _ := o.getPonById(onuPkt.IntfId)
494 onu, _ := pon.getOnuById(onuPkt.OnuId)
495
496 rawpkt := gopacket.NewPacket(onuPkt.Pkt, layers.LayerTypeEthernet, gopacket.Default)
497
498 // NOTE is this the best way to the to the ethertype?
499 etherType := rawpkt.Layer(layers.LayerTypeEthernet).(*layers.Ethernet).EthernetType
500
501 if etherType == layers.EthernetTypeEAPOL {
502 eapolPkt := bbsim.ByteMsg{IntfId: onuPkt.IntfId, OnuId: onuPkt.OnuId, Bytes: rawpkt.Data()}
503 onu.eapolPktOutCh <- &eapolPkt
504 }
Matteo Scandolo4747d292019-08-05 11:50:18 -0700505 return new(openolt.Empty) , nil
506}
507
508func (o OltDevice) Reboot(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700509 oltLogger.Info("Shutting Down")
510 close(*o.oltDoneChannel)
511 close(*o.apiDoneChannel)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700512 return new(openolt.Empty) , nil
513}
514
515func (o OltDevice) ReenableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700516 oltLogger.Error("ReenableOlt not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700517 return new(openolt.Empty) , nil
518}
519
520func (o OltDevice) UplinkPacketOut(context context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700521 oltLogger.Warn("UplinkPacketOut not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700522 return new(openolt.Empty) , nil
523}
524
525func (o OltDevice) CollectStatistics(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700526 oltLogger.Error("CollectStatistics not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700527 return new(openolt.Empty) , nil
528}
529
Matteo Scandolo4747d292019-08-05 11:50:18 -0700530func (o OltDevice) GetOnuInfo(context context.Context, packet *openolt.Onu) (*openolt.OnuIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700531 oltLogger.Error("GetOnuInfo not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700532 return new(openolt.OnuIndication) , nil
533}
534
535func (o OltDevice) GetPonIf(context context.Context, packet *openolt.Interface) (*openolt.IntfIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700536 oltLogger.Error("GetPonIf not implemented")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700537 return new(openolt.IntfIndication) , nil
Matteo Scandolod54283a2019-08-13 16:22:31 -0700538}
539
540func (s OltDevice) CreateTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700541 oltLogger.Info("received CreateTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700542 return new(openolt.Empty), nil
543}
544
545func (s OltDevice) RemoveTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700546 oltLogger.Info("received RemoveTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700547 return new(openolt.Empty), nil
548}
549
550func (s OltDevice) CreateTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700551 oltLogger.Info("received CreateTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700552 return new(openolt.Empty), nil
553}
554
555func (s OltDevice) RemoveTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700556 oltLogger.Info("received RemoveTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700557 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700558}