blob: ef1b179559e88cb0d71b0db5beeead335c8bffae [file] [log] [blame]
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301/*
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 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
Phaneendra Manda4c62c802019-03-06 21:37:49 +053019
20import (
cuilin20187b2a8c32019-03-26 19:52:28 -070021 "context"
Matt Jeanneretceea2e02020-03-27 14:19:57 -040022 "encoding/binary"
Matt Jeanneret1359c732019-08-01 21:40:02 -040023 "encoding/hex"
Girish Gowdra491a9c62021-01-06 16:43:07 -080024 "errors"
cuilin20187b2a8c32019-03-26 19:52:28 -070025 "fmt"
26 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040027 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070028 "strconv"
29 "strings"
30 "sync"
31 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053032
Matteo Scandolo945e4012019-12-12 14:16:11 -080033 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070034 "github.com/gogo/protobuf/proto"
35 "github.com/golang/protobuf/ptypes"
Girish Kumar93e91742020-07-27 16:43:19 +000036 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
37 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070038 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080039 "github.com/opencord/voltha-lib-go/v4/pkg/config"
Himani Chawlacd407802020-12-10 12:08:59 +053040 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
Girish Gowdra491a9c62021-01-06 16:43:07 -080041 flow_utils "github.com/opencord/voltha-lib-go/v4/pkg/flows"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070042 "github.com/opencord/voltha-lib-go/v4/pkg/log"
43 "github.com/opencord/voltha-lib-go/v4/pkg/pmmetrics"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080044
Thomas Lee S94109f12020-03-03 16:39:29 +053045 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080046 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070047 "github.com/opencord/voltha-protos/v4/go/common"
kesavand62126212021-01-12 04:56:06 -050048 "github.com/opencord/voltha-protos/v4/go/extension"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070049 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
50 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
51 oop "github.com/opencord/voltha-protos/v4/go/openolt"
52 "github.com/opencord/voltha-protos/v4/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070053 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040054 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040055 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053056)
57
salmansiddiqui7ac62132019-08-22 03:58:50 +000058// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040059const (
Girish Gowdra491a9c62021-01-06 16:43:07 -080060 InvalidPort = 0xffffffff
61 MaxNumOfGroupHandlerChannels = 256
62
63 McastFlowOrGroupAdd = "McastFlowOrGroupAdd"
64 McastFlowOrGroupModify = "McastFlowOrGroupModify"
65 McastFlowOrGroupRemove = "McastFlowOrGroupRemove"
kesavand62126212021-01-12 04:56:06 -050066 oltPortInfoTimeout = 3
Manikkaraj kb1d51442019-07-23 10:41:02 -040067)
68
Phaneendra Manda4c62c802019-03-06 21:37:49 +053069//DeviceHandler will interact with the OLT device.
70type DeviceHandler struct {
Matteo Scandolodfa7a972020-11-06 13:03:40 -080071 cm *config.ConfigManager
cuilin20187b2a8c32019-03-26 19:52:28 -070072 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053073 coreProxy adapterif.CoreProxy
74 AdapterProxy adapterif.AdapterProxy
Himani Chawlacd407802020-12-10 12:08:59 +053075 EventProxy eventif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070076 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070077 exitChannel chan int
78 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053079 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070080 transitionMap *TransitionMap
81 clientCon *grpc.ClientConn
Girish Gowdra9602eb42020-09-09 15:50:39 -070082 flowMgr []*OpenOltFlowMgr
83 groupMgr *OpenOltGroupMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040084 eventMgr *OpenOltEventMgr
manikkaraj kbf256be2019-03-25 00:13:48 +053085 resourceMgr *rsrcMgr.OpenOltResourceMgr
Naga Manjunatha8dc9372019-10-31 23:01:18 +053086
Girish Gowdra3ab6d212020-03-24 17:33:15 -070087 discOnus sync.Map
88 onus sync.Map
89 portStats *OpenOltStatisticsMgr
90 metrics *pmmetrics.PmMetrics
91 stopCollector chan bool
92 stopHeartbeatCheck chan bool
93 activePorts sync.Map
94 stopIndications chan bool
95 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070096
Mahir Gunyel2fb81472020-12-16 23:18:34 -080097 totalPonPorts uint32
98 perOnuChannel map[string]onuIndicationChannels
99 perOnuChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800100
101 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
102 // A go routine per index, waits on a unique channel for incoming mcast flow or group (add/modify/remove).
103 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700104}
105
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700106//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700107type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700108 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700109 deviceType string
110 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700111 onuID uint32
112 intfID uint32
113 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530114 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400115 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700116}
117
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800118type perOnuIndication struct {
119 ctx context.Context
120 indication *oop.Indication
121 serialNumber string
122}
123
124type onuIndicationChannels struct {
125 indicationChannel chan perOnuIndication
126 stopChannel chan struct{}
127}
128
Girish Gowdra491a9c62021-01-06 16:43:07 -0800129//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
130//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
131//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
132//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
133type McastFlowOrGroupControlBlock struct {
134 ctx context.Context // Flow/group handler context
135 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
136 flow *voltha.OfpFlowStats // Flow message (can be nil or valid flow)
137 group *voltha.OfpGroupEntry // Group message (can be nil or valid group)
138 errChan *chan error // channel to report the mcast Flow/group handling error
139}
140
Naga Manjunath7615e552019-10-11 22:35:47 +0530141var pmNames = []string{
142 "rx_bytes",
143 "rx_packets",
144 "rx_mcast_packets",
145 "rx_bcast_packets",
146 "tx_bytes",
147 "tx_packets",
148 "tx_mcast_packets",
149 "tx_bcast_packets",
150}
151
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700152//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530153func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700154 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700155 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700156 device.deviceType = deviceTp
157 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700158 device.onuID = onuID
159 device.intfID = intfID
160 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530161 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700162 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530163}
164
165//NewDeviceHandler creates a new device handler
Himani Chawlacd407802020-12-10 12:08:59 +0530166func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep eventif.EventProxy, device *voltha.Device, adapter *OpenOLT, cm *config.ConfigManager) *DeviceHandler {
cuilin20187b2a8c32019-03-26 19:52:28 -0700167 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800168 dh.cm = cm
cuilin20187b2a8c32019-03-26 19:52:28 -0700169 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400170 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400171 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700172 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700173 dh.device = cloned
174 dh.openOLT = adapter
175 dh.exitChannel = make(chan int, 1)
176 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530177 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530178 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530179 dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Chaitrashree G Sef088112020-02-03 21:39:27 -0500180 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400181 dh.stopIndications = make(chan bool, 1)
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800182 dh.perOnuChannel = make(map[string]onuIndicationChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800183 // Create a slice of buffered channels for handling concurrent mcast flow/group.
184 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
185 for i := range dh.incomingMcastFlowOrGroup {
186 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
187 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
188 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
189 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
190 // for incoming mcast flow/group to be processed serially.
191 go dh.mcastFlowOrGroupChannelHandlerRoutine(dh.incomingMcastFlowOrGroup[i])
192 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700193 //TODO initialize the support classes.
194 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530195}
196
197// start save the device to the data model
198func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700199 dh.lockDevice.Lock()
200 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000201 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700202 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000203 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530204}
205
206// stop stops the device dh. Not much to do for now
207func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700208 dh.lockDevice.Lock()
209 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000210 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700211 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000212 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530213}
214
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400215func macifyIP(ip net.IP) string {
216 if len(ip) > 0 {
217 oct1 := strconv.FormatInt(int64(ip[12]), 16)
218 oct2 := strconv.FormatInt(int64(ip[13]), 16)
219 oct3 := strconv.FormatInt(int64(ip[14]), 16)
220 oct4 := strconv.FormatInt(int64(ip[15]), 16)
221 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
222 }
223 return ""
224}
225
Neha Sharma96b7bf22020-06-15 10:37:32 +0000226func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400227 var genmac string
228 var addr net.IP
229 var ips []string
230 var err error
231
Neha Sharma96b7bf22020-06-15 10:37:32 +0000232 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400233
234 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000235 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400236
237 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000238 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400239 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000240 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400241 }
242 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000243 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530244 log.Fields{"host": ips[0],
245 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400246 return genmac, nil
247 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000248 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400249 }
250
251 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000252 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530253 log.Fields{"host": host,
254 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400255 return genmac, nil
256}
257
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530258func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700259 slist := strings.Split(mac, ":")
260 result := make([]uint32, len(slist))
261 var err error
262 var tmp int64
263 for index, val := range slist {
264 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
265 return []uint32{1, 2, 3, 4, 5, 6}
266 }
267 result[index] = uint32(tmp)
268 }
269 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530270}
271
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700272//GetportLabel returns the label for the NNI and the PON port based on port number and port type
David K. Bainbridge794735f2020-02-11 21:01:37 -0800273func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530274
David K. Bainbridge794735f2020-02-11 21:01:37 -0800275 switch portType {
276 case voltha.Port_ETHERNET_NNI:
277 return fmt.Sprintf("nni-%d", portNum), nil
278 case voltha.Port_PON_OLT:
279 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700280 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800281
Girish Kumarf26e4882020-03-05 06:49:10 +0000282 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530283}
284
Neha Sharma96b7bf22020-06-15 10:37:32 +0000285func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000286 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700287 if state == "up" {
288 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500289 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500290 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700291 } else {
292 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500293 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700294 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700295 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400296 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800297 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000298 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400299 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500300
Neha Sharma8f4e4322020-08-06 10:51:53 +0000301 if port, err := dh.coreProxy.GetDevicePort(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portNum); err == nil && port.Type == portType {
Girish Kumara1ea2aa2020-08-19 18:14:22 +0000302 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000303 if err := dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, portType, portNum, operStatus); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400304 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
305 "device-id": dh.device.Id,
306 "port-type": portType,
307 "port-number": portNum,
308 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500309 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400310 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500311 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400312 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700313 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400314 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700315 PortNo: portNum,
316 Label: label,
317 Type: portType,
318 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700319 OfpPort: &of.OfpPort{
320 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
321 Config: 0,
322 State: uint32(of.OfpPortState_OFPPS_LIVE),
323 Curr: capacity,
324 Advertised: capacity,
325 Peer: capacity,
326 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
327 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
328 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700329 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000330 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700331 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000332 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000333 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800334 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000335 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400336 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000337 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530338 return nil
339}
340
Kent Hagermane6ff1012020-07-14 15:07:53 -0400341func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530342 dh.lockDevice.Lock()
343 defer dh.lockDevice.Unlock()
Neha Sharma8f4e4322020-08-06 10:51:53 +0000344 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530345 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400346 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
347 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530348 }
349 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530350}
351
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700352// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530353// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800354func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000355 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700356 defer func() {
357 dh.lockDevice.Lock()
358 dh.isReadIndicationRoutineActive = false
359 dh.lockDevice.Unlock()
360 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700361 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700362 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700363 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700364 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400365 /* get device state */
npujarec5762e2020-01-01 14:08:48 +0530366 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400367 if err != nil || device == nil {
368 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000369 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400370 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400371
David Bainbridgef5879ca2019-12-13 21:17:54 +0000372 // Create an exponential backoff around re-enabling indications. The
373 // maximum elapsed time for the back off is set to 0 so that we will
374 // continue to retry. The max interval defaults to 1m, but is set
375 // here for code clarity
376 indicationBackoff := backoff.NewExponentialBackOff()
377 indicationBackoff.MaxElapsedTime = 0
378 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700379
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700380 dh.lockDevice.Lock()
381 dh.isReadIndicationRoutineActive = true
382 dh.lockDevice.Unlock()
383
Girish Gowdra3f974912020-03-23 20:35:18 -0700384Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700385 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400386 select {
387 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000388 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700389 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400390 default:
391 indication, err := indications.Recv()
392 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000393 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530394 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530395 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400396 // Use an exponential back off to prevent getting into a tight loop
397 duration := indicationBackoff.NextBackOff()
398 if duration == backoff.Stop {
399 // If we reach a maximum then warn and reset the backoff
400 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000401 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530402 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530403 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400404 indicationBackoff.Reset()
405 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700406
407 // On failure process a backoff timer while watching for stopIndications
408 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700409 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700410 select {
411 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000412 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700413 if !backoffTimer.Stop() {
414 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700415 }
416 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700417 case <-backoffTimer.C:
418 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700419 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700420 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
421 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400422 }
423 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000424 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530425 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000426 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530427 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530428 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700429 // Close the stream, and re-initialize it
430 if err = indications.CloseSend(); err != nil {
431 // Ok to ignore here, because we landed here due to a problem on the stream
432 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000433 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530434 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530435 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700436 }
437 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
438 return err
439 }
440 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400441 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530442 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400443 // Reset backoff if we have a successful receive
444 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400445 // When OLT is admin down, ignore all indications.
Thomas Lee S985938d2020-05-04 11:40:41 +0530446 if device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000447 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530448 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530449 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400450 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400451 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400452 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700453 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700454 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700455 // Close the send stream
456 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700457
Girish Gowdra3f974912020-03-23 20:35:18 -0700458 return nil
459}
460
461func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
462
463 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
464 if err != nil {
465 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
466 }
467 if indications == nil {
468 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
469 }
470
471 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400472}
473
474// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
475func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
476 switch indication.Data.(type) {
477 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
478 return true
479
480 default:
481 return false
482 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700483}
484
David K. Bainbridge794735f2020-02-11 21:01:37 -0800485func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Daniele Rossi051466a2019-07-26 13:39:37 +0000486 raisedTs := time.Now().UnixNano()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000487 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530488 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700489 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530490 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700491 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000492 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000493 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530494 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000495 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800496 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000497 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800498 }
499 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700500}
501
David K. Bainbridge794735f2020-02-11 21:01:37 -0800502// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530503func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Devmalya Paulfb990a52019-07-09 10:01:49 -0400504 raisedTs := time.Now().UnixNano()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700505 switch indication.Data.(type) {
506 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000507 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
508 defer span.Finish()
509
David K. Bainbridge794735f2020-02-11 21:01:37 -0800510 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400511 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800512 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700513 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000514 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
515 defer span.Finish()
516
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700517 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800518 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000519 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400520 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800521 }
522 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000523 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700524 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000525 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
526 defer span.Finish()
527
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700528 intfOperInd := indication.GetIntfOperInd()
529 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800530 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000531 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400532 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-nni", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800533 }
534 }()
Kent Hagermane6ff1012020-07-14 15:07:53 -0400535 if err := dh.resourceMgr.AddNNIToKVStore(ctx, intfOperInd.GetIntfId()); err != nil {
536 logger.Warn(ctx, err)
537 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700538 } else if intfOperInd.GetType() == "pon" {
539 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
540 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800541 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000542 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400543 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface-oper-pon", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800544 }
545 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000546 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700547 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000548 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530549 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530550 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700551 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000552 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
553 defer span.Finish()
554
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700555 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000556 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700557 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800558 //put message to channel and return immediately
559 dh.putOnuIndicationToChannel(ctx, indication, sn)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700560 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000561 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
562 defer span.Finish()
563
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700564 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000565 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800566 sn := dh.stringifySerialNumber(onuInd.SerialNumber)
567 //put message to channel and return immediately
568 dh.putOnuIndicationToChannel(ctx, indication, sn)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700569 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000570 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
571 defer span.Finish()
572
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700573 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000574 logger.Debugw(ctx, "received-omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800575 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000576 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400577 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800578 }
579 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700580 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000581 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
582 defer span.Finish()
583
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700584 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000585 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700586 "intf-type": pktInd.IntfId,
587 "intf-id": pktInd.IntfId,
588 "gem-port-id": pktInd.GemportId,
589 "port-no": pktInd.PortNo,
590 "device-id": dh.device.Id,
591 })
592
593 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000594 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700595 "intf-type": pktInd.IntfId,
596 "intf-id": pktInd.IntfId,
597 "gem-port-id": pktInd.GemportId,
598 "port-no": pktInd.PortNo,
599 "packet": hex.EncodeToString(pktInd.Pkt),
600 "device-id": dh.device.Id,
601 })
602 }
603
David K. Bainbridge794735f2020-02-11 21:01:37 -0800604 go func() {
605 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400606 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800607 }
608 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700609 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000610 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
611 defer span.Finish()
612
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700613 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700614 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700615 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000616 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
617 defer span.Finish()
618
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700619 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000620 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700621 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000622 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
623 defer span.Finish()
624
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700625 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000626 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
627 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700628 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530629}
630
631// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530632func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530633 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000634 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530635
Girish Gowdru0c588b22019-04-23 23:24:56 -0400636 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530637 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400638 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000639 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400640 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000641
642 //Clear olt communication failure event
643 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
644 dh.device.OperStatus = voltha.OperStatus_ACTIVE
645 raisedTs := time.Now().UnixNano()
646 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
647
Girish Gowdru0c588b22019-04-23 23:24:56 -0400648 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530649}
650
651// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530652func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
serkant.uluderya245caba2019-09-24 23:15:29 -0700653 dh.lockDevice.Lock()
654 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000655 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400656
npujarec5762e2020-01-01 14:08:48 +0530657 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400658 if err != nil || device == nil {
659 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000660 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400661 }
662
663 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400664
665 //Update the device oper state and connection status
666 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrud4245152019-05-10 00:47:31 -0400667 dh.device = cloned
668
David K. Bainbridge794735f2020-02-11 21:01:37 -0800669 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000670 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400671 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400672
673 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530674 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400675 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000676 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400677 }
678 for _, onuDevice := range onuDevices.Items {
679
680 // Update onu state as down in onu adapter
681 onuInd := oop.OnuIndication{}
682 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800683 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300684 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800685 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400686 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300687 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800688 "onu-indicator": onuInd,
689 "device-type": onuDevice.Type,
690 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700691 //Do not return here and continue to process other ONUs
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700692 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400693 }
serkant.uluderya245caba2019-09-24 23:15:29 -0700694 /* Discovered ONUs entries need to be cleared , since after OLT
695 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530696 dh.discOnus = sync.Map{}
Neha Sharma96b7bf22020-06-15 10:37:32 +0000697 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700698 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530699}
700
701// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530702func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400703 var err error
Girish Kumar93e91742020-07-27 16:43:19 +0000704 // Use Intercepters to automatically inject and publish Open Tracing Spans by this GRPC client
705 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
706 grpc.WithInsecure(),
707 grpc.WithBlock(),
708 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000709 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000710 )),
711 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000712 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000713 )))
714
715 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530716 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530717 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000718 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400719 }
720 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530721}
722
723// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530724func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400725 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530726 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400727 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530728}
729
730// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530731func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530732 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000733 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400734
735 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530736 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
737 if err != nil || device == nil {
738 /*TODO: needs to handle error scenarios */
739 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
740 }
741 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000742 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400743
744 cloned := proto.Clone(device).(*voltha.Device)
745 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
746 cloned.OperStatus = voltha.OperStatus_UNKNOWN
747 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530748 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
749 return olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400750 }
751
Chaitrashree G S44124192019-08-07 20:21:36 -0400752 // Since the device was disabled before the OLT was rebooted, enforce the OLT to be Disabled after re-connection.
npujarec5762e2020-01-01 14:08:48 +0530753 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400754 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530755 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400756 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400757 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
758 // all the modules initialized and ready to handle incoming ONUs.
759
Thomas Lee S985938d2020-05-04 11:40:41 +0530760 err = dh.initializeDeviceHandlerModules(ctx)
761 if err != nil {
762 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400763 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400764
765 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800766 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530767 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400768 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800769 }
770 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700771
772 go startHeartbeatCheck(ctx, dh)
773
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400774 return nil
775 }
776
Neha Sharma8f4e4322020-08-06 10:51:53 +0000777 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400778 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400779 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400780 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400781 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400782 dh.populateActivePorts(ctx, ports)
783 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
784 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400785 }
786
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400787 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530788 return olterrors.NewErrAdapter("device-handler-initialization-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400789 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530790
cuilin20187b2a8c32019-03-26 19:52:28 -0700791 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800792 go func() {
793 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400794 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800795 }
796 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000797 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000798
799 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000800 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000801 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700802
803 go startHeartbeatCheck(ctx, dh)
804
cuilin20187b2a8c32019-03-26 19:52:28 -0700805 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530806}
807
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400808func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000809 deviceInfo, err := dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400810
811 if err != nil {
812 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
813 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700814 dh.totalPonPorts = deviceInfo.GetPonPorts()
815
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400816 // Instantiate resource manager
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800817 if dh.resourceMgr = rsrcMgr.NewResourceMgr(ctx, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, deviceInfo, dh.cm.Backend.PathPrefix); dh.resourceMgr == nil {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400818 return olterrors.ErrResourceManagerInstantiating
819 }
820
Girish Gowdra9602eb42020-09-09 15:50:39 -0700821 dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400822
Girish Gowdra9602eb42020-09-09 15:50:39 -0700823 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
824 for i := range dh.flowMgr {
825 // Instantiate flow manager
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700826 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr, dh.groupMgr, uint32(i)); dh.flowMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700827 return olterrors.ErrResourceManagerInstantiating
828 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400829 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700830
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400831 /* TODO: Instantiate Alarm , stats , BW managers */
832 /* Instantiating Event Manager to handle Alarms and KPIs */
833 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
834
835 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000836 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400837
838 return nil
839
840}
841
Neha Sharma96b7bf22020-06-15 10:37:32 +0000842func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400843 var err error
844 var deviceInfo *oop.DeviceInfo
845
Neha Sharma8f4e4322020-08-06 10:51:53 +0000846 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400847
848 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000849 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400850 }
851 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000852 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400853 }
854
Neha Sharma96b7bf22020-06-15 10:37:32 +0000855 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400856 dh.device.Root = true
857 dh.device.Vendor = deviceInfo.Vendor
858 dh.device.Model = deviceInfo.Model
859 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
860 dh.device.HardwareVersion = deviceInfo.HardwareVersion
861 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
862
863 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000864 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400865 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000866 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400867 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000868 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400869 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000870 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400871 dh.device.MacAddress = genmac
872 } else {
873 dh.device.MacAddress = deviceInfo.DeviceId
874 }
875
876 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000877 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000878 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400879 }
880
881 return deviceInfo, nil
882}
883
Neha Sharma96b7bf22020-06-15 10:37:32 +0000884func startCollector(ctx context.Context, dh *DeviceHandler) {
885 logger.Debugf(ctx, "starting-collector")
Naga Manjunath7615e552019-10-11 22:35:47 +0530886 for {
887 select {
888 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000889 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530890 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000891 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700892
Neha Sharma8f4e4322020-08-06 10:51:53 +0000893 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400894 if err != nil {
895 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "error": err})
896 continue
897 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530898 for _, port := range ports {
899 // NNI Stats
900 if port.Type == voltha.Port_ETHERNET_NNI {
901 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
902 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000903 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000904 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000905 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530906 }
907 // PON Stats
908 if port.Type == voltha.Port_PON_OLT {
909 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
910 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
911 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000912 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000913 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530914 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000915 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000916
917 //ONU & Gem Stats
918 onuGemInfo := dh.flowMgr[intfID].onuGemInfo
919 if len(onuGemInfo) != 0 {
920 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfo)
921 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500922 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530923 }
924 }
925 }
926}
927
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700928//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530929func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400930 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000931 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530932 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530933
934 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400935 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
936 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530937 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530938}
939
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700940//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530941func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700942 return &ic.SwitchCapability{
943 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530944 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700945 HwDesc: "open_pon",
946 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700947 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700948 },
949 SwitchFeatures: &of.OfpSwitchFeatures{
950 NBuffers: 256,
951 NTables: 2,
952 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
953 of.OfpCapabilities_OFPC_TABLE_STATS |
954 of.OfpCapabilities_OFPC_PORT_STATS |
955 of.OfpCapabilities_OFPC_GROUP_STATS),
956 },
957 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530958}
959
Neha Sharma96b7bf22020-06-15 10:37:32 +0000960func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
961 logger.Debugw(ctx, "omci-indication", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700962 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700963 var deviceID string
964 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700965
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400966 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -0700967 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000968 logger.Debugw(ctx, "recv-omci-msg", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id,
Matteo Scandolo92186242020-06-12 10:54:18 -0700969 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
970 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -0400971
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700972 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530973
974 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
975
Neha Sharma96b7bf22020-06-15 10:37:32 +0000976 logger.Debugw(ctx, "omci-indication-for-a-device-not-in-cache.", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700977 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700978 kwargs := make(map[string]interface{})
979 kwargs["onu_id"] = omciInd.OnuId
980 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -0700981
Neha Sharma8f4e4322020-08-06 10:51:53 +0000982 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700983 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530984 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700985 "intf-id": omciInd.IntfId,
986 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -0700987 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700988 deviceType = onuDevice.Type
989 deviceID = onuDevice.Id
990 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
991 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530992 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700993 } else {
994 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +0000995 logger.Debugw(ctx, "omci-indication-for-a-device-in-cache.", log.Fields{"intf-id": omciInd.IntfId, "onu-id": omciInd.OnuId, "device-id": dh.device.Id})
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530996 deviceType = onuInCache.(*OnuDevice).deviceType
997 deviceID = onuInCache.(*OnuDevice).deviceID
998 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -0700999 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001000
1001 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001002 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001003 ic.InterAdapterMessageType_OMCI_REQUEST, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001004 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301005 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001006 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001007 "destination": deviceType,
1008 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001009 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001010 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001011 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301012}
1013
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001014//ProcessInterAdapterMessage sends the proxied messages to the target device
1015// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1016// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001017func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1018 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001019 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001020 msgID := msg.Header.Id
cuilin20187b2a8c32019-03-26 19:52:28 -07001021 fromTopic := msg.Header.FromTopic
1022 toTopic := msg.Header.ToTopic
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001023 toDeviceID := msg.Header.ToDeviceId
1024 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001025
Neha Sharma96b7bf22020-06-15 10:37:32 +00001026 logger.Debugw(ctx, "omci-request-message-header", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
cuilin20187b2a8c32019-03-26 19:52:28 -07001027
1028 msgBody := msg.GetBody()
1029
1030 omciMsg := &ic.InterAdapterOmciMessage{}
1031 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001032 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001033 }
1034
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001035 if omciMsg.GetProxyAddress() == nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001036 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001037 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301038 return olterrors.NewErrNotFound("onu", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001039 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001040 "onu-device-id": toDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001041 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001042 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1043 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301044 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001045 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001046 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001047 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001048 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001049 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1050 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301051 return olterrors.NewErrCommunication("send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001052 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001053 "onu-device-id": toDeviceID}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001054 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001055 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001056 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001057 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001058 }
1059 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301060}
1061
Neha Sharma96b7bf22020-06-15 10:37:32 +00001062func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001063 var intfID uint32
1064 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001065 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001066 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001067 intfID = onuDevice.ProxyAddress.GetChannelId()
1068 onuID = onuDevice.ProxyAddress.GetOnuId()
1069 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001070 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001071 intfID = omciMsg.GetProxyAddress().GetChannelId()
1072 onuID = omciMsg.GetProxyAddress().GetOnuId()
1073 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001074 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001075 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001076 logger.Debugw(ctx, "onu-not-reachable--cannot-send-omci", log.Fields{"intf-id": intfID, "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001077
Thomas Lee S94109f12020-03-03 16:39:29 +05301078 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001079 "intf-id": intfID,
1080 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001081 }
1082
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001083 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1084 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001085 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001086 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1087 hex.Encode(hexPkt, omciMsg.Message)
1088 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1089
1090 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1091 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1092 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001093 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001094 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001095
Neha Sharma8f4e4322020-08-06 10:51:53 +00001096 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001097 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301098 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001099 "intf-id": intfID,
1100 "onu-id": onuID,
1101 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001102 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001103 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001104}
1105
David K. Bainbridge794735f2020-02-11 21:01:37 -08001106func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301107 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001108 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001109 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001110 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001111 // TODO: need resource manager
1112 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301113 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301114 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001115 st, _ := status.FromError(err)
1116 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001117 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1118
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001119 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301120 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001121 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001122 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001123 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001124 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001125 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001126}
1127
David K. Bainbridge794735f2020-02-11 21:01:37 -08001128func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication, sn string) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001129 channelID := onuDiscInd.GetIntfId()
1130 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001131
Neha Sharma96b7bf22020-06-15 10:37:32 +00001132 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301133
cuilin20187b2a8c32019-03-26 19:52:28 -07001134 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001135 if sn != "" {
1136 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001137 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001138 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001139 }
1140
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301141 var alarmInd oop.OnuAlarmIndication
1142 raisedTs := time.Now().UnixNano()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001143 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301144
1145 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1146 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1147 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1148 OnuLosRaise event sent for it */
1149 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1150 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1151 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001152 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301153 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1154 "currentIntfId": onuDiscInd.GetIntfId()})
1155 // TODO:: Should we need to ignore raising OnuLosClear event
1156 // when onu connected to different PON?
1157 }
1158 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1159 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1160 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001161 go func() {
1162 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
1163 logger.Debugw(ctx, "indication-failed", log.Fields{"error": err})
1164 }
1165 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301166 }
1167 return true
1168 })
1169
Neha Sharma96b7bf22020-06-15 10:37:32 +00001170 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001171 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001172 }
1173
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001174 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001175
1176 // check the ONU is already know to the OLT
1177 // NOTE the second time the ONU is discovered this should return a device
1178 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1179
1180 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001181 logger.Debugw(ctx, "core-proxy-get-child-device-failed", log.Fields{"parentDevice": dh.device.Id, "err": err, "sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001182 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001183 logger.Debugw(ctx, "core-proxy-get-child-device-failed-with-code", log.Fields{"errCode": e.Code(), "sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001184 switch e.Code() {
1185 case codes.Internal:
1186 // this probably means NOT FOUND, so just create a new device
1187 onuDevice = nil
1188 case codes.DeadlineExceeded:
1189 // if the call times out, cleanup and exit
1190 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001191 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001192 }
1193 }
1194 }
1195
1196 if onuDevice == nil {
1197 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001198 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001199 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001200 ponintfid := onuDiscInd.GetIntfId()
npujarec5762e2020-01-01 14:08:48 +05301201 onuID, err = dh.resourceMgr.GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001202
Neha Sharma96b7bf22020-06-15 10:37:32 +00001203 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001204
1205 if err != nil {
1206 // if we can't create an ID in resource manager,
1207 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001208 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001209 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001210 "pon-intf-id": ponintfid,
1211 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001212 }
1213
Neha Sharma8f4e4322020-08-06 10:51:53 +00001214 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001215 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001216 dh.discOnus.Delete(sn)
1217 dh.resourceMgr.FreeonuID(ctx, ponintfid, []uint32{onuID}) // NOTE I'm not sure this method is actually cleaning up the right thing
Thomas Lee S94109f12020-03-03 16:39:29 +05301218 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001219 "pon-intf-id": ponintfid,
1220 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001221 }
Kent Hagermane6ff1012020-07-14 15:07:53 -04001222 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().UnixNano()); err != nil {
1223 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"error": err})
1224 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001225 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301226 log.Fields{"onuDevice": onuDevice,
1227 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001228 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301229 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001230 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001231
1232 // we can now use the existing ONU Id
1233 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001234 //Insert the ONU into cache to use in OnuIndication.
1235 //TODO: Do we need to remove this from the cache on ONU change, or wait for overwritten on next discovery.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001236 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001237 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301238 "intfId": onuDiscInd.GetIntfId(),
1239 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001240 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001241
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301242 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301243 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001244 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301245 log.Fields{"onu": onuDev,
1246 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001247
Kent Hagermane6ff1012020-07-14 15:07:53 -04001248 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301249 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001250 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001251 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001252 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001253 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001254 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301255 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001256 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001257 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001258 }
1259 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001260}
1261
Mahir Gunyel2fb81472020-12-16 23:18:34 -08001262func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication, serialNumber string) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001263
1264 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001265 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001266 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001267 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001268 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001269 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301270 log.Fields{"onuId": onuInd.OnuId,
1271 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301272 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001273 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301274
David K. Bainbridge794735f2020-02-11 21:01:37 -08001275 errFields := log.Fields{"device-id": dh.device.Id}
1276
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301277 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1278
Mahir Gunyele77977b2019-06-27 05:36:22 -07001279 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1280 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001281 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001282 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001283 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001284 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1285 if serialNumber != "" {
1286 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001287 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001288 } else {
1289 kwargs["onu_id"] = onuInd.OnuId
1290 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001291 errFields["onu-id"] = onuInd.OnuId
1292 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001293 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001294 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001295 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001296
David K. Bainbridge794735f2020-02-11 21:01:37 -08001297 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001298 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001299 }
1300
David K. Bainbridge794735f2020-02-11 21:01:37 -08001301 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001302 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001303 "previousIntfId": onuDevice.ParentPortNo,
1304 "currentIntfId": ponPort})
1305 }
1306
1307 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001308 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301309 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1310 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301311 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001312 }
1313 if !foundInCache {
1314 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1315
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301316 dh.onus.Store(onuKey, NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuInd.GetOnuId(), onuInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001317
1318 }
kesavand7cf3a052020-08-28 12:49:18 +05301319 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
1320 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().UnixNano()); err != nil {
1321 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"error": err})
1322 }
1323 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001324 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001325 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001326 }
1327 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001328}
1329
Neha Sharma96b7bf22020-06-15 10:37:32 +00001330func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001331 logger.Debugw(ctx, "onu-indication-for-state", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Girish Gowdra748de5c2020-07-01 10:27:52 -07001332 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1333 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1334 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1335 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001336 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001337 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1338 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001339 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001340 onuInd.OperState = "down"
1341 }
1342 }
1343
David K. Bainbridge794735f2020-02-11 21:01:37 -08001344 switch onuInd.OperState {
1345 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001346 logger.Debugw(ctx, "sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001347 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301348 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001349 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001350 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301351 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001352 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001353 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001354 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001355 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001356 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001357 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001358 logger.Debugw(ctx, "sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Matt Jeanneret53539512019-07-20 14:47:02 -04001359 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301360 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001361 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001362 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301363 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001364 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001365 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001366 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001367 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001368 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001369 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001370 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001371 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001372 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001373}
1374
cuilin20187b2a8c32019-03-26 19:52:28 -07001375func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1376 if serialNum != nil {
1377 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001378 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001379 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001380}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001381func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1382 decodedStr, err := hex.DecodeString(serialNum[4:])
1383 if err != nil {
1384 return nil, err
1385 }
1386 return &oop.SerialNumber{
1387 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001388 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001389 }, nil
1390}
cuilin20187b2a8c32019-03-26 19:52:28 -07001391
1392func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
1393 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001394 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
cuilin20187b2a8c32019-03-26 19:52:28 -07001395 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1396 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1397 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1398 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1399 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1400 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1401 return tmp
1402}
1403
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001404//UpdateFlowsBulk upates the bulk flow
1405func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301406 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001407}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001408
1409//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001410func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1411 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301412 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001413 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301414 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001415 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001416 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001417 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001418 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001419 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001420 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001421 "intf-id": parentPort,
1422 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001423 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001424 logger.Debugw(ctx, "successfully-received-child-device-from-core", log.Fields{"child-device-id": onuDevice.Id, "child-device-sn": onuDevice.SerialNumber})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001425 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301426}
1427
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001428// SendPacketInToCore sends packet-in to core
1429// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1430// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001431func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001432 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001433 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001434 "port": logicalPort,
1435 "packet": hex.EncodeToString(packetPayload),
1436 "device-id": dh.device.Id,
1437 })
1438 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001439 if err := dh.coreProxy.SendPacketIn(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, logicalPort, packetPayload); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301440 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001441 "source": "adapter",
1442 "destination": "core",
1443 "device-id": dh.device.Id,
1444 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001445 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001446 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001447 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001448 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001449 "packet": hex.EncodeToString(packetPayload),
1450 "device-id": dh.device.Id,
1451 })
1452 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001453 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001454}
1455
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001456// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001457func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001458 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001459
1460 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1461 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001462 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001463 }
1464
Kent Hagermane6ff1012020-07-14 15:07:53 -04001465 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001466 metrics := dh.metrics.GetSubscriberMetrics()
1467 for _, m := range pmConfigs.Metrics {
1468 metrics[m.Name].Enabled = m.Enabled
1469
1470 }
1471 }
1472}
1473
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001474//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301475func (dh *DeviceHandler) UpdateFlowsIncrementally(ctx context.Context, device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001476 logger.Debugw(ctx, "received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
Andrea Campanellac63bba92020-03-10 17:01:04 +01001477
Girish Gowdra491a9c62021-01-06 16:43:07 -08001478 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001479 var errorsList []error
1480
Girish Gowdru0c588b22019-04-23 23:24:56 -04001481 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001482 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001483 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001484
Neha Sharma96b7bf22020-06-15 10:37:32 +00001485 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301486 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001487 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301488 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001489 if flow_utils.HasGroup(flow) {
1490 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1491 } else {
1492 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1493 }
Girish Gowdracefae192020-03-19 18:14:10 -07001494 if err != nil {
1495 errorsList = append(errorsList, err)
1496 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001497 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301498
1499 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001500 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001501 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301502 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001503 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301504 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001505 if flow_utils.HasGroup(flow) {
1506 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1507 } else {
1508 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1509 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001510 if err != nil {
1511 errorsList = append(errorsList, err)
1512 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301513 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001514 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001515
Girish Gowdracefae192020-03-19 18:14:10 -07001516 // Whether we need to synchronize multicast group adds and modifies like flow add and delete needs to be investigated
Esin Karamanccb714b2019-11-29 15:02:06 +00001517 if groups != nil {
1518 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001519 // err = dh.groupMgr.AddGroup(ctx, group)
1520 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001521 if err != nil {
1522 errorsList = append(errorsList, err)
1523 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001524 }
1525 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001526 // err = dh.groupMgr.ModifyGroup(ctx, group)
1527 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001528 if err != nil {
1529 errorsList = append(errorsList, err)
1530 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001531 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001532 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001533 // err = dh.groupMgr.DeleteGroup(ctx, group)
1534 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001535 if err != nil {
1536 errorsList = append(errorsList, err)
1537 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001538 }
1539 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001540 if len(errorsList) > 0 {
1541 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1542 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001543 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001544 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301545}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001546
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001547//DisableDevice disables the given device
1548//It marks the following for the given device:
1549//Device-Handler Admin-State : down
1550//Device Port-State: UNKNOWN
1551//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001552func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001553 /* On device disable ,admin state update has to be done prior sending request to agent since
1554 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001555 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001556 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001557 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001558 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001559 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001560 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001561 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001562 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001563 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001564 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301565
1566 dh.discOnus = sync.Map{}
1567 dh.onus = sync.Map{}
1568
Thomas Lee S85f37312020-04-03 17:06:12 +05301569 //stopping the stats collector
1570 dh.stopCollector <- true
1571
Neha Sharma96b7bf22020-06-15 10:37:32 +00001572 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001573 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301574 //Update device Admin state
1575 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001576 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
Neha Sharma8f4e4322020-08-06 10:51:53 +00001577 if err := dh.coreProxy.PortsStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), cloned.Id, ^uint32(1<<voltha.Port_PON_OLT), voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001578 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001579 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001580 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001581 return nil
1582}
1583
Neha Sharma96b7bf22020-06-15 10:37:32 +00001584func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001585 // Update onu state as unreachable in onu adapter
1586 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301587 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001588 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001589 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001590 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001591 logger.Errorw(ctx, "failed-to-get-child-devices-information", log.Fields{"device-id": dh.device.Id, "error": err})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001592 }
1593 if onuDevices != nil {
1594 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001595 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001596 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001597 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001598 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001599 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001600 }
1601
1602 }
1603 }
1604
1605}
1606
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001607//ReenableDevice re-enables the olt device after disable
1608//It marks the following for the given device:
1609//Device-Handler Admin-State : up
1610//Device Port-State: ACTIVE
1611//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001612func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001613 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301614 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001615 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301616 }
1617 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001618 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001619
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001620 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001621
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001622 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1623 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001624 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001625 }
1626 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001627 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001628 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001629 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001630 device.OperStatus = voltha.OperStatus_ACTIVE
1631 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001632
Neha Sharma8f4e4322020-08-06 10:51:53 +00001633 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), device.Id, device.ConnectStatus, device.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301634 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001635 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001636 "connect-status": device.ConnectStatus,
1637 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001638 }
kesavand39e0aa32020-01-28 20:58:50 -05001639
Neha Sharma96b7bf22020-06-15 10:37:32 +00001640 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001641
1642 return nil
1643}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001644
npujarec5762e2020-01-01 14:08:48 +05301645func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001646 var uniID uint32
1647 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301648 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001649 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001650 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001651 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001652 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001653 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001654 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001655 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301656 tpIDList := dh.resourceMgr.GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001657 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301658 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001659 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001660 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001661 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
npujarec5762e2020-01-01 14:08:48 +05301662 if err = dh.resourceMgr.RemoveMeterIDForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001663 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001664 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001665 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301666 }
npujarec5762e2020-01-01 14:08:48 +05301667 dh.resourceMgr.FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1668 if err = dh.resourceMgr.RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001669 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301670 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001671 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001672 if err = dh.resourceMgr.DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001673 logger.Debugw(ctx, "failed-to-remove-gemport-pkt-in", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001674 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001675 if err = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, onu.IntfID, int32(onu.OnuID), int32(uniID)); err != nil {
1676 logger.Debugw(ctx, "failed-to-remove-flow-for", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
1677 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001678 }
1679 return nil
1680}
1681
npujarec5762e2020-01-01 14:08:48 +05301682func (dh *DeviceHandler) clearNNIData(ctx context.Context) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001683 nniUniID := -1
1684 nniOnuID := -1
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301685
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001686 if dh.resourceMgr == nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301687 return olterrors.NewErrNotFound("resource-manager", log.Fields{"device-id": dh.device.Id}, nil)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001688 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001689 //Free the flow-ids for the NNI port
npujarec5762e2020-01-01 14:08:48 +05301690 nni, err := dh.resourceMgr.GetNNIFromKVStore(ctx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301691 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001692 return olterrors.NewErrPersistence("get", "nni", 0, nil, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001693 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001694 logger.Debugw(ctx, "nni-", log.Fields{"nni": nni})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301695 for _, nniIntfID := range nni {
npujarec5762e2020-01-01 14:08:48 +05301696 dh.resourceMgr.RemoveResourceMap(ctx, nniIntfID, int32(nniOnuID), int32(nniUniID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001697 _ = dh.resourceMgr.RemoveAllFlowsForIntfOnuUniKey(ctx, nniIntfID, -1, -1)
1698
Devmalya Paul495b94a2019-08-27 19:42:00 -04001699 }
npujarec5762e2020-01-01 14:08:48 +05301700 if err = dh.resourceMgr.DelNNiFromKVStore(ctx); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001701 return olterrors.NewErrPersis