blob: 6910ecef004659761b15f8a16954333f908b0830 [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"
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070021 "fmt"
Zdravko Bozakov2da76342019-10-21 09:47:35 +020022
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070023 "github.com/looplab/fsm"
Matteo Scandolo4f4ac792020-10-01 16:33:21 -070024 "github.com/opencord/voltha-protos/v4/go/openolt"
Pragya Arya6a708d62020-01-01 17:17:20 +053025 log "github.com/sirupsen/logrus"
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070026)
27
28type PonPort struct {
29 // BBSIM Internals
Pragya Arya996a0892020-03-09 21:47:52 +053030 ID uint32
31 NumOnu int
32 Onus []*Onu
33 Olt *OltDevice
34 PacketCount uint64
35 InternalState *fsm.FSM
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070036
37 // PON Attributes
38 OperState *fsm.FSM
39 Type string
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070040}
41
Pragya Arya6a708d62020-01-01 17:17:20 +053042// CreatePonPort creates pon port object
Pragya Arya2225f202020-01-29 18:05:01 +053043func CreatePonPort(olt *OltDevice, id uint32) *PonPort {
Pragya Arya6a708d62020-01-01 17:17:20 +053044
45 ponPort := PonPort{
46 NumOnu: olt.NumOnuPerPon,
47 ID: id,
48 Type: "pon",
49 Olt: olt,
50 Onus: []*Onu{},
51 }
52
Pragya Arya2225f202020-01-29 18:05:01 +053053 ponPort.InternalState = fsm.NewFSM(
54 "created",
55 fsm.Events{
56 {Name: "enable", Src: []string{"created", "disabled"}, Dst: "enabled"},
57 {Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
58 },
59 fsm.Callbacks{
60 "enter_enabled": func(e *fsm.Event) {
61 oltLogger.WithFields(log.Fields{
62 "ID": ponPort.ID,
63 }).Debugf("Changing PON Port InternalState from %s to %s", e.Src, e.Dst)
64
65 if e.Src == "created" {
66 if olt.ControlledActivation == Default || olt.ControlledActivation == OnlyPON {
67 for _, onu := range ponPort.Onus {
68 if err := onu.InternalState.Event("initialize"); err != nil {
69 log.Errorf("Error initializing ONU: %v", err)
70 continue
71 }
72 if err := onu.InternalState.Event("discover"); err != nil {
73 log.Errorf("Error discover ONU: %v", err)
74 }
75 }
76 }
77 } else if e.Src == "disabled" {
Matteo Scandolo0de43d12020-10-05 13:54:41 -070078 if ponPort.Olt.ControlledActivation == OnlyONU || ponPort.Olt.ControlledActivation == Both {
79 // if ONUs are manually activated then only initialize them
80 for _, onu := range ponPort.Onus {
Pragya Arya2225f202020-01-29 18:05:01 +053081 if err := onu.InternalState.Event("initialize"); err != nil {
Hardik Windlassad790cb2020-06-17 21:26:22 +053082 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -080083 "Err": err,
84 "OnuSn": onu.Sn(),
Hardik Windlassad790cb2020-06-17 21:26:22 +053085 "IntfId": onu.PonPortID,
86 }).Error("Error initializing ONU")
Pragya Arya2225f202020-01-29 18:05:01 +053087 continue
88 }
Matteo Scandolo0de43d12020-10-05 13:54:41 -070089 }
90 } else {
91 for _, onu := range ponPort.Onus {
92 if onu.InternalState.Current() == "pon_disabled" {
93 if err := onu.InternalState.Event("enable"); err != nil {
94 log.WithFields(log.Fields{
95 "Err": err,
96 "OnuSn": onu.Sn(),
97 "IntfId": onu.PonPortID,
98 }).Error("Error enabling ONU")
99 }
100 } else if onu.InternalState.Current() == "disabled" {
101 if err := onu.InternalState.Event("initialize"); err != nil {
102 log.WithFields(log.Fields{
103 "Err": err,
104 "OnuSn": onu.Sn(),
105 "IntfId": onu.PonPortID,
106 }).Error("Error initializing ONU")
107 continue
108 }
109 if err := onu.InternalState.Event("discover"); err != nil {
110 log.WithFields(log.Fields{
111 "Err": err,
112 "OnuSn": onu.Sn(),
113 "IntfId": onu.PonPortID,
114 }).Error("Error discovering ONU")
115 }
116 } else if onu.InternalState.Current() == "initialized" {
117 if err := onu.InternalState.Event("discover"); err != nil {
118 log.WithFields(log.Fields{
119 "Err": err,
120 "OnuSn": onu.Sn(),
121 "IntfId": onu.PonPortID,
122 }).Error("Error discovering ONU")
123 }
124 } else {
125 // this is to loudly report unexpected states in order to address them
Hardik Windlassad790cb2020-06-17 21:26:22 +0530126 log.WithFields(log.Fields{
Matteo Scandolo0de43d12020-10-05 13:54:41 -0700127 "OnuSn": onu.Sn(),
128 "IntfId": onu.PonPortID,
129 "InternalState": onu.InternalState.Current(),
130 }).Error("Unexpected ONU state in PON enabling")
Pragya Arya2225f202020-01-29 18:05:01 +0530131 }
132 }
133 }
134 }
135 },
136 "enter_disabled": func(e *fsm.Event) {
137 for _, onu := range ponPort.Onus {
Matteo Scandolo635b2bf2020-09-04 10:23:40 -0700138 if onu.InternalState.Current() == "initialized" || onu.InternalState.Current() == "disabled" {
Pragya Arya2225f202020-01-29 18:05:01 +0530139 continue
140 }
141 if err := onu.InternalState.Event("pon_disabled"); err != nil {
142 oltLogger.Errorf("Failed to move ONU in pon_disabled states: %v", err)
143 }
144 }
145 },
146 },
147 )
148
Pragya Arya6a708d62020-01-01 17:17:20 +0530149 ponPort.OperState = fsm.NewFSM(
150 "down",
151 fsm.Events{
152 {Name: "enable", Src: []string{"down"}, Dst: "up"},
153 {Name: "disable", Src: []string{"up"}, Dst: "down"},
154 },
155 fsm.Callbacks{
156 "enter_up": func(e *fsm.Event) {
157 oltLogger.WithFields(log.Fields{
158 "ID": ponPort.ID,
159 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
Pragya Arya2225f202020-01-29 18:05:01 +0530160 olt.sendPonIndication(ponPort.ID)
Pragya Arya6a708d62020-01-01 17:17:20 +0530161 },
162 "enter_down": func(e *fsm.Event) {
163 oltLogger.WithFields(log.Fields{
164 "ID": ponPort.ID,
165 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
Pragya Arya2225f202020-01-29 18:05:01 +0530166 olt.sendPonIndication(ponPort.ID)
Pragya Arya6a708d62020-01-01 17:17:20 +0530167 },
168 },
169 )
170 return &ponPort
171}
172
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700173func (p PonPort) GetOnuBySn(sn *openolt.SerialNumber) (*Onu, error) {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700174 for _, onu := range p.Onus {
175 if bytes.Equal(onu.SerialNumber.VendorSpecific, sn.VendorSpecific) {
Matteo Scandolo27428702019-10-11 16:21:16 -0700176 return onu, nil
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700177 }
178 }
Shrey Baid688b4242020-07-10 20:40:10 +0530179 return nil, fmt.Errorf("Cannot find Onu with serial number %d in PonPort %d", sn, p.ID)
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700180}
181
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700182func (p PonPort) GetOnuById(id uint32) (*Onu, error) {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700183 for _, onu := range p.Onus {
184 if onu.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700185 return onu, nil
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700186 }
187 }
Shrey Baid688b4242020-07-10 20:40:10 +0530188 return nil, fmt.Errorf("Cannot find Onu with id %d in PonPort %d", id, p.ID)
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700189}
Pragya Arya996a0892020-03-09 21:47:52 +0530190
191// GetNumOfActiveOnus returns number of active ONUs for PON port
192func (p PonPort) GetNumOfActiveOnus() uint32 {
193 var count uint32 = 0
194 for _, onu := range p.Onus {
195 if onu.InternalState.Current() == "initialized" || onu.InternalState.Current() == "created" || onu.InternalState.Current() == "disabled" {
196 continue
197 }
198 count++
199 }
200 return count
201}