blob: 6b15de4004641c1096286a32bdab1b48c282cceb [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 Scandolo27428702019-10-11 16:21:16 -070055 Pons []*PonPort
56 Nnis []*NniPort
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070057
58 // OLT Attributes
59 OperState *fsm.FSM
Matteo Scandolo4747d292019-08-05 11:50:18 -070060}
61
Matteo Scandolo27428702019-10-11 16:21:16 -070062var olt OltDevice
Matteo Scandolo84f7d482019-08-08 19:00:47 -070063
Matteo Scandolo27428702019-10-11 16:21:16 -070064func GetOLT() *OltDevice {
65 return &olt
Matteo Scandolo84f7d482019-08-08 19:00:47 -070066}
67
Matteo Scandoloc1147092019-10-29 09:38:33 -070068func CreateOLT(oltId int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, oltDoneChannel *chan bool, apiDoneChannel *chan bool, auth bool, dhcp bool, isMock bool) *OltDevice {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070069 oltLogger.WithFields(log.Fields{
Matteo Scandolo40e067f2019-10-16 16:59:41 -070070 "ID": oltId,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070071 "NumNni": nni,
72 "NumPon": pon,
73 "NumOnuPerPon": onuPerPon,
Matteo Scandolo4747d292019-08-05 11:50:18 -070074 }).Debug("CreateOLT")
75
Matteo Scandolo84f7d482019-08-08 19:00:47 -070076 olt = OltDevice{
Matteo Scandolo40e067f2019-10-16 16:59:41 -070077 ID: oltId,
78 SerialNumber: fmt.Sprintf("BBSIM_OLT_%d", oltId),
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070079 OperState: getOperStateFSM(func(e *fsm.Event) {
80 oltLogger.Debugf("Changing OLT OperState from %s to %s", e.Src, e.Dst)
81 }),
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070082 NumNni: nni,
83 NumPon: pon,
84 NumOnuPerPon: onuPerPon,
Matteo Scandolo27428702019-10-11 16:21:16 -070085 Pons: []*PonPort{},
86 Nnis: []*NniPort{},
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070087 channel: make(chan Message),
88 oltDoneChannel: oltDoneChannel,
89 apiDoneChannel: apiDoneChannel,
90 nniPktInChannel: make(chan *bbsim.PacketMsg, 1024), // packets coming in from the NNI and going to VOLTHA
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{
98 {Name: "enable", Src: []string{"created"}, Dst: "enabled"},
99 {Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
100 },
101 fsm.Callbacks{
102 "enter_state": func(e *fsm.Event) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700103 oltLogger.Debugf("Changing OLT InternalState from %s to %s", e.Src, e.Dst)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700104 },
105 },
106 )
107
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700108 if isMock != true {
109 // create NNI Port
110 nniPort, err := CreateNNI(&olt)
111 if err != nil {
112 oltLogger.Fatalf("Couldn't create NNI Port: %v", err)
113 }
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700114
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700115 olt.Nnis = append(olt.Nnis, &nniPort)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700116 }
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700117
Matteo Scandolo4747d292019-08-05 11:50:18 -0700118 // create PON ports
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700119 availableCTag := cTagInit
Matteo Scandolo4747d292019-08-05 11:50:18 -0700120 for i := 0; i < pon; i++ {
121 p := PonPort{
122 NumOnu: olt.NumOnuPerPon,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700123 ID: uint32(i),
124 Type: "pon",
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700125 Olt: olt,
Matteo Scandolo27428702019-10-11 16:21:16 -0700126 Onus: []*Onu{},
Matteo Scandolo4747d292019-08-05 11:50:18 -0700127 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700128 p.OperState = getOperStateFSM(func(e *fsm.Event) {
129 oltLogger.WithFields(log.Fields{
130 "ID": p.ID,
131 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
132 })
Matteo Scandolo4747d292019-08-05 11:50:18 -0700133
134 // create ONU devices
135 for j := 0; j < onuPerPon; j++ {
Matteo Scandoloc1147092019-10-29 09:38:33 -0700136 o := CreateONU(olt, p, uint32(j+1), sTag, availableCTag, auth, dhcp)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700137 p.Onus = append(p.Onus, o)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700138 availableCTag = availableCTag + 1
Matteo Scandolo4747d292019-08-05 11:50:18 -0700139 }
140
Matteo Scandolo27428702019-10-11 16:21:16 -0700141 olt.Pons = append(olt.Pons, &p)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700142 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700143 return &olt
144}
Matteo Scandolo4747d292019-08-05 11:50:18 -0700145
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700146// this function start the OLT gRPC server and blocks until it's done
147func StartOlt(olt *OltDevice, group *sync.WaitGroup) {
148 newOltServer(*olt)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700149 group.Done()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700150}
151
152func newOltServer(o OltDevice) error {
153 // TODO make configurable
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700154 address := "0.0.0.0:50060"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700155 lis, err := net.Listen("tcp", address)
156 if err != nil {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700157 oltLogger.Fatalf("OLT failed to listen: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700158 }
159 grpcServer := grpc.NewServer()
160 openolt.RegisterOpenoltServer(grpcServer, o)
161
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700162 wg := sync.WaitGroup{}
163 wg.Add(1)
164
Matteo Scandolo4747d292019-08-05 11:50:18 -0700165 go grpcServer.Serve(lis)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700166 oltLogger.Debugf("OLT Listening on: %v", address)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700167
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700168 for {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700169 _, ok := <-*o.oltDoneChannel
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700170 if !ok {
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700171 // if the olt Channel is closed, stop the gRPC server
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700172 log.Warnf("Stopping OLT gRPC server")
173 grpcServer.Stop()
174 wg.Done()
175 break
176 }
177 }
178
179 wg.Wait()
180
Matteo Scandolo4747d292019-08-05 11:50:18 -0700181 return nil
182}
183
184// Device Methods
185
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700186func (o OltDevice) Enable(stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700187
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700188 oltLogger.Debug("Enable OLT called")
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700189
Matteo Scandolo4747d292019-08-05 11:50:18 -0700190 wg := sync.WaitGroup{}
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700191 wg.Add(2)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700192
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700193 // create a Channel for all the OLT events
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700194 go o.processOltMessages(stream)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700195 go o.processNniPacketIns(stream)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700196
197 // enable the OLT
198 olt_msg := Message{
199 Type: OltIndication,
200 Data: OltIndicationMessage{
201 OperState: UP,
202 },
203 }
204 o.channel <- olt_msg
205
206 // send NNI Port Indications
207 for _, nni := range o.Nnis {
208 msg := Message{
209 Type: NniIndication,
210 Data: NniIndicationMessage{
211 OperState: UP,
212 NniPortID: nni.ID,
213 },
214 }
215 o.channel <- msg
216 }
William Kurkian9dadc5b2019-10-22 13:51:57 -0400217 go o.processOmciMessages()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700218 // send PON Port indications
219 for _, pon := range o.Pons {
220 msg := Message{
221 Type: PonIndication,
222 Data: PonIndicationMessage{
223 OperState: UP,
224 PonPortID: pon.ID,
225 },
226 }
227 o.channel <- msg
228
229 for _, onu := range pon.Onus {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700230 go onu.ProcessOnuMessages(stream, nil)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700231 // FIXME move the message generation in the state transition
232 // from here only invoke the state transition
Matteo Scandolo4747d292019-08-05 11:50:18 -0700233 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700234 Type: OnuDiscIndication,
Matteo Scandolo4747d292019-08-05 11:50:18 -0700235 Data: OnuDiscIndicationMessage{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700236 Onu: onu,
Matteo Scandolo4747d292019-08-05 11:50:18 -0700237 OperState: UP,
238 },
239 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700240 onu.Channel <- msg
Matteo Scandolo4747d292019-08-05 11:50:18 -0700241 }
242 }
243
244 wg.Wait()
245 return nil
246}
247
William Kurkian9dadc5b2019-10-22 13:51:57 -0400248func (o OltDevice) processOmciMessages() {
249 ch := omcisim.GetChannel()
250
251 oltLogger.Debug("Started OMCI Indication Channel")
252
253 for message := range ch {
254 onuId := message.Data.OnuId
255 intfId := message.Data.IntfId
256 onu, err := o.FindOnuById(intfId, onuId)
257 if err != nil {
258 oltLogger.Errorf("Failed to find onu: %v", err)
259 }
260 go onu.processOmciMessage(message)
261 }
262}
263
Matteo Scandolo4747d292019-08-05 11:50:18 -0700264// Helpers method
265
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700266func (o OltDevice) GetPonById(id uint32) (*PonPort, error) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700267 for _, pon := range o.Pons {
268 if pon.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700269 return pon, nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700270 }
271 }
272 return nil, errors.New(fmt.Sprintf("Cannot find PonPort with id %d in OLT %d", id, o.ID))
273}
274
275func (o OltDevice) getNniById(id uint32) (*NniPort, error) {
276 for _, nni := range o.Nnis {
277 if nni.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700278 return nni, nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700279 }
280 }
281 return nil, errors.New(fmt.Sprintf("Cannot find NniPort with id %d in OLT %d", id, o.ID))
282}
283
Matteo Scandolo4747d292019-08-05 11:50:18 -0700284func (o OltDevice) sendOltIndication(msg OltIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
285 data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: msg.OperState.String()}}
286 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700287 oltLogger.Errorf("Failed to send Indication_OltInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700288 }
289
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700290 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700291 "OperState": msg.OperState,
292 }).Debug("Sent Indication_OltInd")
293}
294
295func (o OltDevice) sendNniIndication(msg NniIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
296 nni, _ := o.getNniById(msg.NniPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700297 nni.OperState.Event("enable")
298 // NOTE Operstate may need to be an integer
Matteo Scandolo4747d292019-08-05 11:50:18 -0700299 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700300 Type: nni.Type,
301 IntfId: nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700302 OperState: nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700303 }}
304
305 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700306 oltLogger.Errorf("Failed to send Indication_IntfOperInd for NNI: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700307 }
308
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700309 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700310 "Type": nni.Type,
311 "IntfId": nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700312 "OperState": nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700313 }).Debug("Sent Indication_IntfOperInd for NNI")
314}
315
316func (o OltDevice) sendPonIndication(msg PonIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700317 pon, _ := o.GetPonById(msg.PonPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700318 pon.OperState.Event("enable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700319 discoverData := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700320 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700321 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700322 }}
323
324 if err := stream.Send(&openolt.Indication{Data: discoverData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700325 oltLogger.Errorf("Failed to send Indication_IntfInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700326 }
327
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700328 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700329 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700330 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700331 }).Debug("Sent Indication_IntfInd")
332
333 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700334 Type: pon.Type,
335 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700336 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700337 }}
338
339 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700340 oltLogger.Errorf("Failed to send Indication_IntfOperInd for PON: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700341 }
342
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700343 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700344 "Type": pon.Type,
345 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700346 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700347 }).Debug("Sent Indication_IntfOperInd for PON")
348}
349
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700350func (o OltDevice) processOltMessages(stream openolt.Openolt_EnableIndicationServer) {
351 oltLogger.Debug("Started OLT Indication Channel")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700352 for message := range o.channel {
353
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700354 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700355 "oltId": o.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700356 "messageType": message.Type,
357 }).Trace("Received message")
358
359 switch message.Type {
360 case OltIndication:
361 msg, _ := message.Data.(OltIndicationMessage)
362 if msg.OperState == UP {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700363 o.InternalState.Event("enable")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700364 o.OperState.Event("enable")
365 } else if msg.OperState == DOWN {
366 o.InternalState.Event("disable")
367 o.OperState.Event("disable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700368 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700369 o.sendOltIndication(msg, stream)
370 case NniIndication:
371 msg, _ := message.Data.(NniIndicationMessage)
372 o.sendNniIndication(msg, stream)
373 case PonIndication:
374 msg, _ := message.Data.(PonIndicationMessage)
375 o.sendPonIndication(msg, stream)
376 default:
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700377 oltLogger.Warnf("Received unknown message data %v for type %v in OLT Channel", message.Data, message.Type)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700378 }
379
380 }
381}
382
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700383func (o OltDevice) processNniPacketIns(stream openolt.Openolt_EnableIndicationServer) {
384 oltLogger.WithFields(log.Fields{
385 "nniChannel": o.nniPktInChannel,
386 }).Debug("Started NNI Channel")
387 nniId := o.Nnis[0].ID // FIXME we are assuming we have only one NNI
388 for message := range o.nniPktInChannel {
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700389 oltLogger.Tracef("Received packets on NNI Channel")
390
391 onuMac, err := packetHandlers.GetDstMacAddressFromPacket(message.Pkt)
392
393 if err != nil {
394 log.WithFields(log.Fields{
395 "IntfType": "nni",
396 "IntfId": nniId,
397 "Pkt": message.Pkt.Data(),
Matteo Scandolo27428702019-10-11 16:21:16 -0700398 }).Error("Can't find Dst MacAddress in packet")
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700399 return
400 }
401
402 onu, err := o.FindOnuByMacAddress(onuMac)
403 if err != nil {
404 log.WithFields(log.Fields{
405 "IntfType": "nni",
406 "IntfId": nniId,
407 "Pkt": message.Pkt.Data(),
408 "MacAddress": onuMac.String(),
Matteo Scandolo27428702019-10-11 16:21:16 -0700409 }).Error("Can't find ONU with MacAddress")
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700410 return
411 }
412
413 doubleTaggedPkt, err := packetHandlers.PushDoubleTag(onu.STag, onu.CTag, message.Pkt)
414 if err != nil {
415 log.Error("Fail to add double tag to packet")
416 }
417
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700418 data := &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{
419 IntfType: "nni",
420 IntfId: nniId,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700421 Pkt: doubleTaggedPkt.Data()}}
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700422 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
423 oltLogger.WithFields(log.Fields{
424 "IntfType": data.PktInd.IntfType,
425 "IntfId": nniId,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700426 "Pkt": doubleTaggedPkt.Data(),
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700427 }).Errorf("Fail to send PktInd indication: %v", err)
428 }
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700429 oltLogger.WithFields(log.Fields{
430 "IntfType": data.PktInd.IntfType,
431 "IntfId": nniId,
432 "Pkt": doubleTaggedPkt.Data(),
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700433 "OnuSn": onu.Sn(),
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700434 }).Tracef("Sent PktInd indication")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700435 }
436}
437
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700438// returns an ONU with a given Serial Number
439func (o OltDevice) FindOnuBySn(serialNumber string) (*Onu, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +0200440 // TODO this function can be a performance bottleneck when we have many ONUs,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700441 // memoizing it will remove the bottleneck
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700442 for _, pon := range o.Pons {
443 for _, onu := range pon.Onus {
444 if onu.Sn() == serialNumber {
Matteo Scandolo27428702019-10-11 16:21:16 -0700445 return onu, nil
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700446 }
447 }
448 }
449
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700450 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-serial-number-%s", serialNumber))
451}
452
William Kurkian9dadc5b2019-10-22 13:51:57 -0400453// returns an ONU with a given interface/Onu Id
454func (o OltDevice) FindOnuById(intfId uint32, onuId uint32) (*Onu, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +0200455 // TODO this function can be a performance bottleneck when we have many ONUs,
William Kurkian9dadc5b2019-10-22 13:51:57 -0400456 // memoizing it will remove the bottleneck
457 for _, pon := range o.Pons {
458 if pon.ID == intfId {
459 for _, onu := range pon.Onus {
460 if onu.ID == onuId {
461 return onu, nil
462 }
463 }
464 }
465 }
466 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-id-%v-%v", intfId, onuId))
467}
468
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700469// returns an ONU with a given Mac Address
470func (o OltDevice) FindOnuByMacAddress(mac net.HardwareAddr) (*Onu, error) {
Zdravko Bozakov2da76342019-10-21 09:47:35 +0200471 // TODO this function can be a performance bottleneck when we have many ONUs,
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700472 // memoizing it will remove the bottleneck
473 for _, pon := range o.Pons {
474 for _, onu := range pon.Onus {
475 if onu.HwAddress.String() == mac.String() {
Matteo Scandolo27428702019-10-11 16:21:16 -0700476 return onu, nil
Matteo Scandolof6f3a7f2019-10-11 11:19:29 -0700477 }
478 }
479 }
480
481 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-by-mac-address-%s", mac))
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700482}
483
Matteo Scandolo4747d292019-08-05 11:50:18 -0700484// GRPC Endpoints
485
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700486func (o OltDevice) ActivateOnu(context context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700487 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700488 "OnuSn": onuSnToString(onu.SerialNumber),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700489 }).Info("Received ActivateOnu call from VOLTHA")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700490
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700491 pon, _ := o.GetPonById(onu.IntfId)
492 _onu, _ := pon.GetOnuBySn(onu.SerialNumber)
William Kurkian0418bc82019-11-06 12:16:24 -0500493 _onu.SetID(onu.OnuId)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700494
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700495 if err := _onu.OperState.Event("enable"); err != nil {
496 oltLogger.WithFields(log.Fields{
497 "IntfId": _onu.PonPortID,
498 "OnuSn": _onu.Sn(),
499 "OnuId": _onu.ID,
500 }).Infof("Failed to transition ONU.OperState to enabled state: %s", err.Error())
Matteo Scandolo4747d292019-08-05 11:50:18 -0700501 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700502 if err := _onu.InternalState.Event("enable"); err != nil {
503 oltLogger.WithFields(log.Fields{
504 "IntfId": _onu.PonPortID,
505 "OnuSn": _onu.Sn(),
506 "OnuId": _onu.ID,
507 }).Infof("Failed to transition ONU to enabled state: %s", err.Error())
508 }
509
510 // NOTE we need to immediately activate the ONU or the OMCI state machine won't start
511
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700512 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700513}
514
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700515func (o OltDevice) DeactivateOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700516 oltLogger.Error("DeactivateOnu not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700517 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700518}
519
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700520func (o OltDevice) DeleteOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700521 oltLogger.Error("DeleteOnu not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700522 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700523}
524
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700525func (o OltDevice) DisableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700526 // NOTE when we disable the OLT should we disable NNI, PONs and ONUs altogether?
527 olt_msg := Message{
528 Type: OltIndication,
529 Data: OltIndicationMessage{
530 OperState: DOWN,
531 },
532 }
533 o.channel <- olt_msg
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700534 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700535}
536
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700537func (o OltDevice) DisablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700538 oltLogger.Error("DisablePonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700539 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700540}
541
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700542func (o OltDevice) EnableIndication(_ *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700543 oltLogger.WithField("oltId", o.ID).Info("OLT receives EnableIndication call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700544 o.Enable(stream)
545 return nil
546}
547
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700548func (o OltDevice) EnablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700549 oltLogger.Error("EnablePonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700550 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700551}
552
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700553func (o OltDevice) FlowAdd(ctx context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700554 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700555 "IntfId": flow.AccessIntfId,
556 "OnuId": flow.OnuId,
557 "EthType": fmt.Sprintf("%x", flow.Classifier.EthType),
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700558 "InnerVlan": flow.Classifier.IVid,
559 "OuterVlan": flow.Classifier.OVid,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700560 "FlowType": flow.FlowType,
561 "FlowId": flow.FlowId,
562 "UniID": flow.UniId,
563 "PortNo": flow.PortNo,
564 }).Tracef("OLT receives Flow")
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700565 // TODO optionally store flows somewhere
566
567 if flow.AccessIntfId == -1 {
568 oltLogger.WithFields(log.Fields{
569 "FlowId": flow.FlowId,
570 }).Debugf("This is an OLT flow")
571 } else {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700572 pon, err := o.GetPonById(uint32(flow.AccessIntfId))
Matteo Scandolo27428702019-10-11 16:21:16 -0700573 if err != nil {
574 oltLogger.WithFields(log.Fields{
575 "OnuId": flow.OnuId,
576 "IntfId": flow.AccessIntfId,
577 "err": err,
578 }).Error("Can't find PonPort")
579 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700580 onu, err := pon.GetOnuById(uint32(flow.OnuId))
Matteo Scandolo27428702019-10-11 16:21:16 -0700581 if err != nil {
582 oltLogger.WithFields(log.Fields{
583 "OnuId": flow.OnuId,
584 "IntfId": flow.AccessIntfId,
585 "err": err,
586 }).Error("Can't find Onu")
587 }
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700588
589 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700590 Type: FlowUpdate,
591 Data: OnuFlowUpdateMessage{
592 PonPortID: pon.ID,
593 OnuID: onu.ID,
594 Flow: flow,
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700595 },
596 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700597 onu.Channel <- msg
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700598 }
599
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700600 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700601}
602
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700603func (o OltDevice) FlowRemove(context.Context, *openolt.Flow) (*openolt.Empty, error) {
604 oltLogger.Tracef("received FlowRemove")
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700605 // TODO store flows somewhere
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) HeartbeatCheck(context.Context, *openolt.Empty) (*openolt.Heartbeat, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700610 oltLogger.Error("HeartbeatCheck not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700611 return new(openolt.Heartbeat), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700612}
613
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700614func (o OltDevice) GetDeviceInfo(context.Context, *openolt.Empty) (*openolt.DeviceInfo, error) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700615
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700616 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700617 "oltId": o.ID,
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700618 "PonPorts": o.NumPon,
619 }).Info("OLT receives GetDeviceInfo call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700620 devinfo := new(openolt.DeviceInfo)
621 devinfo.Vendor = "BBSim"
622 devinfo.Model = "asfvolt16"
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700623 devinfo.HardwareVersion = "emulated"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700624 devinfo.FirmwareVersion = ""
625 devinfo.Technology = "xgspon"
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700626 devinfo.PonPorts = uint32(o.NumPon)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700627 devinfo.OnuIdStart = 1
628 devinfo.OnuIdEnd = 255
629 devinfo.AllocIdStart = 1024
630 devinfo.AllocIdEnd = 16383
631 devinfo.GemportIdStart = 1024
632 devinfo.GemportIdEnd = 65535
633 devinfo.FlowIdStart = 1
634 devinfo.FlowIdEnd = 16383
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700635 devinfo.DeviceSerialNumber = o.SerialNumber
Matteo Scandolo3f5d7f22019-10-16 14:21:13 -0700636 devinfo.DeviceId = net.HardwareAddr{0xA, 0xA, 0xA, 0xA, 0xA, byte(o.ID)}.String()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700637
638 return devinfo, nil
639}
640
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700641func (o OltDevice) OmciMsgOut(ctx context.Context, omci_msg *openolt.OmciMsg) (*openolt.Empty, error) {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700642 pon, _ := o.GetPonById(omci_msg.IntfId)
643 onu, _ := pon.GetOnuById(omci_msg.OnuId)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700644 oltLogger.WithFields(log.Fields{
645 "IntfId": onu.PonPortID,
646 "OnuId": onu.ID,
647 "OnuSn": onu.Sn(),
648 }).Tracef("Received OmciMsgOut")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700649 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700650 Type: OMCI,
651 Data: OmciMessage{
652 OnuSN: onu.SerialNumber,
653 OnuID: onu.ID,
654 omciMsg: omci_msg,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700655 },
656 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700657 onu.Channel <- msg
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700658 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700659}
660
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700661func (o OltDevice) OnuPacketOut(ctx context.Context, onuPkt *openolt.OnuPacket) (*openolt.Empty, error) {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700662 pon, err := o.GetPonById(onuPkt.IntfId)
Matteo Scandolo27428702019-10-11 16:21:16 -0700663 if err != nil {
664 oltLogger.WithFields(log.Fields{
665 "OnuId": onuPkt.OnuId,
666 "IntfId": onuPkt.IntfId,
667 "err": err,
668 }).Error("Can't find PonPort")
669 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700670 onu, err := pon.GetOnuById(onuPkt.OnuId)
Matteo Scandolo27428702019-10-11 16:21:16 -0700671 if err != nil {
672 oltLogger.WithFields(log.Fields{
673 "OnuId": onuPkt.OnuId,
674 "IntfId": onuPkt.IntfId,
675 "err": err,
676 }).Error("Can't find Onu")
677 }
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700678
Matteo Scandolo075b1892019-10-07 12:11:07 -0700679 oltLogger.WithFields(log.Fields{
680 "IntfId": onu.PonPortID,
681 "OnuId": onu.ID,
682 "OnuSn": onu.Sn(),
683 }).Tracef("Received OnuPacketOut")
684
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700685 rawpkt := gopacket.NewPacket(onuPkt.Pkt, layers.LayerTypeEthernet, gopacket.Default)
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700686 pktType, err := packetHandlers.IsEapolOrDhcp(rawpkt)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700687
Matteo Scandolo075b1892019-10-07 12:11:07 -0700688 msg := Message{
689 Type: OnuPacketOut,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700690 Data: OnuPacketMessage{
Matteo Scandolo075b1892019-10-07 12:11:07 -0700691 IntfId: onuPkt.IntfId,
692 OnuId: onuPkt.OnuId,
693 Packet: rawpkt,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700694 Type: pktType,
Matteo Scandolo075b1892019-10-07 12:11:07 -0700695 },
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700696 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700697 onu.Channel <- msg
698
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700699 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700700}
701
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700702func (o OltDevice) Reboot(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700703 oltLogger.Info("Shutting Down")
704 close(*o.oltDoneChannel)
705 close(*o.apiDoneChannel)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700706 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700707}
708
709func (o OltDevice) ReenableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700710 oltLogger.Error("ReenableOlt not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700711 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700712}
713
714func (o OltDevice) UplinkPacketOut(context context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700715 pkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
716
717 sendNniPacket(pkt)
718 // NOTE should we return an error if sendNniPakcet fails?
719 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700720}
721
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700722func (o OltDevice) CollectStatistics(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700723 oltLogger.Error("CollectStatistics not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700724 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700725}
726
Matteo Scandolo4747d292019-08-05 11:50:18 -0700727func (o OltDevice) GetOnuInfo(context context.Context, packet *openolt.Onu) (*openolt.OnuIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700728 oltLogger.Error("GetOnuInfo not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700729 return new(openolt.OnuIndication), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700730}
731
732func (o OltDevice) GetPonIf(context context.Context, packet *openolt.Interface) (*openolt.IntfIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700733 oltLogger.Error("GetPonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700734 return new(openolt.IntfIndication), nil
Matteo Scandolod54283a2019-08-13 16:22:31 -0700735}
736
737func (s OltDevice) CreateTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700738 oltLogger.Info("received CreateTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700739 return new(openolt.Empty), nil
740}
741
742func (s OltDevice) RemoveTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700743 oltLogger.Info("received RemoveTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700744 return new(openolt.Empty), nil
745}
746
747func (s OltDevice) CreateTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700748 oltLogger.Info("received CreateTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700749 return new(openolt.Empty), nil
750}
751
752func (s OltDevice) RemoveTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700753 oltLogger.Info("received RemoveTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700754 return new(openolt.Empty), nil
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700755}