blob: 54301fad0dd53435df38c1104188280b5deed48d [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 Scandolo3de9de02019-11-14 13:40:03 -080024 "github.com/opencord/voltha-protos/v2/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" {
78 for _, onu := range ponPort.Onus {
79 if onu.InternalState.Current() == "pon_disabled" {
Hardik Windlassad790cb2020-06-17 21:26:22 +053080 if err := onu.InternalState.Event("enable"); err != nil {
81 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -080082 "Err": err,
83 "OnuSn": onu.Sn(),
Hardik Windlassad790cb2020-06-17 21:26:22 +053084 "IntfId": onu.PonPortID,
85 }).Error("Error enabling ONU")
Pragya Arya2225f202020-01-29 18:05:01 +053086 }
87 } else if onu.InternalState.Current() == "disabled" {
88 if err := onu.InternalState.Event("initialize"); err != nil {
Hardik Windlassad790cb2020-06-17 21:26:22 +053089 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -080090 "Err": err,
91 "OnuSn": onu.Sn(),
Hardik Windlassad790cb2020-06-17 21:26:22 +053092 "IntfId": onu.PonPortID,
93 }).Error("Error initializing ONU")
Pragya Arya2225f202020-01-29 18:05:01 +053094 continue
95 }
96 if err := onu.InternalState.Event("discover"); err != nil {
Hardik Windlassad790cb2020-06-17 21:26:22 +053097 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -080098 "Err": err,
99 "OnuSn": onu.Sn(),
Hardik Windlassad790cb2020-06-17 21:26:22 +0530100 "IntfId": onu.PonPortID,
101 }).Error("Error discovering ONU")
Pragya Arya2225f202020-01-29 18:05:01 +0530102 }
Hardik Windlassad790cb2020-06-17 21:26:22 +0530103 } else if onu.InternalState.Current() == "initialized" {
104 if err := onu.InternalState.Event("discover"); err != nil {
105 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800106 "Err": err,
107 "OnuSn": onu.Sn(),
Hardik Windlassad790cb2020-06-17 21:26:22 +0530108 "IntfId": onu.PonPortID,
109 }).Error("Error discovering ONU")
110 }
111 } else {
112 // this is to loudly report unexpected states in order to address them
113 log.WithFields(log.Fields{
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800114 "OnuSn": onu.Sn(),
115 "IntfId": onu.PonPortID,
Hardik Windlassad790cb2020-06-17 21:26:22 +0530116 "InternalState": onu.InternalState.Current(),
117 }).Error("Unexpected ONU state in PON enabling")
Pragya Arya2225f202020-01-29 18:05:01 +0530118 }
119 }
120 }
121 },
122 "enter_disabled": func(e *fsm.Event) {
123 for _, onu := range ponPort.Onus {
124 if onu.InternalState.Current() == "initialized" {
125 continue
126 }
127 if err := onu.InternalState.Event("pon_disabled"); err != nil {
128 oltLogger.Errorf("Failed to move ONU in pon_disabled states: %v", err)
129 }
130 }
131 },
132 },
133 )
134
Pragya Arya6a708d62020-01-01 17:17:20 +0530135 ponPort.OperState = fsm.NewFSM(
136 "down",
137 fsm.Events{
138 {Name: "enable", Src: []string{"down"}, Dst: "up"},
139 {Name: "disable", Src: []string{"up"}, Dst: "down"},
140 },
141 fsm.Callbacks{
142 "enter_up": func(e *fsm.Event) {
143 oltLogger.WithFields(log.Fields{
144 "ID": ponPort.ID,
145 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
Pragya Arya2225f202020-01-29 18:05:01 +0530146 olt.sendPonIndication(ponPort.ID)
Pragya Arya6a708d62020-01-01 17:17:20 +0530147 },
148 "enter_down": func(e *fsm.Event) {
149 oltLogger.WithFields(log.Fields{
150 "ID": ponPort.ID,
151 }).Debugf("Changing PON Port OperState from %s to %s", e.Src, e.Dst)
Pragya Arya2225f202020-01-29 18:05:01 +0530152 olt.sendPonIndication(ponPort.ID)
Pragya Arya6a708d62020-01-01 17:17:20 +0530153 },
154 },
155 )
156 return &ponPort
157}
158
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700159func (p PonPort) GetOnuBySn(sn *openolt.SerialNumber) (*Onu, error) {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700160 for _, onu := range p.Onus {
161 if bytes.Equal(onu.SerialNumber.VendorSpecific, sn.VendorSpecific) {
Matteo Scandolo27428702019-10-11 16:21:16 -0700162 return onu, nil
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700163 }
164 }
Shrey Baid688b4242020-07-10 20:40:10 +0530165 return nil, fmt.Errorf("Cannot find Onu with serial number %d in PonPort %d", sn, p.ID)
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700166}
167
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700168func (p PonPort) GetOnuById(id uint32) (*Onu, error) {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700169 for _, onu := range p.Onus {
170 if onu.ID == id {
Matteo Scandolo27428702019-10-11 16:21:16 -0700171 return onu, nil
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700172 }
173 }
Shrey Baid688b4242020-07-10 20:40:10 +0530174 return nil, fmt.Errorf("Cannot find Onu with id %d in PonPort %d", id, p.ID)
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700175}
Pragya Arya996a0892020-03-09 21:47:52 +0530176
177// GetNumOfActiveOnus returns number of active ONUs for PON port
178func (p PonPort) GetNumOfActiveOnus() uint32 {
179 var count uint32 = 0
180 for _, onu := range p.Onus {
181 if onu.InternalState.Current() == "initialized" || onu.InternalState.Current() == "created" || onu.InternalState.Current() == "disabled" {
182 continue
183 }
184 count++
185 }
186 return count
187}