blob: 2d46cedae861d61b5cfd4da34ad4c84b8b58fd2c [file] [log] [blame]
Matteo Scandolo11006992019-08-28 11:29:46 -07001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Matteo Scandolo4747d292019-08-05 11:50:18 -070017package devices
18
19import (
20 "context"
21 "errors"
22 "fmt"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070023 "github.com/google/gopacket"
24 "github.com/google/gopacket/layers"
Matteo Scandolo4747d292019-08-05 11:50:18 -070025 "github.com/looplab/fsm"
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070026 bbsim "github.com/opencord/bbsim/internal/bbsim/types"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070027 "github.com/opencord/voltha-protos/go/openolt"
Matteo Scandolod54283a2019-08-13 16:22:31 -070028 "github.com/opencord/voltha-protos/go/tech_profile"
Matteo Scandolo4747d292019-08-05 11:50:18 -070029 log "github.com/sirupsen/logrus"
30 "google.golang.org/grpc"
31 "net"
32 "sync"
33)
34
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070035var oltLogger = log.WithFields(log.Fields{
Matteo Scandolo84f7d482019-08-08 19:00:47 -070036 "module": "OLT",
37})
38
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070039type OltDevice struct {
40 // BBSIM Internals
41 ID int
42 SerialNumber string
43 NumNni int
44 NumPon int
45 NumOnuPerPon int
46 InternalState *fsm.FSM
47 channel chan Message
48 oltDoneChannel *chan bool
49 apiDoneChannel *chan bool
50 nniPktInChannel chan *bbsim.PacketMsg
51
52 Pons []PonPort
53 Nnis []NniPort
54
55 // OLT Attributes
56 OperState *fsm.FSM
Matteo Scandolo4747d292019-08-05 11:50:18 -070057}
58
Matteo Scandolo84f7d482019-08-08 19:00:47 -070059var olt = OltDevice{}
60
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070061func GetOLT() OltDevice {
Matteo Scandolo84f7d482019-08-08 19:00:47 -070062 return olt
63}
64
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070065func CreateOLT(seq int, nni int, pon int, onuPerPon int, sTag int, cTagInit int, oltDoneChannel *chan bool, apiDoneChannel *chan bool, group *sync.WaitGroup) OltDevice {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070066 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070067 "ID": seq,
68 "NumNni": nni,
69 "NumPon": pon,
70 "NumOnuPerPon": onuPerPon,
Matteo Scandolo4747d292019-08-05 11:50:18 -070071 }).Debug("CreateOLT")
72
Matteo Scandolo84f7d482019-08-08 19:00:47 -070073 olt = OltDevice{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070074 ID: seq,
Matteo Scandolo8df63df2019-09-12 10:34:32 -070075 SerialNumber: fmt.Sprintf("BBSIM_OLT_%d", seq),
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070076 OperState: getOperStateFSM(func(e *fsm.Event) {
77 oltLogger.Debugf("Changing OLT OperState from %s to %s", e.Src, e.Dst)
78 }),
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070079 NumNni: nni,
80 NumPon: pon,
81 NumOnuPerPon: onuPerPon,
82 Pons: []PonPort{},
83 Nnis: []NniPort{},
84 channel: make(chan Message),
85 oltDoneChannel: oltDoneChannel,
86 apiDoneChannel: apiDoneChannel,
87 nniPktInChannel: make(chan *bbsim.PacketMsg, 1024), // packets coming in from the NNI and going to VOLTHA
Matteo Scandolo4747d292019-08-05 11:50:18 -070088 }
89
90 // OLT State machine
Matteo Scandolo9a3518c2019-08-13 14:36:01 -070091 // NOTE do we need 2 state machines for the OLT? (InternalState and OperState)
Matteo Scandolo4747d292019-08-05 11:50:18 -070092 olt.InternalState = fsm.NewFSM(
93 "created",
94 fsm.Events{
95 {Name: "enable", Src: []string{"created"}, Dst: "enabled"},
96 {Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
97 },
98 fsm.Callbacks{
99 "enter_state": func(e *fsm.Event) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700100 oltLogger.Debugf("Changing OLT InternalState from %s to %s", e.Src, e.Dst)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700101 },
102 },
103 )
104
105 // create NNI Port
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700106 nniPort, err := CreateNNI(&olt)
107
108 if err != nil {
109 oltLogger.Fatalf("Couldn't create NNI Port: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700110 }
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700111
Matteo Scandolo4747d292019-08-05 11:50:18 -0700112 olt.Nnis = append(olt.Nnis, nniPort)
113
114 // create PON ports
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700115 availableCTag := cTagInit
Matteo Scandolo4747d292019-08-05 11:50:18 -0700116 for i := 0; i < pon; i++ {
117 p := PonPort{
118 NumOnu: olt.NumOnuPerPon,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700119 ID: uint32(i),
120 Type: "pon",
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700121 Olt: olt,
Matteo Scandolo4747d292019-08-05 11:50:18 -0700122 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700123 p.OperState = getOperStateFSM(func(e *fsm.Event) {
124 oltLogger.WithFields(log.Fields{
125 "ID": p.ID,
126 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
127 })
Matteo Scandolo4747d292019-08-05 11:50:18 -0700128
129 // create ONU devices
130 for j := 0; j < onuPerPon; j++ {
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700131 //o := CreateONU(olt, p, uint32(onuId))
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700132 o := CreateONU(olt, p, uint32(j+1), sTag, availableCTag)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700133 p.Onus = append(p.Onus, o)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700134 availableCTag = availableCTag + 1
Matteo Scandolo4747d292019-08-05 11:50:18 -0700135 }
136
137 olt.Pons = append(olt.Pons, p)
138 }
139
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700140 newOltServer(olt)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700141
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700142 group.Done()
Matteo Scandolo4747d292019-08-05 11:50:18 -0700143 return olt
144}
145
146func newOltServer(o OltDevice) error {
147 // TODO make configurable
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700148 address := "0.0.0.0:50060"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700149 lis, err := net.Listen("tcp", address)
150 if err != nil {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700151 oltLogger.Fatalf("OLT failed to listen: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700152 }
153 grpcServer := grpc.NewServer()
154 openolt.RegisterOpenoltServer(grpcServer, o)
155
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700156 wg := sync.WaitGroup{}
157 wg.Add(1)
158
Matteo Scandolo4747d292019-08-05 11:50:18 -0700159 go grpcServer.Serve(lis)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700160 oltLogger.Debugf("OLT Listening on: %v", address)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700161
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700162 for {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700163 _, ok := <-*o.oltDoneChannel
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700164 if !ok {
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700165 // if the olt Channel is closed, stop the gRPC server
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700166 log.Warnf("Stopping OLT gRPC server")
167 grpcServer.Stop()
168 wg.Done()
169 break
170 }
171 }
172
173 wg.Wait()
174
Matteo Scandolo4747d292019-08-05 11:50:18 -0700175 return nil
176}
177
178// Device Methods
179
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700180func (o OltDevice) Enable(stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700181
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700182 oltLogger.Debug("Enable OLT called")
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700183
Matteo Scandolo4747d292019-08-05 11:50:18 -0700184 wg := sync.WaitGroup{}
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700185 wg.Add(2)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700186
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700187 // create a Channel for all the OLT events
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700188 go o.processOltMessages(stream)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700189 go o.processNniPacketIns(stream)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700190
191 // enable the OLT
192 olt_msg := Message{
193 Type: OltIndication,
194 Data: OltIndicationMessage{
195 OperState: UP,
196 },
197 }
198 o.channel <- olt_msg
199
200 // send NNI Port Indications
201 for _, nni := range o.Nnis {
202 msg := Message{
203 Type: NniIndication,
204 Data: NniIndicationMessage{
205 OperState: UP,
206 NniPortID: nni.ID,
207 },
208 }
209 o.channel <- msg
210 }
211
212 // send PON Port indications
213 for _, pon := range o.Pons {
214 msg := Message{
215 Type: PonIndication,
216 Data: PonIndicationMessage{
217 OperState: UP,
218 PonPortID: pon.ID,
219 },
220 }
221 o.channel <- msg
222
223 for _, onu := range pon.Onus {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700224 go onu.processOnuMessages(stream)
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700225 go onu.processOmciMessages(stream)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700226 // FIXME move the message generation in the state transition
227 // from here only invoke the state transition
Matteo Scandolo4747d292019-08-05 11:50:18 -0700228 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700229 Type: OnuDiscIndication,
Matteo Scandolo4747d292019-08-05 11:50:18 -0700230 Data: OnuDiscIndicationMessage{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700231 Onu: onu,
Matteo Scandolo4747d292019-08-05 11:50:18 -0700232 OperState: UP,
233 },
234 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700235 onu.Channel <- msg
Matteo Scandolo4747d292019-08-05 11:50:18 -0700236 }
237 }
238
239 wg.Wait()
240 return nil
241}
242
243// Helpers method
244
245func (o OltDevice) getPonById(id uint32) (*PonPort, error) {
246 for _, pon := range o.Pons {
247 if pon.ID == id {
248 return &pon, nil
249 }
250 }
251 return nil, errors.New(fmt.Sprintf("Cannot find PonPort with id %d in OLT %d", id, o.ID))
252}
253
254func (o OltDevice) getNniById(id uint32) (*NniPort, error) {
255 for _, nni := range o.Nnis {
256 if nni.ID == id {
257 return &nni, nil
258 }
259 }
260 return nil, errors.New(fmt.Sprintf("Cannot find NniPort with id %d in OLT %d", id, o.ID))
261}
262
Matteo Scandolo4747d292019-08-05 11:50:18 -0700263func (o OltDevice) sendOltIndication(msg OltIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
264 data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: msg.OperState.String()}}
265 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700266 oltLogger.Errorf("Failed to send Indication_OltInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700267 }
268
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700269 oltLogger.WithFields(log.Fields{
Matteo Scandolo4747d292019-08-05 11:50:18 -0700270 "OperState": msg.OperState,
271 }).Debug("Sent Indication_OltInd")
272}
273
274func (o OltDevice) sendNniIndication(msg NniIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
275 nni, _ := o.getNniById(msg.NniPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700276 nni.OperState.Event("enable")
277 // NOTE Operstate may need to be an integer
Matteo Scandolo4747d292019-08-05 11:50:18 -0700278 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700279 Type: nni.Type,
280 IntfId: nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700281 OperState: nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700282 }}
283
284 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700285 oltLogger.Errorf("Failed to send Indication_IntfOperInd for NNI: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700286 }
287
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700288 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700289 "Type": nni.Type,
290 "IntfId": nni.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700291 "OperState": nni.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700292 }).Debug("Sent Indication_IntfOperInd for NNI")
293}
294
295func (o OltDevice) sendPonIndication(msg PonIndicationMessage, stream openolt.Openolt_EnableIndicationServer) {
296 pon, _ := o.getPonById(msg.PonPortID)
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700297 pon.OperState.Event("enable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700298 discoverData := &openolt.Indication_IntfInd{IntfInd: &openolt.IntfIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700299 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700300 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700301 }}
302
303 if err := stream.Send(&openolt.Indication{Data: discoverData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700304 oltLogger.Errorf("Failed to send Indication_IntfInd: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700305 }
306
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700307 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700308 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700309 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700310 }).Debug("Sent Indication_IntfInd")
311
312 operData := &openolt.Indication_IntfOperInd{IntfOperInd: &openolt.IntfOperIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700313 Type: pon.Type,
314 IntfId: pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700315 OperState: pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700316 }}
317
318 if err := stream.Send(&openolt.Indication{Data: operData}); err != nil {
Matteo Scandolo11006992019-08-28 11:29:46 -0700319 oltLogger.Errorf("Failed to send Indication_IntfOperInd for PON: %v", err)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700320 }
321
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700322 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700323 "Type": pon.Type,
324 "IntfId": pon.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700325 "OperState": pon.OperState.Current(),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700326 }).Debug("Sent Indication_IntfOperInd for PON")
327}
328
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700329func (o OltDevice) processOltMessages(stream openolt.Openolt_EnableIndicationServer) {
330 oltLogger.Debug("Started OLT Indication Channel")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700331 for message := range o.channel {
332
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700333 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700334 "oltId": o.ID,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700335 "messageType": message.Type,
336 }).Trace("Received message")
337
338 switch message.Type {
339 case OltIndication:
340 msg, _ := message.Data.(OltIndicationMessage)
341 if msg.OperState == UP {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700342 o.InternalState.Event("enable")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700343 o.OperState.Event("enable")
344 } else if msg.OperState == DOWN {
345 o.InternalState.Event("disable")
346 o.OperState.Event("disable")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700347 }
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700348 o.sendOltIndication(msg, stream)
349 case NniIndication:
350 msg, _ := message.Data.(NniIndicationMessage)
351 o.sendNniIndication(msg, stream)
352 case PonIndication:
353 msg, _ := message.Data.(PonIndicationMessage)
354 o.sendPonIndication(msg, stream)
355 default:
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700356 oltLogger.Warnf("Received unknown message data %v for type %v in OLT Channel", message.Data, message.Type)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700357 }
358
359 }
360}
361
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700362func (o OltDevice) processNniPacketIns(stream openolt.Openolt_EnableIndicationServer) {
363 oltLogger.WithFields(log.Fields{
364 "nniChannel": o.nniPktInChannel,
365 }).Debug("Started NNI Channel")
366 nniId := o.Nnis[0].ID // FIXME we are assuming we have only one NNI
367 for message := range o.nniPktInChannel {
368 oltLogger.Debug("Received packets on NNI Channel")
369 data := &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{
370 IntfType: "nni",
371 IntfId: nniId,
372 Pkt: message.Pkt.Data()}}
373 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
374 oltLogger.WithFields(log.Fields{
375 "IntfType": data.PktInd.IntfType,
376 "IntfId": nniId,
377 "Pkt": message.Pkt.Data(),
378 }).Errorf("Fail to send PktInd indication: %v", err)
379 }
380 }
381}
382
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700383func (o OltDevice) FindOnu(serialNumber string) (*Onu, error) {
384
385 for _, pon := range o.Pons {
386 for _, onu := range pon.Onus {
387 if onu.Sn() == serialNumber {
388 return &onu, nil
389 }
390 }
391 }
392
393 return &Onu{}, errors.New(fmt.Sprintf("cannot-find-onu-%s", serialNumber))
394}
395
Matteo Scandolo4747d292019-08-05 11:50:18 -0700396// GRPC Endpoints
397
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700398func (o OltDevice) ActivateOnu(context context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700399 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700400 "OnuSn": onuSnToString(onu.SerialNumber),
Matteo Scandolo4747d292019-08-05 11:50:18 -0700401 }).Info("Received ActivateOnu call from VOLTHA")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700402
403 pon, _ := o.getPonById(onu.IntfId)
404 _onu, _ := pon.getOnuBySn(onu.SerialNumber)
405
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700406 if err := _onu.OperState.Event("enable"); err != nil {
407 oltLogger.WithFields(log.Fields{
408 "IntfId": _onu.PonPortID,
409 "OnuSn": _onu.Sn(),
410 "OnuId": _onu.ID,
411 }).Infof("Failed to transition ONU.OperState to enabled state: %s", err.Error())
Matteo Scandolo4747d292019-08-05 11:50:18 -0700412 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700413 if err := _onu.InternalState.Event("enable"); err != nil {
414 oltLogger.WithFields(log.Fields{
415 "IntfId": _onu.PonPortID,
416 "OnuSn": _onu.Sn(),
417 "OnuId": _onu.ID,
418 }).Infof("Failed to transition ONU to enabled state: %s", err.Error())
419 }
420
421 // NOTE we need to immediately activate the ONU or the OMCI state machine won't start
422
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700423 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700424}
425
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700426func (o OltDevice) DeactivateOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700427 oltLogger.Error("DeactivateOnu not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700428 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700429}
430
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700431func (o OltDevice) DeleteOnu(context.Context, *openolt.Onu) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700432 oltLogger.Error("DeleteOnu not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700433 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700434}
435
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700436func (o OltDevice) DisableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700437 // NOTE when we disable the OLT should we disable NNI, PONs and ONUs altogether?
438 olt_msg := Message{
439 Type: OltIndication,
440 Data: OltIndicationMessage{
441 OperState: DOWN,
442 },
443 }
444 o.channel <- olt_msg
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700445 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700446}
447
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700448func (o OltDevice) DisablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700449 oltLogger.Error("DisablePonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700450 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700451}
452
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700453func (o OltDevice) EnableIndication(_ *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700454 oltLogger.WithField("oltId", o.ID).Info("OLT receives EnableIndication call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700455 o.Enable(stream)
456 return nil
457}
458
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700459func (o OltDevice) EnablePonIf(context.Context, *openolt.Interface) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700460 oltLogger.Error("EnablePonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700461 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700462}
463
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700464func (o OltDevice) FlowAdd(ctx context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700465 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700466 "IntfId": flow.AccessIntfId,
467 "OnuId": flow.OnuId,
468 "EthType": fmt.Sprintf("%x", flow.Classifier.EthType),
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700469 "InnerVlan": flow.Classifier.IVid,
470 "OuterVlan": flow.Classifier.OVid,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700471 "FlowType": flow.FlowType,
472 "FlowId": flow.FlowId,
473 "UniID": flow.UniId,
474 "PortNo": flow.PortNo,
475 }).Tracef("OLT receives Flow")
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700476 // TODO optionally store flows somewhere
477
478 if flow.AccessIntfId == -1 {
479 oltLogger.WithFields(log.Fields{
480 "FlowId": flow.FlowId,
481 }).Debugf("This is an OLT flow")
482 } else {
483 pon, _ := o.getPonById(uint32(flow.AccessIntfId))
484 onu, _ := pon.getOnuById(uint32(flow.OnuId))
485
486 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700487 Type: FlowUpdate,
488 Data: OnuFlowUpdateMessage{
489 PonPortID: pon.ID,
490 OnuID: onu.ID,
491 Flow: flow,
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700492 },
493 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700494 onu.Channel <- msg
Matteo Scandolo3bc73742019-08-20 14:04:04 -0700495 }
496
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700497 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700498}
499
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700500func (o OltDevice) FlowRemove(context.Context, *openolt.Flow) (*openolt.Empty, error) {
501 oltLogger.Tracef("received FlowRemove")
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700502 // TODO store flows somewhere
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700503 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700504}
505
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700506func (o OltDevice) HeartbeatCheck(context.Context, *openolt.Empty) (*openolt.Heartbeat, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700507 oltLogger.Error("HeartbeatCheck not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700508 return new(openolt.Heartbeat), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700509}
510
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700511func (o OltDevice) GetDeviceInfo(context.Context, *openolt.Empty) (*openolt.DeviceInfo, error) {
Matteo Scandolo4747d292019-08-05 11:50:18 -0700512
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700513 oltLogger.WithFields(log.Fields{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700514 "oltId": o.ID,
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700515 "PonPorts": o.NumPon,
516 }).Info("OLT receives GetDeviceInfo call from VOLTHA")
Matteo Scandolo4747d292019-08-05 11:50:18 -0700517 devinfo := new(openolt.DeviceInfo)
518 devinfo.Vendor = "BBSim"
519 devinfo.Model = "asfvolt16"
Matteo Scandolo84f7d482019-08-08 19:00:47 -0700520 devinfo.HardwareVersion = "emulated"
Matteo Scandolo4747d292019-08-05 11:50:18 -0700521 devinfo.FirmwareVersion = ""
522 devinfo.Technology = "xgspon"
Matteo Scandoloda9cbe22019-08-19 16:05:10 -0700523 devinfo.PonPorts = uint32(o.NumPon)
Matteo Scandolo4747d292019-08-05 11:50:18 -0700524 devinfo.OnuIdStart = 1
525 devinfo.OnuIdEnd = 255
526 devinfo.AllocIdStart = 1024
527 devinfo.AllocIdEnd = 16383
528 devinfo.GemportIdStart = 1024
529 devinfo.GemportIdEnd = 65535
530 devinfo.FlowIdStart = 1
531 devinfo.FlowIdEnd = 16383
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700532 devinfo.DeviceSerialNumber = o.SerialNumber
Matteo Scandolo4747d292019-08-05 11:50:18 -0700533
534 return devinfo, nil
535}
536
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700537func (o OltDevice) OmciMsgOut(ctx context.Context, omci_msg *openolt.OmciMsg) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700538 pon, _ := o.getPonById(omci_msg.IntfId)
539 onu, _ := pon.getOnuById(omci_msg.OnuId)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700540 oltLogger.WithFields(log.Fields{
541 "IntfId": onu.PonPortID,
542 "OnuId": onu.ID,
543 "OnuSn": onu.Sn(),
544 }).Tracef("Received OmciMsgOut")
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700545 msg := Message{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700546 Type: OMCI,
547 Data: OmciMessage{
548 OnuSN: onu.SerialNumber,
549 OnuID: onu.ID,
550 omciMsg: omci_msg,
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700551 },
552 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700553 onu.Channel <- msg
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700554 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700555}
556
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700557func (o OltDevice) OnuPacketOut(ctx context.Context, onuPkt *openolt.OnuPacket) (*openolt.Empty, error) {
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700558 pon, _ := o.getPonById(onuPkt.IntfId)
559 onu, _ := pon.getOnuById(onuPkt.OnuId)
560
Matteo Scandolo075b1892019-10-07 12:11:07 -0700561 oltLogger.WithFields(log.Fields{
562 "IntfId": onu.PonPortID,
563 "OnuId": onu.ID,
564 "OnuSn": onu.Sn(),
565 }).Tracef("Received OnuPacketOut")
566
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700567 rawpkt := gopacket.NewPacket(onuPkt.Pkt, layers.LayerTypeEthernet, gopacket.Default)
568
Matteo Scandolo075b1892019-10-07 12:11:07 -0700569 msg := Message{
570 Type: OnuPacketOut,
571 Data: OnuPacketOutMessage{
572 IntfId: onuPkt.IntfId,
573 OnuId: onuPkt.OnuId,
574 Packet: rawpkt,
575 },
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700576 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700577 onu.Channel <- msg
578
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700579 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700580}
581
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700582func (o OltDevice) Reboot(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700583 oltLogger.Info("Shutting Down")
584 close(*o.oltDoneChannel)
585 close(*o.apiDoneChannel)
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700586 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700587}
588
589func (o OltDevice) ReenableOlt(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700590 oltLogger.Error("ReenableOlt not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700591 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700592}
593
594func (o OltDevice) UplinkPacketOut(context context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700595 pkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
596
597 sendNniPacket(pkt)
598 // NOTE should we return an error if sendNniPakcet fails?
599 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700600}
601
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700602func (o OltDevice) CollectStatistics(context.Context, *openolt.Empty) (*openolt.Empty, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700603 oltLogger.Error("CollectStatistics not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700604 return new(openolt.Empty), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700605}
606
Matteo Scandolo4747d292019-08-05 11:50:18 -0700607func (o OltDevice) GetOnuInfo(context context.Context, packet *openolt.Onu) (*openolt.OnuIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700608 oltLogger.Error("GetOnuInfo not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700609 return new(openolt.OnuIndication), nil
Matteo Scandolo4747d292019-08-05 11:50:18 -0700610}
611
612func (o OltDevice) GetPonIf(context context.Context, packet *openolt.Interface) (*openolt.IntfIndication, error) {
Matteo Scandolo9a3518c2019-08-13 14:36:01 -0700613 oltLogger.Error("GetPonIf not implemented")
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700614 return new(openolt.IntfIndication), nil
Matteo Scandolod54283a2019-08-13 16:22:31 -0700615}
616
617func (s OltDevice) CreateTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700618 oltLogger.Info("received CreateTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700619 return new(openolt.Empty), nil
620}
621
622func (s OltDevice) RemoveTrafficQueues(context.Context, *tech_profile.TrafficQueues) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700623 oltLogger.Info("received RemoveTrafficQueues")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700624 return new(openolt.Empty), nil
625}
626
627func (s OltDevice) CreateTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700628 oltLogger.Info("received CreateTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700629 return new(openolt.Empty), nil
630}
631
632func (s OltDevice) RemoveTrafficSchedulers(context.Context, *tech_profile.TrafficSchedulers) (*openolt.Empty, error) {
Matteo Scandoloc559ef12019-08-20 13:24:21 -0700633 oltLogger.Info("received RemoveTrafficSchedulers")
Matteo Scandolod54283a2019-08-13 16:22:31 -0700634 return new(openolt.Empty), nil
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700635}