blob: eabbe622c0bcdfbe9fb17cbf10f31f941bdba132 [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"
Zdravko Bozakov2da76342019-10-21 09:47:35 +020023 "net"
24 "sync"
Zdravko Bozakov681364d2019-11-10 14:28:46 +010025 "time"
Zdravko Bozakov2da76342019-10-21 09:47:35 +020026
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070027 "github.com/google/gopacket"
28 "github.com/google/gopacket/layers"
Matteo Scandolo4747d292019-08-05 11:50:18 -070029 "github.com/looplab/fsm"
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070030 "github.com/opencord/bbsim/internal/bbsim/packetHandlers"
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070031 bbsim "github.com/opencord/bbsim/internal/bbsim/types"
William Kurkian9dadc5b2019-10-22 13:51:57 -040032 omcisim "github.com/opencord/omci-sim"
Matteo Scandolo3de9de02019-11-14 13:40:03 -080033 "github.com/opencord/voltha-protos/v2/go/openolt"
34 "github.com/opencord/voltha-protos/v2/go/tech_profile"
Matteo Scandolo4747d292019-08-05 11:50:18 -070035 log "github.com/sirupsen/logrus"
36 "google.golang.org/grpc"
Zdravko Bozakov681364d2019-11-10 14:28:46 +010037 "google.golang.org/grpc/reflection"
Matteo Scandolo4747d292019-08-05 11:50:18 -070038)
39
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070040var oltLogger = log.WithFields(log.Fields{
Matteo Scandolo84f7d482019-08-08 19:00:47 -070041 "module": "OLT",
42})
43
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070044type OltDevice struct {
45 // BBSIM Internals
46 ID int
47 SerialNumber string
48 NumNni int
49 NumPon int
50 NumOnuPerPon int
51 InternalState *fsm.FSM
52 channel chan Message
Zdravko Bozakov681364d2019-11-10 14:28:46 +010053 nniPktInChannel chan *bbsim.PacketMsg // packets coming in from the NNI and going to VOLTHA
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070054
Matteo Scandoloe33447a2019-10-31 12:38:23 -070055 Delay int
56
Matteo Scandolo27428702019-10-11 16:21:16 -070057 Pons []*PonPort
58 Nnis []*NniPort
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070059
60 // OLT Attributes
61 OperState *fsm.FSM
Matteo Scandolo4747d292019-08-05 11:50:18 -070062}
63
Matteo Scandolo27428702019-10-11 16:21:16 -070064var olt OltDevice
Zdravko Bozakov681364d2019-11-10 14:28:46 +010065var oltServer *grpc.Server
Matteo Scandolo84f7d482019-08-08 19:00:47 -070066
Matteo Scandolo27428702019-10-11 16:21:16 -070067func GetOLT() *OltDevice {
68 return &olt
Matteo Scandolo84f7d482019-08-08 19:00:47 -070069}
70
Zdravko Bozakov681364d2019-11-10 14:28:46 +010071func CreateOLT(oltId int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, auth bool, dhcp bool, delay int, isMock bool) *OltDevice {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070072 oltLogger.WithFields(log.Fields{
Matteo Scandolo40e067f2019-10-16 16:59:41 -070073 "ID": oltId,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070074 "NumNni": nni,
75 "NumPon": pon,
76 "NumOnuPerPon": onuPerPon,
Matteo Scandolo4747d292019-08-05 11:50:18 -070077 }).Debug("CreateOLT")
78
Matteo Scandolo84f7d482019-08-08 19:00:47 -070079 olt = OltDevice{
Matteo Scandolo40e067f2019-10-16 16:59:41 -070080 ID: oltId,
81 SerialNumber: fmt.Sprintf("BBSIM_OLT_%d", oltId),
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070082 OperState: getOperStateFSM(func(e *fsm.Event) {
83 oltLogger.Debugf("Changing OLT OperState from %s to %s", e.Src, e.Dst)
84 }),
Zdravko Bozakov681364d2019-11-10 14:28:46 +010085 NumNni: nni,
86 NumPon: pon,
87 NumOnuPerPon: onuPerPon,
88 Pons: []*PonPort{},
89 Nnis: []*NniPort{},
90 Delay: delay,
Matteo Scandolo4747d292019-08-05 11:50:18 -070091 }
92
93 // OLT State machine
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070094 // NOTE do we need 2 state machines for the OLT? (InternalState and OperState)
Matteo Scandolo4747d292019-08-05 11:50:18 -070095 olt.InternalState = fsm.NewFSM(
96 "created",
97 fsm.Events{
Zdravko Bozakov681364d2019-11-10 14:28:46 +010098 {Name: "initialize", Src: []string{"disabled", "created"}, Dst: "initialized"},
99 {Name: "enable", Src: []string{"initialized", "disabled"}, Dst: "enabled"},
Matteo Scandolo4747d292019-08-05 11:50:18 -0700100 {Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
101 },
102 fsm.Callbacks{
103 "enter_state": func(e *fsm.Event) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700104 oltLogger.Debugf("Changing OLT InternalState from %s to %s", e.Src, e.Dst)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700105 },
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100106 "enter_disabled": func(e *fsm.Event) { olt.disableOlt() },
107 "enter_initialized": func(e *fsm.Event) { olt.InitOlt() },
Matteo Scandolo4747d292019-08-05 11:50:18 -0700108 },
109 )
110
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700111 if isMock != true {
112 // create NNI Port
113 nniPort, err := CreateNNI(&olt)
114 if err != nil {
115 oltLogger.Fatalf("Couldn't create NNI Port: %v", err)
116 }
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700117
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700118 olt.Nnis = append(olt.Nnis, &nniPort)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700119 }
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700120
Matteo Scandolo4747d292019-08-05 11:50:18 -0700121 // create PON ports
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700122 availableCTag := cTagInit
Matteo Scandolo4747d292019-08-05 11:50:18 -0700123 for i := 0; i < pon; i++ {
124 p := PonPort{
125 NumOnu: olt.NumOnuPerPon,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700126 ID: uint32(i),
127 Type: "pon",
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700128 Olt: olt,
Matteo Scandolo27428702019-10-11 16:21:16 -0700129 Onus: []*Onu{},
Matteo Scandolo4747d292019-08-05 11:50:18 -0700130 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700131 p.OperState = getOperStateFSM(func(e *fsm.Event) {
132 oltLogger.WithFields(log.Fields{
133 "ID": p.ID,
134 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
135 })
Matteo Scandolo4747d292019-08-05 11:50:18 -0700136
137 // create ONU devices
138 for j := 0; j < onuPerPon; j++ {
Matteo Scandoloc1147092019-10-29 09:38:33 -0700139 o := CreateONU(olt, p, uint32(j+1), sTag, availableCTag, auth, dhcp)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700140 p.Onus = append(p.Onus, o)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700141 availableCTag = availableCTag + 1
Matteo Scandolo4747d292019-08-05 11:50:18 -0700142 }
143
Matteo Scandolo27428702019-10-11 16:21:16 -0700144 olt.Pons = append(olt.Pons, &p)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700145 }
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100146
Matteo Scandolod32c3822019-11-26 15:57:46 -0700147 if isMock != true {
148 if err := olt.InternalState.Event("initialize"); err != nil {
149 log.Errorf("Error initializing OLT: %v", err)
150 return nil
151 }
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100152 }
153
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700154 return &olt
155}
Matteo Scandolo4747d292019-08-05 11:50:18 -0700156
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100157func (o *OltDevice) InitOlt() error {
158
159 if oltServer == nil {
160 oltServer, _ = newOltServer()
161 } else {
162 oltLogger.Warn("OLT server already running.")
163 }
164
165 // create new channel for processOltMessages Go routine
166 o.channel = make(chan Message)
167
168 o.nniPktInChannel = make(chan *bbsim.PacketMsg, 1024)
169 // FIXME we are assuming we have only one NNI
170 if o.Nnis[0] != nil {
171 ch, err := o.Nnis[0].NewVethChan()
172 if err == nil {
173 o.nniPktInChannel = ch
174 } else {
175 log.Errorf("Error getting NNI channel: %v", err)
176 }
177 }
178
179 for i := range olt.Pons {
180 for _, onu := range olt.Pons[i].Onus {
181 if err := onu.InternalState.Event("initialize"); err != nil {
182 log.Errorf("Error initializing ONU: %v", err)
183 return err
184 }
185 }
186 }
187
188 return nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700189}
190
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100191// callback for disable state entry
192func (o *OltDevice) disableOlt() error {
193
194 // disable all onus
195 for i := range o.Pons {
196 for _, onu := range o.Pons[i].Onus {
197 // NOTE order of these is important.
198 onu.OperState.Event("disable")
199 onu.InternalState.Event("disable")
200 }
201 }
202
203 // TODO handle hard poweroff (i.e. no indications sent to Voltha) vs soft poweroff
204 if err := StopOltServer(); err != nil {
205 return err
206 }
207
208 // terminate the OLT's processOltMessages go routine
209 close(o.channel)
210 // terminate the OLT's processNniPacketIns go routine
211 close(o.nniPktInChannel)
212 return nil
213}
214
215func (o *OltDevice) RestartOLT() error {
216 oltLogger.Infof("Simulating OLT restart... (%ds)", OltRebootDelay)
217
218 // transition internal state to disable
219 if !o.InternalState.Is("disabled") {
220 if err := o.InternalState.Event("disable"); err != nil {
221 log.Errorf("Error disabling OLT: %v", err)
222 return err
223 }
224 }
225
226 time.Sleep(OltRebootDelay * time.Second)
227
228 if err := o.InternalState.Event("initialize"); err != nil {
229 log.Errorf("Error initializing OLT: %v", err)
230 return err
231 }
232 oltLogger.Info("OLT restart completed")
233 return nil
234}
235
236// newOltServer launches a new grpc server for OpenOLT
237func newOltServer() (*grpc.Server, error) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700238 // TODO make configurable
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700239 address := "0.0.0.0:50060"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700240 lis, err := net.Listen("tcp", address)
241 if err != nil {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700242 oltLogger.Fatalf("OLT failed to listen: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700243 }
244 grpcServer := grpc.NewServer()
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100245
246 o := GetOLT()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700247 openolt.RegisterOpenoltServer(grpcServer, o)
248
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100249 reflection.Register(grpcServer)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700250
Matteo Scandolo4747d292019-08-05 11:50:18 -0700251 go grpcServer.Serve(lis)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700252 oltLogger.Debugf("OLT Listening on: %v", address)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700253
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100254 return grpcServer, nil
255}
256
257// StopOltServer stops the OpenOLT grpc server
258func StopOltServer() error {
259 // TODO handle poweroff vs graceful shutdown
260 if oltServer != nil {
261 log.Warnf("Stopping OLT gRPC server")
262 oltServer.Stop()
263 oltServer = nil
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700264 }
Matteo Scandolo4747d292019-08-05 11:50:18 -0700265 return nil
266}
267
268// Device Methods
269
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100270// Enable implements the OpenOLT EnableIndicationServer functionality
271func (o *OltDevice) Enable(stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700272 oltLogger.Debug("Enable OLT called")
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700273
Matteo Scandolo4747d292019-08-05 11:50:18 -0700274 wg := sync.WaitGroup{}
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700275 wg.Add(2)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700276
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100277 // create Go routine to process all OLT events
278 go o.processOltMessages(stream, &wg)
279 go o.processNniPacketIns(stream, &wg)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700280
281 // enable the OLT
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100282 oltMsg := Message{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700283 Type: OltIndication,
284 Data: OltIndicationMessage{
285 OperState: UP,
286 },
287 }
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100288 o.channel <- oltMsg
Matteo Scandolo4747d292019-08-05 11:50:18 -0700289
290 // send NNI Port Indications
291 for _, nni := range o.Nnis {
292 msg := Message{
293 Type: NniIndication,
294 Data: NniIndicationMessage{
295 OperState: UP,
296 NniPortID: nni.ID,
297 },
298 }
299 o.channel <- msg
300 }
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100301
William Kurkian9dadc5b2019-10-22 13:51:57 -0400302 go o.processOmciMessages()
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100303
Matteo Scandolo4747d292019-08-05 11:50:18 -0700304 // send PON Port indications
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100305 for i, pon := range o.Pons {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700306 msg := Message{
307 Type: PonIndication,
308 Data: PonIndicationMessage{
309 OperState: UP,
310 PonPortID: pon.ID,
311 },
312 }
313 o.channel <- msg
314
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100315 for _, onu := range o.Pons[i].Onus {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700316 go onu.ProcessOnuMessages(stream, nil)
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100317 if err := onu.InternalState.Event("discover"); err != nil {
318 log.Errorf("Error discover ONU: %v", err)
319 return err
Matteo Scandolo4747d292019-08-05 11:50:18 -0700320 }
Matteo Scandolo4747d292019-08-05 11:50:18 -0700321 }
322 }
323
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100324 oltLogger.Warn("Enable OLT Done")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700325 wg.Wait()
326 return nil
327}
328
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100329func (o *OltDevice) processOmciMessages() {
William Kurkian9dadc5b2019-10-22 13:51:57 -0400330 ch := omcisim.GetChannel()
331
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100332 oltLogger.Debug("Starting OMCI Indication Channel")
William Kurkian9dadc5b2019-10-22 13:51:57 -0400333
334 for message := range ch {
335 onuId := message.Data.OnuId
336 intfId := message.Data.IntfId
337 onu, err := o.FindOnuById(intfId, onuId)
338 if err != nil {
339 oltLogger.Errorf("Failed to find onu: %v", err)
340 }
341 go onu.processOmciMessage(message)
342 }
343}
344
Matteo Scandolo4747d292019-08-05 11:50:18 -0700345// Helpers method
346
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700347func (o OltDevice) GetPonById(id uint32) (*PonPort, error) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700348 for _, pon := range o.Pons {
349 if pon.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700350 return pon, nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700351 }
352 }
353 return nil, errors.New(fmt.Sprintf("Cannot find PonPort with id %d in OLT %d", id, o.ID))
354}
355
356func (o OltDevice) getNniById(id uint32) (*NniPort, error) {
357 for _, nni := range o.Nnis {
358 if nni.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700359 return nni, nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700360 }
361 }
362 return nil, errors.New(fmt.Sprintf("Cannot find NniPort with id %d in OLT %d", id, o.ID))
363}
364
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100365func (o *OltDevice) sendOltIndication(msg OltIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700366 data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: msg.OperState.String()}}
367 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700368 oltLogger.Errorf("Failed to send Indication_OltInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700369 }
370
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700371 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700372 "OperState": msg.OperState,
373 }).Debug("Sent Indication_OltInd")
374}
375
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100376func (o *OltDevice) sendNniIndication(msg NniIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700377 nni, _ := o.getNniById(msg.NniPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700378 nni.OperState.Event("enable")
379 // NOTE Operstate may need to be an integer
Matteo Scandolo4747d292019-08-05 11:50:18 -0700380 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700381 Type: nni.Type,
382 IntfId: nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700383 OperState: nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700384 }}
385
386 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700387 oltLogger.Errorf("Failed to send Indication_IntfOperInd for NNI: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700388 }
389
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700390 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700391 "Type": nni.Type,
392 "IntfId": nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700393 "OperState": nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700394 }).Debug("Sent Indication_IntfOperInd for NNI")
395}
396
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100397func (o *OltDevice) sendPonIndication(msg PonIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700398 pon, _ := o.GetPonById(msg.PonPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700399 pon.OperState.Event("enable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700400 discoverData := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700401 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700402 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700403 }}
404
405 if err := stream.Send(&openolt.Indication{Data: discoverData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700406 oltLogger.Errorf("Failed to send Indication_IntfInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700407 }
408
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700409 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700410 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700411 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700412 }).Debug("Sent Indication_IntfInd")
413
414 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700415 Type: pon.Type,
416 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700417 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700418 }}
419
420 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700421 oltLogger.Errorf("Failed to send Indication_IntfOperInd for PON: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700422 }
423
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700424 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700425 "Type": pon.Type,
426 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700427 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700428 }).Debug("Sent Indication_IntfOperInd for PON")
429}
430
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100431// processOltMessages handles messages received over the OpenOLT interface
432func (o *OltDevice) processOltMessages(stream openolt.Openolt_EnableIndicationServer, wg *sync.WaitGroup) {
433 oltLogger.Debug("Starting OLT Indication Channel")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700434 for message := range o.channel {
435
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700436 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700437 "oltId": o.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700438 "messageType": message.Type,
439 }).Trace("Received message")
440
441 switch message.Type {
442 case OltIndication:
443 msg, _ := message.Data.(OltIndicationMessage)
444 if msg.OperState == UP {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700445 o.InternalState.Event("enable")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700446 o.OperState.Event("enable")
447 } else if msg.OperState == DOWN {
448 o.InternalState.Event("disable")
449 o.OperState.Event("disable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700450 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700451 o.sendOltIndication(msg, stream)
452 case NniIndication:
453 msg, _ := message.Data.(NniIndicationMessage)
454 o.sendNniIndication(msg, stream)
455 case PonIndication:
456 msg, _ := message.Data.(PonIndicationMessage)
457 o.sendPonIndication(msg, stream)
458 default:
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700459 oltLogger.Warnf("Received unknown message data %v for type %v in OLT Channel", message.Data, message.Type)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700460 }
461
462 }
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100463 wg.Done()
464 oltLogger.Warn("Stopped handling OLT Indication Channel")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700465}
466
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100467// processNniPacketIns handles messages received over the NNI interface
468func (o *OltDevice) processNniPacketIns(stream openolt.Openolt_EnableIndicationServer, wg *sync.WaitGroup) {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700469 oltLogger.WithFields(log.Fields{
470 "nniChannel": o.nniPktInChannel,
471 }).Debug("Started NNI Channel")
472 nniId := o.Nnis[0].ID // FIXME we are assuming we have only one NNI
473 for message := range o.nniPktInChannel {
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700474 oltLogger.Tracef("Received packets on NNI Channel")
475
476 onuMac, err := packetHandlers.GetDstMacAddressFromPacket(message.Pkt)
477
478 if err != nil {
479 log.WithFields(log.Fields{
480 "IntfType": "nni",
481 "IntfId": nniId,
482 "Pkt": message.Pkt.Data(),
Matteo Scandolo27428702019-10-11 16:21:16 -0700483 }).Error("Can't find Dst MacAddress in packet")
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700484 return
485 }
486
487 onu, err := o.FindOnuByMacAddress(onuMac)
488 if err != nil {
489 log.WithFields(log.Fields{
490 "IntfType": "nni",
491 "IntfId": nniId,
492 "Pkt": message.Pkt.Data(),
493 "MacAddress": onuMac.String(),
Matteo Scandolo27428702019-10-11 16:21:16 -0700494 }).Error("Can't find ONU with MacAddress")
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700495 return
496 }
497
498 doubleTaggedPkt, err := packetHandlers.PushDoubleTag(onu.STag, onu.CTag, message.Pkt)
499 if err != nil {
500 log.Error("Fail to add double tag to packet")
501 }
502
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700503 data := &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{
504 IntfType: "nni",
505 IntfId: nniId,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700506 Pkt: doubleTaggedPkt.Data()}}
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700507 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
508 oltLogger.WithFields(log.Fields{
509 "IntfType": data.PktInd.IntfType,
510 "IntfId": nniId,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700511 "Pkt": doubleTaggedPkt.Data(),
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700512 }).Errorf("Fail to send PktInd indication: %v", err)
513 }
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700514 oltLogger.WithFields(log.Fields{
515 "IntfType": data.PktInd.IntfType,
516 "IntfId": nniId,
517 "Pkt": doubleTaggedPkt.Data(),
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700518 "OnuSn": onu.Sn(),
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700519 }).Tracef("Sent PktInd indication")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700520 }
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100521 wg.Done()
522 oltLogger.WithFields(log.Fields{
523 "nniChannel": o.nniPktInChannel,
524 }).Warn("Stopped handling NNI Channel")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700525}
526
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700527// returns an ONU with a given Serial Number
528func (o OltDevice) FindOnuBySn(serialNumber string) (*Onu, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +0200529 // TODO this function can be a performance bottleneck when we have many ONUs,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700530 // memoizing it will remove the bottleneck
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700531 for _, pon := range o.Pons {
532 for _, onu := range pon.Onus {
533 if onu.Sn() == serialNumber {
Matteo Scandolo27428702019-10-11 16:21:16 -0700534 return onu, nil
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700535 }
536 }
537 }
538
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700539 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-serial-number-%s", serialNumber))
540}
541
William Kurkian9dadc5b2019-10-22 13:51:57 -0400542// returns an ONU with a given interface/Onu Id
543func (o OltDevice) FindOnuById(intfId uint32, onuId uint32) (*Onu, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +0200544 // TODO this function can be a performance bottleneck when we have many ONUs,
William Kurkian9dadc5b2019-10-22 13:51:57 -0400545 // memoizing it will remove the bottleneck
546 for _, pon := range o.Pons {
547 if pon.ID == intfId {
548 for _, onu := range pon.Onus {
549 if onu.ID == onuId {
550 return onu, nil
551 }
552 }
553 }
554 }
555 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-id-%v-%v", intfId, onuId))
556}
557
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700558// returns an ONU with a given Mac Address
559func (o OltDevice) FindOnuByMacAddress(mac net.HardwareAddr) (*Onu, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +0200560 // TODO this function can be a performance bottleneck when we have many ONUs,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700561 // memoizing it will remove the bottleneck
562 for _, pon := range o.Pons {
563 for _, onu := range pon.Onus {
564 if onu.HwAddress.String() == mac.String() {
Matteo Scandolo27428702019-10-11 16:21:16 -0700565 return onu, nil
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700566 }
567 }
568 }
569
570 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-mac-address-%s", mac))
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700571}
572
Matteo Scandolo4747d292019-08-05 11:50:18 -0700573// GRPC Endpoints
574
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700575func (o OltDevice) ActivateOnu(context context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700576 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700577 "OnuSn": onuSnToString(onu.SerialNumber),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700578 }).Info("Received ActivateOnu call from VOLTHA")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700579
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700580 pon, _ := o.GetPonById(onu.IntfId)
581 _onu, _ := pon.GetOnuBySn(onu.SerialNumber)
William Kurkian0418bc82019-11-06 12:16:24 -0500582 _onu.SetID(onu.OnuId)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700583
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700584 if err := _onu.OperState.Event("enable"); err != nil {
585 oltLogger.WithFields(log.Fields{
586 "IntfId": _onu.PonPortID,
587 "OnuSn": _onu.Sn(),
588 "OnuId": _onu.ID,
589 }).Infof("Failed to transition ONU.OperState to enabled state: %s", err.Error())
Matteo Scandolo4747d292019-08-05 11:50:18 -0700590 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700591 if err := _onu.InternalState.Event("enable"); err != nil {
592 oltLogger.WithFields(log.Fields{
593 "IntfId": _onu.PonPortID,
594 "OnuSn": _onu.Sn(),
595 "OnuId": _onu.ID,
596 }).Infof("Failed to transition ONU to enabled state: %s", err.Error())
597 }
598
599 // NOTE we need to immediately activate the ONU or the OMCI state machine won't start
600
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700601 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700602}
603
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700604func (o OltDevice) DeactivateOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700605 oltLogger.Error("DeactivateOnu not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700606 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700607}
608
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700609func (o OltDevice) DeleteOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700610 oltLogger.Error("DeleteOnu not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700611 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700612}
613
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700614func (o OltDevice) DisableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700615 // NOTE when we disable the OLT should we disable NNI, PONs and ONUs altogether?
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100616 oltMsg := Message{
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700617 Type: OltIndication,
618 Data: OltIndicationMessage{
619 OperState: DOWN,
620 },
621 }
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100622 o.channel <- oltMsg
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700623 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700624}
625
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700626func (o OltDevice) DisablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700627 oltLogger.Error("DisablePonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700628 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700629}
630
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100631func (o *OltDevice) EnableIndication(_ *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700632 oltLogger.WithField("oltId", o.ID).Info("OLT receives EnableIndication call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700633 o.Enable(stream)
634 return nil
635}
636
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700637func (o OltDevice) EnablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700638 oltLogger.Error("EnablePonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700639 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700640}
641
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700642func (o OltDevice) FlowAdd(ctx context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700643 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700644 "IntfId": flow.AccessIntfId,
645 "OnuId": flow.OnuId,
646 "EthType": fmt.Sprintf("%x", flow.Classifier.EthType),
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700647 "InnerVlan": flow.Classifier.IVid,
648 "OuterVlan": flow.Classifier.OVid,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700649 "FlowType": flow.FlowType,
650 "FlowId": flow.FlowId,
651 "UniID": flow.UniId,
652 "PortNo": flow.PortNo,
653 }).Tracef("OLT receives Flow")
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700654 // TODO optionally store flows somewhere
655
656 if flow.AccessIntfId == -1 {
657 oltLogger.WithFields(log.Fields{
658 "FlowId": flow.FlowId,
659 }).Debugf("This is an OLT flow")
660 } else {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700661 pon, err := o.GetPonById(uint32(flow.AccessIntfId))
Matteo Scandolo27428702019-10-11 16:21:16 -0700662 if err != nil {
663 oltLogger.WithFields(log.Fields{
664 "OnuId": flow.OnuId,
665 "IntfId": flow.AccessIntfId,
666 "err": err,
667 }).Error("Can't find PonPort")
668 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700669 onu, err := pon.GetOnuById(uint32(flow.OnuId))
Matteo Scandolo27428702019-10-11 16:21:16 -0700670 if err != nil {
671 oltLogger.WithFields(log.Fields{
672 "OnuId": flow.OnuId,
673 "IntfId": flow.AccessIntfId,
674 "err": err,
675 }).Error("Can't find Onu")
676 }
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700677
678 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700679 Type: FlowUpdate,
680 Data: OnuFlowUpdateMessage{
681 PonPortID: pon.ID,
682 OnuID: onu.ID,
683 Flow: flow,
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700684 },
685 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700686 onu.Channel <- msg
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700687 }
688
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700689 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700690}
691
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700692func (o OltDevice) FlowRemove(context.Context, *openolt.Flow) (*openolt.Empty, error) {
693 oltLogger.Tracef("received FlowRemove")
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700694 // TODO store flows somewhere
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700695 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700696}
697
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700698func (o OltDevice) HeartbeatCheck(context.Context, *openolt.Empty) (*openolt.Heartbeat, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700699 oltLogger.Error("HeartbeatCheck not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700700 return new(openolt.Heartbeat), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700701}
702
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700703func (o OltDevice) GetDeviceInfo(context.Context, *openolt.Empty) (*openolt.DeviceInfo, error) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700704
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700705 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700706 "oltId": o.ID,
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700707 "PonPorts": o.NumPon,
708 }).Info("OLT receives GetDeviceInfo call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700709 devinfo := new(openolt.DeviceInfo)
710 devinfo.Vendor = "BBSim"
711 devinfo.Model = "asfvolt16"
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700712 devinfo.HardwareVersion = "emulated"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700713 devinfo.FirmwareVersion = ""
714 devinfo.Technology = "xgspon"
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700715 devinfo.PonPorts = uint32(o.NumPon)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700716 devinfo.OnuIdStart = 1
717 devinfo.OnuIdEnd = 255
718 devinfo.AllocIdStart = 1024
719 devinfo.AllocIdEnd = 16383
720 devinfo.GemportIdStart = 1024
721 devinfo.GemportIdEnd = 65535
722 devinfo.FlowIdStart = 1
723 devinfo.FlowIdEnd = 16383
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700724 devinfo.DeviceSerialNumber = o.SerialNumber
Matteo Scandolo3f5d7f22019-10-16 14:21:13 -0700725 devinfo.DeviceId = net.HardwareAddr{0xA, 0xA, 0xA, 0xA, 0xA, byte(o.ID)}.String()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700726
727 return devinfo, nil
728}
729
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700730func (o OltDevice) OmciMsgOut(ctx context.Context, omci_msg *openolt.OmciMsg) (*openolt.Empty, error) {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700731 pon, _ := o.GetPonById(omci_msg.IntfId)
732 onu, _ := pon.GetOnuById(omci_msg.OnuId)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700733 oltLogger.WithFields(log.Fields{
734 "IntfId": onu.PonPortID,
735 "OnuId": onu.ID,
736 "OnuSn": onu.Sn(),
737 }).Tracef("Received OmciMsgOut")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700738 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700739 Type: OMCI,
740 Data: OmciMessage{
741 OnuSN: onu.SerialNumber,
742 OnuID: onu.ID,
743 omciMsg: omci_msg,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700744 },
745 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700746 onu.Channel <- msg
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700747 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700748}
749
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700750func (o OltDevice) OnuPacketOut(ctx context.Context, onuPkt *openolt.OnuPacket) (*openolt.Empty, error) {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700751 pon, err := o.GetPonById(onuPkt.IntfId)
Matteo Scandolo27428702019-10-11 16:21:16 -0700752 if err != nil {
753 oltLogger.WithFields(log.Fields{
754 "OnuId": onuPkt.OnuId,
755 "IntfId": onuPkt.IntfId,
756 "err": err,
757 }).Error("Can't find PonPort")
758 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700759 onu, err := pon.GetOnuById(onuPkt.OnuId)
Matteo Scandolo27428702019-10-11 16:21:16 -0700760 if err != nil {
761 oltLogger.WithFields(log.Fields{
762 "OnuId": onuPkt.OnuId,
763 "IntfId": onuPkt.IntfId,
764 "err": err,
765 }).Error("Can't find Onu")
766 }
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700767
Matteo Scandolo075b1892019-10-07 12:11:07 -0700768 oltLogger.WithFields(log.Fields{
769 "IntfId": onu.PonPortID,
770 "OnuId": onu.ID,
771 "OnuSn": onu.Sn(),
772 }).Tracef("Received OnuPacketOut")
773
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700774 rawpkt := gopacket.NewPacket(onuPkt.Pkt, layers.LayerTypeEthernet, gopacket.Default)
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700775 pktType, err := packetHandlers.IsEapolOrDhcp(rawpkt)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700776
Matteo Scandolo075b1892019-10-07 12:11:07 -0700777 msg := Message{
778 Type: OnuPacketOut,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700779 Data: OnuPacketMessage{
Matteo Scandolo075b1892019-10-07 12:11:07 -0700780 IntfId: onuPkt.IntfId,
781 OnuId: onuPkt.OnuId,
782 Packet: rawpkt,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700783 Type: pktType,
Matteo Scandolo075b1892019-10-07 12:11:07 -0700784 },
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700785 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700786 onu.Channel <- msg
787
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700788 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700789}
790
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700791func (o OltDevice) Reboot(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100792 oltLogger.Info("Shutting down")
793 o.RestartOLT()
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700794 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700795}
796
797func (o OltDevice) ReenableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700798 oltLogger.Error("ReenableOlt not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700799 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700800}
801
802func (o OltDevice) UplinkPacketOut(context context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700803 pkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
804
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100805 o.Nnis[0].sendNniPacket(pkt) // FIXME we are assuming we have only one NNI
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700806 // NOTE should we return an error if sendNniPakcet fails?
807 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700808}
809
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700810func (o OltDevice) CollectStatistics(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700811 oltLogger.Error("CollectStatistics not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700812 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700813}
814
Matteo Scandolo4747d292019-08-05 11:50:18 -0700815func (o OltDevice) GetOnuInfo(context context.Context, packet *openolt.Onu) (*openolt.OnuIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700816 oltLogger.Error("GetOnuInfo not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700817 return new(openolt.OnuIndication), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700818}
819
820func (o OltDevice) GetPonIf(context context.Context, packet *openolt.Interface) (*openolt.IntfIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700821 oltLogger.Error("GetPonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700822 return new(openolt.IntfIndication), nil
Matteo Scandolod54283a2019-08-13 16:22:31 -0700823}
824
825func (s OltDevice) CreateTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700826 oltLogger.Info("received CreateTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700827 return new(openolt.Empty), nil
828}
829
830func (s OltDevice) RemoveTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700831 oltLogger.Info("received RemoveTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700832 return new(openolt.Empty), nil
833}
834
835func (s OltDevice) CreateTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700836 oltLogger.Info("received CreateTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700837 return new(openolt.Empty), nil
838}
839
840func (s OltDevice) RemoveTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700841 oltLogger.Info("received RemoveTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700842 return new(openolt.Empty), nil
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700843}