blob: 64848963abc80e0dfcd5930360eafb203b09fae4 [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"
25
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070026 "github.com/google/gopacket"
27 "github.com/google/gopacket/layers"
Matteo Scandolo4747d292019-08-05 11:50:18 -070028 "github.com/looplab/fsm"
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -070029 "github.com/opencord/bbsim/internal/bbsim/packetHandlers"
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070030 bbsim "github.com/opencord/bbsim/internal/bbsim/types"
William Kurkian9dadc5b2019-10-22 13:51:57 -040031 omcisim "github.com/opencord/omci-sim"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070032 "github.com/opencord/voltha-protos/go/openolt"
Matteo Scandolod54283a2019-08-13 16:22:31 -070033 "github.com/opencord/voltha-protos/go/tech_profile"
Matteo Scandolo4747d292019-08-05 11:50:18 -070034 log "github.com/sirupsen/logrus"
35 "google.golang.org/grpc"
Matteo Scandolo4747d292019-08-05 11:50:18 -070036)
37
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070038var oltLogger = log.WithFields(log.Fields{
Matteo Scandolo84f7d482019-08-08 19:00:47 -070039 "module": "OLT",
40})
41
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070042type OltDevice struct {
43 // BBSIM Internals
44 ID int
45 SerialNumber string
46 NumNni int
47 NumPon int
48 NumOnuPerPon int
49 InternalState *fsm.FSM
50 channel chan Message
51 oltDoneChannel *chan bool
52 apiDoneChannel *chan bool
53 nniPktInChannel chan *bbsim.PacketMsg
54
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
Matteo Scandolo84f7d482019-08-08 19:00:47 -070065
Matteo Scandolo27428702019-10-11 16:21:16 -070066func GetOLT() *OltDevice {
67 return &olt
Matteo Scandolo84f7d482019-08-08 19:00:47 -070068}
69
Matteo Scandoloe33447a2019-10-31 12:38:23 -070070func CreateOLT(oltId int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, oltDoneChannel *chan bool, apiDoneChannel *chan bool, auth bool, dhcp bool, delay int, isMock bool) *OltDevice {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070071 oltLogger.WithFields(log.Fields{
Matteo Scandolo40e067f2019-10-16 16:59:41 -070072 "ID": oltId,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070073 "NumNni": nni,
74 "NumPon": pon,
75 "NumOnuPerPon": onuPerPon,
Matteo Scandolo4747d292019-08-05 11:50:18 -070076 }).Debug("CreateOLT")
77
Matteo Scandolo84f7d482019-08-08 19:00:47 -070078 olt = OltDevice{
Matteo Scandolo40e067f2019-10-16 16:59:41 -070079 ID: oltId,
80 SerialNumber: fmt.Sprintf("BBSIM_OLT_%d", oltId),
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070081 OperState: getOperStateFSM(func(e *fsm.Event) {
82 oltLogger.Debugf("Changing OLT OperState from %s to %s", e.Src, e.Dst)
83 }),
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070084 NumNni: nni,
85 NumPon: pon,
86 NumOnuPerPon: onuPerPon,
Matteo Scandolo27428702019-10-11 16:21:16 -070087 Pons: []*PonPort{},
88 Nnis: []*NniPort{},
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070089 channel: make(chan Message),
90 oltDoneChannel: oltDoneChannel,
91 apiDoneChannel: apiDoneChannel,
92 nniPktInChannel: make(chan *bbsim.PacketMsg, 1024), // packets coming in from the NNI and going to VOLTHA
Matteo Scandoloe33447a2019-10-31 12:38:23 -070093 Delay: delay,
Matteo Scandolo4747d292019-08-05 11:50:18 -070094 }
95
96 // OLT State machine
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070097 // NOTE do we need 2 state machines for the OLT? (InternalState and OperState)
Matteo Scandolo4747d292019-08-05 11:50:18 -070098 olt.InternalState = fsm.NewFSM(
99 "created",
100 fsm.Events{
101 {Name: "enable", Src: []string{"created"}, Dst: "enabled"},
102 {Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
103 },
104 fsm.Callbacks{
105 "enter_state": func(e *fsm.Event) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700106 oltLogger.Debugf("Changing OLT InternalState from %s to %s", e.Src, e.Dst)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700107 },
108 },
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 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700146 return &olt
147}
Matteo Scandolo4747d292019-08-05 11:50:18 -0700148
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700149// this function start the OLT gRPC server and blocks until it's done
150func StartOlt(olt *OltDevice, group *sync.WaitGroup) {
151 newOltServer(*olt)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700152 group.Done()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700153}
154
155func newOltServer(o OltDevice) error {
156 // TODO make configurable
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700157 address := "0.0.0.0:50060"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700158 lis, err := net.Listen("tcp", address)
159 if err != nil {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700160 oltLogger.Fatalf("OLT failed to listen: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700161 }
162 grpcServer := grpc.NewServer()
163 openolt.RegisterOpenoltServer(grpcServer, o)
164
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700165 wg := sync.WaitGroup{}
166 wg.Add(1)
167
Matteo Scandolo4747d292019-08-05 11:50:18 -0700168 go grpcServer.Serve(lis)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700169 oltLogger.Debugf("OLT Listening on: %v", address)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700170
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700171 for {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700172 _, ok := <-*o.oltDoneChannel
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700173 if !ok {
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700174 // if the olt Channel is closed, stop the gRPC server
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700175 log.Warnf("Stopping OLT gRPC server")
176 grpcServer.Stop()
177 wg.Done()
178 break
179 }
180 }
181
182 wg.Wait()
183
Matteo Scandolo4747d292019-08-05 11:50:18 -0700184 return nil
185}
186
187// Device Methods
188
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700189func (o OltDevice) Enable(stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700190
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700191 oltLogger.Debug("Enable OLT called")
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700192
Matteo Scandolo4747d292019-08-05 11:50:18 -0700193 wg := sync.WaitGroup{}
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700194 wg.Add(2)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700195
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700196 // create a Channel for all the OLT events
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700197 go o.processOltMessages(stream)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700198 go o.processNniPacketIns(stream)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700199
200 // enable the OLT
201 olt_msg := Message{
202 Type: OltIndication,
203 Data: OltIndicationMessage{
204 OperState: UP,
205 },
206 }
207 o.channel <- olt_msg
208
209 // send NNI Port Indications
210 for _, nni := range o.Nnis {
211 msg := Message{
212 Type: NniIndication,
213 Data: NniIndicationMessage{
214 OperState: UP,
215 NniPortID: nni.ID,
216 },
217 }
218 o.channel <- msg
219 }
William Kurkian9dadc5b2019-10-22 13:51:57 -0400220 go o.processOmciMessages()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700221 // send PON Port indications
222 for _, pon := range o.Pons {
223 msg := Message{
224 Type: PonIndication,
225 Data: PonIndicationMessage{
226 OperState: UP,
227 PonPortID: pon.ID,
228 },
229 }
230 o.channel <- msg
231
232 for _, onu := range pon.Onus {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700233 go onu.ProcessOnuMessages(stream, nil)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700234 // FIXME move the message generation in the state transition
235 // from here only invoke the state transition
Matteo Scandolo4747d292019-08-05 11:50:18 -0700236 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700237 Type: OnuDiscIndication,
Matteo Scandolo4747d292019-08-05 11:50:18 -0700238 Data: OnuDiscIndicationMessage{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700239 Onu: onu,
Matteo Scandolo4747d292019-08-05 11:50:18 -0700240 OperState: UP,
241 },
242 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700243 onu.Channel <- msg
Matteo Scandolo4747d292019-08-05 11:50:18 -0700244 }
245 }
246
247 wg.Wait()
248 return nil
249}
250
William Kurkian9dadc5b2019-10-22 13:51:57 -0400251func (o OltDevice) processOmciMessages() {
252 ch := omcisim.GetChannel()
253
254 oltLogger.Debug("Started OMCI Indication Channel")
255
256 for message := range ch {
257 onuId := message.Data.OnuId
258 intfId := message.Data.IntfId
259 onu, err := o.FindOnuById(intfId, onuId)
260 if err != nil {
261 oltLogger.Errorf("Failed to find onu: %v", err)
262 }
263 go onu.processOmciMessage(message)
264 }
265}
266
Matteo Scandolo4747d292019-08-05 11:50:18 -0700267// Helpers method
268
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700269func (o OltDevice) GetPonById(id uint32) (*PonPort, error) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700270 for _, pon := range o.Pons {
271 if pon.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700272 return pon, nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700273 }
274 }
275 return nil, errors.New(fmt.Sprintf("Cannot find PonPort with id %d in OLT %d", id, o.ID))
276}
277
278func (o OltDevice) getNniById(id uint32) (*NniPort, error) {
279 for _, nni := range o.Nnis {
280 if nni.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700281 return nni, nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700282 }
283 }
284 return nil, errors.New(fmt.Sprintf("Cannot find NniPort with id %d in OLT %d", id, o.ID))
285}
286
Matteo Scandolo4747d292019-08-05 11:50:18 -0700287func (o OltDevice) sendOltIndication(msg OltIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
288 data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: msg.OperState.String()}}
289 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700290 oltLogger.Errorf("Failed to send Indication_OltInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700291 }
292
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700293 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700294 "OperState": msg.OperState,
295 }).Debug("Sent Indication_OltInd")
296}
297
298func (o OltDevice) sendNniIndication(msg NniIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
299 nni, _ := o.getNniById(msg.NniPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700300 nni.OperState.Event("enable")
301 // NOTE Operstate may need to be an integer
Matteo Scandolo4747d292019-08-05 11:50:18 -0700302 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700303 Type: nni.Type,
304 IntfId: nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700305 OperState: nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700306 }}
307
308 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700309 oltLogger.Errorf("Failed to send Indication_IntfOperInd for NNI: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700310 }
311
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700312 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700313 "Type": nni.Type,
314 "IntfId": nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700315 "OperState": nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700316 }).Debug("Sent Indication_IntfOperInd for NNI")
317}
318
319func (o OltDevice) sendPonIndication(msg PonIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700320 pon, _ := o.GetPonById(msg.PonPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700321 pon.OperState.Event("enable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700322 discoverData := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700323 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700324 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700325 }}
326
327 if err := stream.Send(&openolt.Indication{Data: discoverData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700328 oltLogger.Errorf("Failed to send Indication_IntfInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700329 }
330
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700331 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700332 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700333 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700334 }).Debug("Sent Indication_IntfInd")
335
336 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700337 Type: pon.Type,
338 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700339 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700340 }}
341
342 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700343 oltLogger.Errorf("Failed to send Indication_IntfOperInd for PON: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700344 }
345
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700346 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700347 "Type": pon.Type,
348 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700349 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700350 }).Debug("Sent Indication_IntfOperInd for PON")
351}
352
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700353func (o OltDevice) processOltMessages(stream openolt.Openolt_EnableIndicationServer) {
354 oltLogger.Debug("Started OLT Indication Channel")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700355 for message := range o.channel {
356
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700357 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700358 "oltId": o.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700359 "messageType": message.Type,
360 }).Trace("Received message")
361
362 switch message.Type {
363 case OltIndication:
364 msg, _ := message.Data.(OltIndicationMessage)
365 if msg.OperState == UP {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700366 o.InternalState.Event("enable")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700367 o.OperState.Event("enable")
368 } else if msg.OperState == DOWN {
369 o.InternalState.Event("disable")
370 o.OperState.Event("disable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700371 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700372 o.sendOltIndication(msg, stream)
373 case NniIndication:
374 msg, _ := message.Data.(NniIndicationMessage)
375 o.sendNniIndication(msg, stream)
376 case PonIndication:
377 msg, _ := message.Data.(PonIndicationMessage)
378 o.sendPonIndication(msg, stream)
379 default:
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700380 oltLogger.Warnf("Received unknown message data %v for type %v in OLT Channel", message.Data, message.Type)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700381 }
382
383 }
384}
385
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700386func (o OltDevice) processNniPacketIns(stream openolt.Openolt_EnableIndicationServer) {
387 oltLogger.WithFields(log.Fields{
388 "nniChannel": o.nniPktInChannel,
389 }).Debug("Started NNI Channel")
390 nniId := o.Nnis[0].ID // FIXME we are assuming we have only one NNI
391 for message := range o.nniPktInChannel {
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700392 oltLogger.Tracef("Received packets on NNI Channel")
393
394 onuMac, err := packetHandlers.GetDstMacAddressFromPacket(message.Pkt)
395
396 if err != nil {
397 log.WithFields(log.Fields{
398 "IntfType": "nni",
399 "IntfId": nniId,
400 "Pkt": message.Pkt.Data(),
Matteo Scandolo27428702019-10-11 16:21:16 -0700401 }).Error("Can't find Dst MacAddress in packet")
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700402 return
403 }
404
405 onu, err := o.FindOnuByMacAddress(onuMac)
406 if err != nil {
407 log.WithFields(log.Fields{
408 "IntfType": "nni",
409 "IntfId": nniId,
410 "Pkt": message.Pkt.Data(),
411 "MacAddress": onuMac.String(),
Matteo Scandolo27428702019-10-11 16:21:16 -0700412 }).Error("Can't find ONU with MacAddress")
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700413 return
414 }
415
416 doubleTaggedPkt, err := packetHandlers.PushDoubleTag(onu.STag, onu.CTag, message.Pkt)
417 if err != nil {
418 log.Error("Fail to add double tag to packet")
419 }
420
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700421 data := &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{
422 IntfType: "nni",
423 IntfId: nniId,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700424 Pkt: doubleTaggedPkt.Data()}}
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700425 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
426 oltLogger.WithFields(log.Fields{
427 "IntfType": data.PktInd.IntfType,
428 "IntfId": nniId,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700429 "Pkt": doubleTaggedPkt.Data(),
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700430 }).Errorf("Fail to send PktInd indication: %v", err)
431 }
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700432 oltLogger.WithFields(log.Fields{
433 "IntfType": data.PktInd.IntfType,
434 "IntfId": nniId,
435 "Pkt": doubleTaggedPkt.Data(),
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700436 "OnuSn": onu.Sn(),
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700437 }).Tracef("Sent PktInd indication")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700438 }
439}
440
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700441// returns an ONU with a given Serial Number
442func (o OltDevice) FindOnuBySn(serialNumber string) (*Onu, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +0200443 // TODO this function can be a performance bottleneck when we have many ONUs,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700444 // memoizing it will remove the bottleneck
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700445 for _, pon := range o.Pons {
446 for _, onu := range pon.Onus {
447 if onu.Sn() == serialNumber {
Matteo Scandolo27428702019-10-11 16:21:16 -0700448 return onu, nil
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700449 }
450 }
451 }
452
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700453 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-serial-number-%s", serialNumber))
454}
455
William Kurkian9dadc5b2019-10-22 13:51:57 -0400456// returns an ONU with a given interface/Onu Id
457func (o OltDevice) FindOnuById(intfId uint32, onuId uint32) (*Onu, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +0200458 // TODO this function can be a performance bottleneck when we have many ONUs,
William Kurkian9dadc5b2019-10-22 13:51:57 -0400459 // memoizing it will remove the bottleneck
460 for _, pon := range o.Pons {
461 if pon.ID == intfId {
462 for _, onu := range pon.Onus {
463 if onu.ID == onuId {
464 return onu, nil
465 }
466 }
467 }
468 }
469 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-id-%v-%v", intfId, onuId))
470}
471
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700472// returns an ONU with a given Mac Address
473func (o OltDevice) FindOnuByMacAddress(mac net.HardwareAddr) (*Onu, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +0200474 // TODO this function can be a performance bottleneck when we have many ONUs,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700475 // memoizing it will remove the bottleneck
476 for _, pon := range o.Pons {
477 for _, onu := range pon.Onus {
478 if onu.HwAddress.String() == mac.String() {
Matteo Scandolo27428702019-10-11 16:21:16 -0700479 return onu, nil
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700480 }
481 }
482 }
483
484 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-mac-address-%s", mac))
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700485}
486
Matteo Scandolo4747d292019-08-05 11:50:18 -0700487// GRPC Endpoints
488
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700489func (o OltDevice) ActivateOnu(context context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700490 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700491 "OnuSn": onuSnToString(onu.SerialNumber),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700492 }).Info("Received ActivateOnu call from VOLTHA")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700493
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700494 pon, _ := o.GetPonById(onu.IntfId)
495 _onu, _ := pon.GetOnuBySn(onu.SerialNumber)
William Kurkian0418bc82019-11-06 12:16:24 -0500496 _onu.SetID(onu.OnuId)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700497
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700498 if err := _onu.OperState.Event("enable"); err != nil {
499 oltLogger.WithFields(log.Fields{
500 "IntfId": _onu.PonPortID,
501 "OnuSn": _onu.Sn(),
502 "OnuId": _onu.ID,
503 }).Infof("Failed to transition ONU.OperState to enabled state: %s", err.Error())
Matteo Scandolo4747d292019-08-05 11:50:18 -0700504 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700505 if err := _onu.InternalState.Event("enable"); err != nil {
506 oltLogger.WithFields(log.Fields{
507 "IntfId": _onu.PonPortID,
508 "OnuSn": _onu.Sn(),
509 "OnuId": _onu.ID,
510 }).Infof("Failed to transition ONU to enabled state: %s", err.Error())
511 }
512
513 // NOTE we need to immediately activate the ONU or the OMCI state machine won't start
514
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700515 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700516}
517
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700518func (o OltDevice) DeactivateOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700519 oltLogger.Error("DeactivateOnu not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700520 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700521}
522
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700523func (o OltDevice) DeleteOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700524 oltLogger.Error("DeleteOnu not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700525 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700526}
527
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700528func (o OltDevice) DisableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700529 // NOTE when we disable the OLT should we disable NNI, PONs and ONUs altogether?
530 olt_msg := Message{
531 Type: OltIndication,
532 Data: OltIndicationMessage{
533 OperState: DOWN,
534 },
535 }
536 o.channel <- olt_msg
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700537 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700538}
539
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700540func (o OltDevice) DisablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700541 oltLogger.Error("DisablePonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700542 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700543}
544
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700545func (o OltDevice) EnableIndication(_ *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700546 oltLogger.WithField("oltId", o.ID).Info("OLT receives EnableIndication call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700547 o.Enable(stream)
548 return nil
549}
550
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700551func (o OltDevice) EnablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700552 oltLogger.Error("EnablePonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700553 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700554}
555
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700556func (o OltDevice) FlowAdd(ctx context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700557 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700558 "IntfId": flow.AccessIntfId,
559 "OnuId": flow.OnuId,
560 "EthType": fmt.Sprintf("%x", flow.Classifier.EthType),
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700561 "InnerVlan": flow.Classifier.IVid,
562 "OuterVlan": flow.Classifier.OVid,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700563 "FlowType": flow.FlowType,
564 "FlowId": flow.FlowId,
565 "UniID": flow.UniId,
566 "PortNo": flow.PortNo,
567 }).Tracef("OLT receives Flow")
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700568 // TODO optionally store flows somewhere
569
570 if flow.AccessIntfId == -1 {
571 oltLogger.WithFields(log.Fields{
572 "FlowId": flow.FlowId,
573 }).Debugf("This is an OLT flow")
574 } else {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700575 pon, err := o.GetPonById(uint32(flow.AccessIntfId))
Matteo Scandolo27428702019-10-11 16:21:16 -0700576 if err != nil {
577 oltLogger.WithFields(log.Fields{
578 "OnuId": flow.OnuId,
579 "IntfId": flow.AccessIntfId,
580 "err": err,
581 }).Error("Can't find PonPort")
582 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700583 onu, err := pon.GetOnuById(uint32(flow.OnuId))
Matteo Scandolo27428702019-10-11 16:21:16 -0700584 if err != nil {
585 oltLogger.WithFields(log.Fields{
586 "OnuId": flow.OnuId,
587 "IntfId": flow.AccessIntfId,
588 "err": err,
589 }).Error("Can't find Onu")
590 }
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700591
592 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700593 Type: FlowUpdate,
594 Data: OnuFlowUpdateMessage{
595 PonPortID: pon.ID,
596 OnuID: onu.ID,
597 Flow: flow,
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700598 },
599 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700600 onu.Channel <- msg
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700601 }
602
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700603 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700604}
605
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700606func (o OltDevice) FlowRemove(context.Context, *openolt.Flow) (*openolt.Empty, error) {
607 oltLogger.Tracef("received FlowRemove")
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700608 // TODO store flows somewhere
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700609 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700610}
611
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700612func (o OltDevice) HeartbeatCheck(context.Context, *openolt.Empty) (*openolt.Heartbeat, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700613 oltLogger.Error("HeartbeatCheck not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700614 return new(openolt.Heartbeat), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700615}
616
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700617func (o OltDevice) GetDeviceInfo(context.Context, *openolt.Empty) (*openolt.DeviceInfo, error) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700618
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700619 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700620 "oltId": o.ID,
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700621 "PonPorts": o.NumPon,
622 }).Info("OLT receives GetDeviceInfo call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700623 devinfo := new(openolt.DeviceInfo)
624 devinfo.Vendor = "BBSim"
625 devinfo.Model = "asfvolt16"
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700626 devinfo.HardwareVersion = "emulated"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700627 devinfo.FirmwareVersion = ""
628 devinfo.Technology = "xgspon"
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700629 devinfo.PonPorts = uint32(o.NumPon)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700630 devinfo.OnuIdStart = 1
631 devinfo.OnuIdEnd = 255
632 devinfo.AllocIdStart = 1024
633 devinfo.AllocIdEnd = 16383
634 devinfo.GemportIdStart = 1024
635 devinfo.GemportIdEnd = 65535
636 devinfo.FlowIdStart = 1
637 devinfo.FlowIdEnd = 16383
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700638 devinfo.DeviceSerialNumber = o.SerialNumber
Matteo Scandolo3f5d7f22019-10-16 14:21:13 -0700639 devinfo.DeviceId = net.HardwareAddr{0xA, 0xA, 0xA, 0xA, 0xA, byte(o.ID)}.String()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700640
641 return devinfo, nil
642}
643
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700644func (o OltDevice) OmciMsgOut(ctx context.Context, omci_msg *openolt.OmciMsg) (*openolt.Empty, error) {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700645 pon, _ := o.GetPonById(omci_msg.IntfId)
646 onu, _ := pon.GetOnuById(omci_msg.OnuId)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700647 oltLogger.WithFields(log.Fields{
648 "IntfId": onu.PonPortID,
649 "OnuId": onu.ID,
650 "OnuSn": onu.Sn(),
651 }).Tracef("Received OmciMsgOut")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700652 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700653 Type: OMCI,
654 Data: OmciMessage{
655 OnuSN: onu.SerialNumber,
656 OnuID: onu.ID,
657 omciMsg: omci_msg,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700658 },
659 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700660 onu.Channel <- msg
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700661 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700662}
663
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700664func (o OltDevice) OnuPacketOut(ctx context.Context, onuPkt *openolt.OnuPacket) (*openolt.Empty, error) {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700665 pon, err := o.GetPonById(onuPkt.IntfId)
Matteo Scandolo27428702019-10-11 16:21:16 -0700666 if err != nil {
667 oltLogger.WithFields(log.Fields{
668 "OnuId": onuPkt.OnuId,
669 "IntfId": onuPkt.IntfId,
670 "err": err,
671 }).Error("Can't find PonPort")
672 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700673 onu, err := pon.GetOnuById(onuPkt.OnuId)
Matteo Scandolo27428702019-10-11 16:21:16 -0700674 if err != nil {
675 oltLogger.WithFields(log.Fields{
676 "OnuId": onuPkt.OnuId,
677 "IntfId": onuPkt.IntfId,
678 "err": err,
679 }).Error("Can't find Onu")
680 }
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700681
Matteo Scandolo075b1892019-10-07 12:11:07 -0700682 oltLogger.WithFields(log.Fields{
683 "IntfId": onu.PonPortID,
684 "OnuId": onu.ID,
685 "OnuSn": onu.Sn(),
686 }).Tracef("Received OnuPacketOut")
687
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700688 rawpkt := gopacket.NewPacket(onuPkt.Pkt, layers.LayerTypeEthernet, gopacket.Default)
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700689 pktType, err := packetHandlers.IsEapolOrDhcp(rawpkt)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700690
Matteo Scandolo075b1892019-10-07 12:11:07 -0700691 msg := Message{
692 Type: OnuPacketOut,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700693 Data: OnuPacketMessage{
Matteo Scandolo075b1892019-10-07 12:11:07 -0700694 IntfId: onuPkt.IntfId,
695 OnuId: onuPkt.OnuId,
696 Packet: rawpkt,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700697 Type: pktType,
Matteo Scandolo075b1892019-10-07 12:11:07 -0700698 },
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700699 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700700 onu.Channel <- msg
701
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700702 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700703}
704
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700705func (o OltDevice) Reboot(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700706 oltLogger.Info("Shutting Down")
707 close(*o.oltDoneChannel)
708 close(*o.apiDoneChannel)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700709 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700710}
711
712func (o OltDevice) ReenableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700713 oltLogger.Error("ReenableOlt not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700714 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700715}
716
717func (o OltDevice) UplinkPacketOut(context context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700718 pkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
719
720 sendNniPacket(pkt)
721 // NOTE should we return an error if sendNniPakcet fails?
722 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700723}
724
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700725func (o OltDevice) CollectStatistics(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700726 oltLogger.Error("CollectStatistics not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700727 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700728}
729
Matteo Scandolo4747d292019-08-05 11:50:18 -0700730func (o OltDevice) GetOnuInfo(context context.Context, packet *openolt.Onu) (*openolt.OnuIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700731 oltLogger.Error("GetOnuInfo not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700732 return new(openolt.OnuIndication), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700733}
734
735func (o OltDevice) GetPonIf(context context.Context, packet *openolt.Interface) (*openolt.IntfIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700736 oltLogger.Error("GetPonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700737 return new(openolt.IntfIndication), nil
Matteo Scandolod54283a2019-08-13 16:22:31 -0700738}
739
740func (s OltDevice) CreateTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700741 oltLogger.Info("received CreateTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700742 return new(openolt.Empty), nil
743}
744
745func (s OltDevice) RemoveTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700746 oltLogger.Info("received RemoveTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700747 return new(openolt.Empty), nil
748}
749
750func (s OltDevice) CreateTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700751 oltLogger.Info("received CreateTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700752 return new(openolt.Empty), nil
753}
754
755func (s OltDevice) RemoveTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700756 oltLogger.Info("received RemoveTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700757 return new(openolt.Empty), nil
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700758}