blob: 130c74f89a42816f33909d96286817212be70188 [file] [log] [blame]
Matteo Scandolo86e8ce62019-10-11 12:03:10 -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
17package devices
18
19import (
20 "bytes"
21 "errors"
22 "fmt"
Zdravko Bozakov2da76342019-10-21 09:47:35 +020023
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070024 "github.com/looplab/fsm"
Matteo Scandolo3de9de02019-11-14 13:40:03 -080025 "github.com/opencord/voltha-protos/v2/go/openolt"
Pragya Arya6a708d62020-01-01 17:17:20 +053026 log "github.com/sirupsen/logrus"
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070027)
28
29type PonPort struct {
30 // BBSIM Internals
31 ID uint32
32 NumOnu int
Matteo Scandolo27428702019-10-11 16:21:16 -070033 Onus []*Onu
Pragya Arya1881df02020-01-29 18:05:01 +053034 Olt *OltDevice
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070035
36 // PON Attributes
37 OperState *fsm.FSM
38 Type string
39
40 // NOTE do we need a state machine for the PON Ports?
Pragya Arya1881df02020-01-29 18:05:01 +053041 InternalState *fsm.FSM
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070042}
43
Pragya Arya6a708d62020-01-01 17:17:20 +053044// CreatePonPort creates pon port object
Pragya Arya1881df02020-01-29 18:05:01 +053045func CreatePonPort(olt *OltDevice, id uint32) *PonPort {
Pragya Arya6a708d62020-01-01 17:17:20 +053046
47 ponPort := PonPort{
48 NumOnu: olt.NumOnuPerPon,
49 ID: id,
50 Type: "pon",
51 Olt: olt,
52 Onus: []*Onu{},
53 }
54
Pragya Arya1881df02020-01-29 18:05:01 +053055 ponPort.InternalState = fsm.NewFSM(
56 "created",
57 fsm.Events{
58 {Name: "enable", Src: []string{"created", "disabled"}, Dst: "enabled"},
59 {Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
60 },
61 fsm.Callbacks{
62 "enter_enabled": func(e *fsm.Event) {
63 oltLogger.WithFields(log.Fields{
64 "ID": ponPort.ID,
65 }).Debugf("Changing PON Port InternalState from %s to %s", e.Src, e.Dst)
66
67 if e.Src == "created" {
68 if olt.ControlledActivation == Default || olt.ControlledActivation == OnlyPON {
69 for _, onu := range ponPort.Onus {
70 if err := onu.InternalState.Event("initialize"); err != nil {
71 log.Errorf("Error initializing ONU: %v", err)
72 continue
73 }
74 if err := onu.InternalState.Event("discover"); err != nil {
75 log.Errorf("Error discover ONU: %v", err)
76 }
77 }
78 }
79 } else if e.Src == "disabled" {
80 for _, onu := range ponPort.Onus {
81 if onu.InternalState.Current() == "pon_disabled" {
82 if err := onu.InternalState.Event("discover"); err != nil {
83 log.Errorf("Error discover ONU: %v", err)
84 }
85 } else if onu.InternalState.Current() == "disabled" {
86 if err := onu.InternalState.Event("initialize"); err != nil {
87 log.Errorf("Error initialize ONU: %v", err)
88 continue
89 }
90 if err := onu.InternalState.Event("discover"); err != nil {
91 log.Errorf("Error discover ONU: %v", err)
92 }
93 }
94 }
95 }
96 },
97 "enter_disabled": func(e *fsm.Event) {
98 for _, onu := range ponPort.Onus {
99 if onu.InternalState.Current() == "initialized" {
100 continue
101 }
102 if err := onu.InternalState.Event("pon_disabled"); err != nil {
103 oltLogger.Errorf("Failed to move ONU in pon_disabled states: %v", err)
104 }
105 }
106 },
107 },
108 )
109
Pragya Arya6a708d62020-01-01 17:17:20 +0530110 ponPort.OperState = fsm.NewFSM(
111 "down",
112 fsm.Events{
113 {Name: "enable", Src: []string{"down"}, Dst: "up"},
114 {Name: "disable", Src: []string{"up"}, Dst: "down"},
115 },
116 fsm.Callbacks{
117 "enter_up": func(e *fsm.Event) {
118 oltLogger.WithFields(log.Fields{
119 "ID": ponPort.ID,
120 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
Pragya Arya1881df02020-01-29 18:05:01 +0530121 olt.sendPonIndication(ponPort.ID)
Pragya Arya6a708d62020-01-01 17:17:20 +0530122 },
123 "enter_down": func(e *fsm.Event) {
124 oltLogger.WithFields(log.Fields{
125 "ID": ponPort.ID,
126 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
Pragya Arya1881df02020-01-29 18:05:01 +0530127 olt.sendPonIndication(ponPort.ID)
Pragya Arya6a708d62020-01-01 17:17:20 +0530128 },
129 },
130 )
131 return &ponPort
132}
133
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700134func (p PonPort) GetOnuBySn(sn *openolt.SerialNumber) (*Onu, error) {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700135 for _, onu := range p.Onus {
136 if bytes.Equal(onu.SerialNumber.VendorSpecific, sn.VendorSpecific) {
Matteo Scandolo27428702019-10-11 16:21:16 -0700137 return onu, nil
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700138 }
139 }
140 return nil, errors.New(fmt.Sprintf("Cannot find Onu with serial number %d in PonPort %d", sn, p.ID))
141}
142
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700143func (p PonPort) GetOnuById(id uint32) (*Onu, error) {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700144 for _, onu := range p.Onus {
145 if onu.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700146 return onu, nil
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700147 }
148 }
149 return nil, errors.New(fmt.Sprintf("Cannot find Onu with id %d in PonPort %d", id, p.ID))
150}