blob: 225a45fcbcfc287341ed1cc4b38c1dd1ad4cf687 [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
Pragya Arya996a0892020-03-09 21:47:52 +053031 ID uint32
32 NumOnu int
33 Onus []*Onu
34 Olt *OltDevice
35 PacketCount uint64
36 InternalState *fsm.FSM
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070037
38 // PON Attributes
39 OperState *fsm.FSM
40 Type string
Matteo Scandolo86e8ce62019-10-11 12:03:10 -070041}
42
Pragya Arya6a708d62020-01-01 17:17:20 +053043// CreatePonPort creates pon port object
Pragya Arya2225f202020-01-29 18:05:01 +053044func CreatePonPort(olt *OltDevice, id uint32) *PonPort {
Pragya Arya6a708d62020-01-01 17:17:20 +053045
46 ponPort := PonPort{
47 NumOnu: olt.NumOnuPerPon,
48 ID: id,
49 Type: "pon",
50 Olt: olt,
51 Onus: []*Onu{},
52 }
53
Pragya Arya2225f202020-01-29 18:05:01 +053054 ponPort.InternalState = fsm.NewFSM(
55 "created",
56 fsm.Events{
57 {Name: "enable", Src: []string{"created", "disabled"}, Dst: "enabled"},
58 {Name: "disable", Src: []string{"enabled"}, Dst: "disabled"},
59 },
60 fsm.Callbacks{
61 "enter_enabled": func(e *fsm.Event) {
62 oltLogger.WithFields(log.Fields{
63 "ID": ponPort.ID,
64 }).Debugf("Changing PON Port InternalState from %s to %s", e.Src, e.Dst)
65
66 if e.Src == "created" {
67 if olt.ControlledActivation == Default || olt.ControlledActivation == OnlyPON {
68 for _, onu := range ponPort.Onus {
69 if err := onu.InternalState.Event("initialize"); err != nil {
70 log.Errorf("Error initializing ONU: %v", err)
71 continue
72 }
73 if err := onu.InternalState.Event("discover"); err != nil {
74 log.Errorf("Error discover ONU: %v", err)
75 }
76 }
77 }
78 } else if e.Src == "disabled" {
79 for _, onu := range ponPort.Onus {
80 if onu.InternalState.Current() == "pon_disabled" {
Hardik Windlassad790cb2020-06-17 21:26:22 +053081 if err := onu.InternalState.Event("enable"); err != nil {
82 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 enabling ONU")
Pragya Arya2225f202020-01-29 18:05:01 +053087 }
88 } else if onu.InternalState.Current() == "disabled" {
89 if err := onu.InternalState.Event("initialize"); err != nil {
Hardik Windlassad790cb2020-06-17 21:26:22 +053090 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -080091 "Err": err,
92 "OnuSn": onu.Sn(),
Hardik Windlassad790cb2020-06-17 21:26:22 +053093 "IntfId": onu.PonPortID,
94 }).Error("Error initializing ONU")
Pragya Arya2225f202020-01-29 18:05:01 +053095 continue
96 }
97 if err := onu.InternalState.Event("discover"); err != nil {
Hardik Windlassad790cb2020-06-17 21:26:22 +053098 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -080099 "Err": err,
100 "OnuSn": onu.Sn(),
Hardik Windlassad790cb2020-06-17 21:26:22 +0530101 "IntfId": onu.PonPortID,
102 }).Error("Error discovering ONU")
Pragya Arya2225f202020-01-29 18:05:01 +0530103 }
Hardik Windlassad790cb2020-06-17 21:26:22 +0530104 } else if onu.InternalState.Current() == "initialized" {
105 if err := onu.InternalState.Event("discover"); err != nil {
106 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800107 "Err": err,
108 "OnuSn": onu.Sn(),
Hardik Windlassad790cb2020-06-17 21:26:22 +0530109 "IntfId": onu.PonPortID,
110 }).Error("Error discovering ONU")
111 }
112 } else {
113 // this is to loudly report unexpected states in order to address them
114 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800115 "OnuSn": onu.Sn(),
116 "IntfId": onu.PonPortID,
Hardik Windlassad790cb2020-06-17 21:26:22 +0530117 "InternalState": onu.InternalState.Current(),
118 }).Error("Unexpected ONU state in PON enabling")
Pragya Arya2225f202020-01-29 18:05:01 +0530119 }
120 }
121 }
122 },
123 "enter_disabled": func(e *fsm.Event) {
124 for _, onu := range ponPort.Onus {
125 if onu.InternalState.Current() == "initialized" {
126 continue
127 }
128 if err := onu.InternalState.Event("pon_disabled"); err != nil {
129 oltLogger.Errorf("Failed to move ONU in pon_disabled states: %v", err)
130 }
131 }
132 },
133 },
134 )
135
Pragya Arya6a708d62020-01-01 17:17:20 +0530136 ponPort.OperState = fsm.NewFSM(
137 "down",
138 fsm.Events{
139 {Name: "enable", Src: []string{"down"}, Dst: "up"},
140 {Name: "disable", Src: []string{"up"}, Dst: "down"},
141 },
142 fsm.Callbacks{
143 "enter_up": func(e *fsm.Event) {
144 oltLogger.WithFields(log.Fields{
145 "ID": ponPort.ID,
146 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
Pragya Arya2225f202020-01-29 18:05:01 +0530147 olt.sendPonIndication(ponPort.ID)
Pragya Arya6a708d62020-01-01 17:17:20 +0530148 },
149 "enter_down": func(e *fsm.Event) {
150 oltLogger.WithFields(log.Fields{
151 "ID": ponPort.ID,
152 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
Pragya Arya2225f202020-01-29 18:05:01 +0530153 olt.sendPonIndication(ponPort.ID)
Pragya Arya6a708d62020-01-01 17:17:20 +0530154 },
155 },
156 )
157 return &ponPort
158}
159
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700160func (p PonPort) GetOnuBySn(sn *openolt.SerialNumber) (*Onu, error) {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700161 for _, onu := range p.Onus {
162 if bytes.Equal(onu.SerialNumber.VendorSpecific, sn.VendorSpecific) {
Matteo Scandolo27428702019-10-11 16:21:16 -0700163 return onu, nil
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700164 }
165 }
166 return nil, errors.New(fmt.Sprintf("Cannot find Onu with serial number %d in PonPort %d", sn, p.ID))
167}
168
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700169func (p PonPort) GetOnuById(id uint32) (*Onu, error) {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700170 for _, onu := range p.Onus {
171 if onu.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700172 return onu, nil
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700173 }
174 }
175 return nil, errors.New(fmt.Sprintf("Cannot find Onu with id %d in PonPort %d", id, p.ID))
176}
Pragya Arya996a0892020-03-09 21:47:52 +0530177
178// GetNumOfActiveOnus returns number of active ONUs for PON port
179func (p PonPort) GetNumOfActiveOnus() uint32 {
180 var count uint32 = 0
181 for _, onu := range p.Onus {
182 if onu.InternalState.Current() == "initialized" || onu.InternalState.Current() == "created" || onu.InternalState.Current() == "disabled" {
183 continue
184 }
185 count++
186 }
187 return count
188}