blob: 3f23fb43d5c57965f640283b06a64bc3f0d0869c [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 Gowdra8a0bdcd2021-05-13 12:31:04 -070038 "github.com/opencord/voltha-lib-go/v5/pkg/adapters/adapterif"
39 "github.com/opencord/voltha-lib-go/v5/pkg/config"
40 "github.com/opencord/voltha-lib-go/v5/pkg/events/eventif"
41 flow_utils "github.com/opencord/voltha-lib-go/v5/pkg/flows"
42 "github.com/opencord/voltha-lib-go/v5/pkg/log"
43 "github.com/opencord/voltha-lib-go/v5/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
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070085 resourceMgr []*rsrcMgr.OpenOltResourceMgr
86
87 deviceInfo *oop.DeviceInfo
Naga Manjunatha8dc9372019-10-31 23:01:18 +053088
Girish Gowdra3ab6d212020-03-24 17:33:15 -070089 discOnus sync.Map
90 onus sync.Map
91 portStats *OpenOltStatisticsMgr
92 metrics *pmmetrics.PmMetrics
93 stopCollector chan bool
94 stopHeartbeatCheck chan bool
95 activePorts sync.Map
96 stopIndications chan bool
97 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070098
Mahir Gunyelb0046752021-02-26 13:51:05 -080099 totalPonPorts uint32
100 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
101 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800102
103 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
104 // A go routine per index, waits on a unique channel for incoming mcast flow or group (add/modify/remove).
105 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
Gamze Abakac2c32a62021-03-11 11:44:18 +0000106
107 adapterPreviouslyConnected bool
108 agentPreviouslyConnected bool
Girish Gowdra1cd96d82021-11-05 09:56:26 -0700109
110 isDeviceDeletionInProgress bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700111}
112
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700113//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700114type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700115 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700116 deviceType string
117 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700118 onuID uint32
119 intfID uint32
120 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530121 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400122 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700123}
124
Mahir Gunyelb0046752021-02-26 13:51:05 -0800125type onuIndicationMsg struct {
126 ctx context.Context
127 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800128}
129
130type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800131 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800132 stopChannel chan struct{}
133}
134
Girish Gowdra491a9c62021-01-06 16:43:07 -0800135//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
136//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
137//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
138//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
139type McastFlowOrGroupControlBlock struct {
140 ctx context.Context // Flow/group handler context
141 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
142 flow *voltha.OfpFlowStats // Flow message (can be nil or valid flow)
143 group *voltha.OfpGroupEntry // Group message (can be nil or valid group)
144 errChan *chan error // channel to report the mcast Flow/group handling error
145}
146
Naga Manjunath7615e552019-10-11 22:35:47 +0530147var pmNames = []string{
148 "rx_bytes",
149 "rx_packets",
150 "rx_mcast_packets",
151 "rx_bcast_packets",
152 "tx_bytes",
153 "tx_packets",
154 "tx_mcast_packets",
155 "tx_bcast_packets",
156}
157
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700158//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530159func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700160 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700161 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700162 device.deviceType = deviceTp
163 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700164 device.onuID = onuID
165 device.intfID = intfID
166 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530167 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700168 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530169}
170
171//NewDeviceHandler creates a new device handler
Himani Chawlacd407802020-12-10 12:08:59 +0530172func 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 -0700173 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800174 dh.cm = cm
cuilin20187b2a8c32019-03-26 19:52:28 -0700175 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400176 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400177 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700178 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700179 dh.device = cloned
180 dh.openOLT = adapter
181 dh.exitChannel = make(chan int, 1)
182 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530183 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530184 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530185 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 -0500186 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400187 dh.stopIndications = make(chan bool, 1)
Mahir Gunyelb0046752021-02-26 13:51:05 -0800188 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800189 // Create a slice of buffered channels for handling concurrent mcast flow/group.
190 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
191 for i := range dh.incomingMcastFlowOrGroup {
192 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
193 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
194 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
195 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
196 // for incoming mcast flow/group to be processed serially.
197 go dh.mcastFlowOrGroupChannelHandlerRoutine(dh.incomingMcastFlowOrGroup[i])
198 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700199 //TODO initialize the support classes.
200 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530201}
202
203// start save the device to the data model
204func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700205 dh.lockDevice.Lock()
206 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000207 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700208 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000209 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530210}
211
212// stop stops the device dh. Not much to do for now
213func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700214 dh.lockDevice.Lock()
215 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000216 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700217 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000218 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530219}
220
ssiddiqui5dcd2312021-08-23 21:58:25 +0530221func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
222 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
223 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
224 if pooledIntfID == intfID {
225 return resourceRanges.GetTechnology()
226 }
227 }
228 }
229 return ""
230}
231
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400232func macifyIP(ip net.IP) string {
233 if len(ip) > 0 {
234 oct1 := strconv.FormatInt(int64(ip[12]), 16)
235 oct2 := strconv.FormatInt(int64(ip[13]), 16)
236 oct3 := strconv.FormatInt(int64(ip[14]), 16)
237 oct4 := strconv.FormatInt(int64(ip[15]), 16)
238 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
239 }
240 return ""
241}
242
Neha Sharma96b7bf22020-06-15 10:37:32 +0000243func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400244 var genmac string
245 var addr net.IP
246 var ips []string
247 var err error
248
Neha Sharma96b7bf22020-06-15 10:37:32 +0000249 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400250
251 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000252 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400253
254 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000255 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400256 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000257 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400258 }
259 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000260 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530261 log.Fields{"host": ips[0],
262 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400263 return genmac, nil
264 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000265 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400266 }
267
268 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000269 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530270 log.Fields{"host": host,
271 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400272 return genmac, nil
273}
274
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530275func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700276 slist := strings.Split(mac, ":")
277 result := make([]uint32, len(slist))
278 var err error
279 var tmp int64
280 for index, val := range slist {
281 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
282 return []uint32{1, 2, 3, 4, 5, 6}
283 }
284 result[index] = uint32(tmp)
285 }
286 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530287}
288
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700289//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 -0800290func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530291
David K. Bainbridge794735f2020-02-11 21:01:37 -0800292 switch portType {
293 case voltha.Port_ETHERNET_NNI:
294 return fmt.Sprintf("nni-%d", portNum), nil
295 case voltha.Port_PON_OLT:
296 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700297 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800298
Girish Kumarf26e4882020-03-05 06:49:10 +0000299 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530300}
301
Neha Sharma96b7bf22020-06-15 10:37:32 +0000302func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000303 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700304 if state == "up" {
305 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500306 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500307 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700308 } else {
309 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500310 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700311 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700312 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400313 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800314 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000315 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400316 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500317
Neha Sharma8f4e4322020-08-06 10:51:53 +0000318 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 +0000319 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000320 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 -0400321 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
322 "device-id": dh.device.Id,
323 "port-type": portType,
324 "port-number": portNum,
325 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500326 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400327 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500328 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400329 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700330 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400331 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700332 PortNo: portNum,
333 Label: label,
334 Type: portType,
335 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700336 OfpPort: &of.OfpPort{
337 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
338 Config: 0,
339 State: uint32(of.OfpPortState_OFPPS_LIVE),
340 Curr: capacity,
341 Advertised: capacity,
342 Peer: capacity,
343 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
344 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
345 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700346 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000347 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700348 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000349 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000350 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800351 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000352 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400353 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000354 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530355 return nil
356}
357
Kent Hagermane6ff1012020-07-14 15:07:53 -0400358func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000359 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530360 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400361 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
362 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530363 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800364 dh.lockDevice.Lock()
365 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530366 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530367}
368
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700369// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530370// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800371func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000372 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700373 defer func() {
374 dh.lockDevice.Lock()
375 dh.isReadIndicationRoutineActive = false
376 dh.lockDevice.Unlock()
377 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700378 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700379 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700380 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700381 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400382
David Bainbridgef5879ca2019-12-13 21:17:54 +0000383 // Create an exponential backoff around re-enabling indications. The
384 // maximum elapsed time for the back off is set to 0 so that we will
385 // continue to retry. The max interval defaults to 1m, but is set
386 // here for code clarity
387 indicationBackoff := backoff.NewExponentialBackOff()
388 indicationBackoff.MaxElapsedTime = 0
389 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700390
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700391 dh.lockDevice.Lock()
392 dh.isReadIndicationRoutineActive = true
393 dh.lockDevice.Unlock()
394
Girish Gowdra3f974912020-03-23 20:35:18 -0700395Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700396 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400397 select {
398 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000399 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700400 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400401 default:
402 indication, err := indications.Recv()
403 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000404 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530405 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530406 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400407 // Use an exponential back off to prevent getting into a tight loop
408 duration := indicationBackoff.NextBackOff()
409 if duration == backoff.Stop {
410 // If we reach a maximum then warn and reset the backoff
411 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000412 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530413 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530414 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400415 indicationBackoff.Reset()
416 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700417
418 // On failure process a backoff timer while watching for stopIndications
419 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700420 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700421 select {
422 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000423 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700424 if !backoffTimer.Stop() {
425 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700426 }
427 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700428 case <-backoffTimer.C:
429 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700430 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700431 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
432 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400433 }
434 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000435 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530436 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000437 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530438 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530439 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700440 // Close the stream, and re-initialize it
441 if err = indications.CloseSend(); err != nil {
442 // Ok to ignore here, because we landed here due to a problem on the stream
443 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000444 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530445 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530446 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700447 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000448 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700449 return err
450 }
451 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400452 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530453 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400454 // Reset backoff if we have a successful receive
455 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400456 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700457 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000458 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530459 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530460 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400461 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400462 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400463 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700464 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700465 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700466 // Close the send stream
467 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700468
Girish Gowdra3f974912020-03-23 20:35:18 -0700469 return nil
470}
471
472func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700473 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700474 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
475 if err != nil {
476 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
477 }
478 if indications == nil {
479 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
480 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700481 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700482 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400483}
484
485// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
486func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
487 switch indication.Data.(type) {
488 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
489 return true
490
491 default:
492 return false
493 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700494}
495
David K. Bainbridge794735f2020-02-11 21:01:37 -0800496func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700497 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000498 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530499 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700500 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530501 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700502 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000503 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000504 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530505 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000506 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800507 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000508 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800509 }
510 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700511}
512
David K. Bainbridge794735f2020-02-11 21:01:37 -0800513// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530514func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700515 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700516 switch indication.Data.(type) {
517 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000518 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
519 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700520 logger.Infow(ctx, "received olt indication", log.Fields{"device-id": dh.device.Id, "olt-ind": indication.GetOltInd()})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800521 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400522 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800523 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700524 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000525 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
526 defer span.Finish()
527
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700528 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800529 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000530 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400531 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800532 }
533 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000534 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700535 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000536 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
537 defer span.Finish()
538
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700539 intfOperInd := indication.GetIntfOperInd()
540 if intfOperInd.GetType() == "nni" {
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_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400543 _ = 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 -0800544 }
545 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700546 } else if intfOperInd.GetType() == "pon" {
547 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
548 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800549 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000550 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400551 _ = 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 -0800552 }
553 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000554 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700555 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000556 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530557 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530558 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700559 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000560 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
561 defer span.Finish()
562
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700563 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000564 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800565 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800566 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700567 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000568 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
569 defer span.Finish()
570
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700571 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000572 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800573 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800574 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700575 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000576 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
577 defer span.Finish()
578
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700579 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000580 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 -0800581 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000582 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400583 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800584 }
585 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700586 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000587 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
588 defer span.Finish()
589
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700590 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000591 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700592 "intf-type": pktInd.IntfId,
593 "intf-id": pktInd.IntfId,
594 "gem-port-id": pktInd.GemportId,
595 "port-no": pktInd.PortNo,
596 "device-id": dh.device.Id,
597 })
598
599 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000600 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700601 "intf-type": pktInd.IntfId,
602 "intf-id": pktInd.IntfId,
603 "gem-port-id": pktInd.GemportId,
604 "port-no": pktInd.PortNo,
605 "packet": hex.EncodeToString(pktInd.Pkt),
606 "device-id": dh.device.Id,
607 })
608 }
609
David K. Bainbridge794735f2020-02-11 21:01:37 -0800610 go func() {
611 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400612 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800613 }
614 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700615 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000616 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
617 defer span.Finish()
618
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700619 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700620 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700621 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000622 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
623 defer span.Finish()
624
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700625 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000626 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700627 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000628 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
629 defer span.Finish()
630
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700631 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000632 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
633 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700634 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530635}
636
637// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530638func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530639 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000640 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530641
Girish Gowdru0c588b22019-04-23 23:24:56 -0400642 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530643 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400644 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000645 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400646 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000647
648 //Clear olt communication failure event
649 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
650 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700651 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000652 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
653
Gamze Abakac2c32a62021-03-11 11:44:18 +0000654 //check adapter and agent reconcile status
655 //reboot olt if needed (olt disconnection case)
656 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
657 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
658 log.Fields{
659 "device-id": dh.device.Id,
660 "adapter-status": dh.adapterPreviouslyConnected,
661 "agent-status": dh.agentPreviouslyConnected,
662 })
663 _ = dh.RebootDevice(ctx, dh.device)
664 }
665
Girish Gowdru0c588b22019-04-23 23:24:56 -0400666 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530667}
668
669// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530670func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000671 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400672
npujarec5762e2020-01-01 14:08:48 +0530673 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400674 if err != nil || device == nil {
675 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000676 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400677 }
678
679 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400680
681 //Update the device oper state and connection status
682 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800683 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400684 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800685 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400686
David K. Bainbridge794735f2020-02-11 21:01:37 -0800687 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000688 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400689 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400690
691 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530692 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400693 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000694 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400695 }
696 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400697 // Update onu state as down in onu adapter
698 onuInd := oop.OnuIndication{}
699 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800700 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300701 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800702 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400703 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300704 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800705 "onu-indicator": onuInd,
706 "device-type": onuDevice.Type,
707 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700708 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800709 } else {
710 logger.Debugw(ctx, "sending inter adapter down ind to onu success", log.Fields{"olt-device-id": device.Id, "onu-device-id": onuDevice.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700711 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400712 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800713 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700714 /* Discovered ONUs entries need to be cleared , since after OLT
715 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530716 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800717 dh.lockDevice.Unlock()
718
Neha Sharma96b7bf22020-06-15 10:37:32 +0000719 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700720 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530721}
722
723// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530724func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400725 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000726
727 // if the connection is already available, close the previous connection (olt reboot case)
728 if dh.clientCon != nil {
729 if err = dh.clientCon.Close(); err != nil {
730 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
731 } else {
732 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
733 }
734 }
735
736 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000737 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
738 grpc.WithInsecure(),
739 grpc.WithBlock(),
740 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000741 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000742 )),
743 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000744 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000745 )))
746
747 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530748 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530749 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000750 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400751 }
752 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530753}
754
755// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530756func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400757 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530758 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400759 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530760}
761
762// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530763func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530764 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000765 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400766
767 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530768 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
769 if err != nil || device == nil {
770 /*TODO: needs to handle error scenarios */
771 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
772 }
773 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000774 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400775
776 cloned := proto.Clone(device).(*voltha.Device)
777 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
778 cloned.OperStatus = voltha.OperStatus_UNKNOWN
779 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530780 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
781 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 -0400782 }
783
Chaitrashree G S44124192019-08-07 20:21:36 -0400784 // 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 +0530785 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400786 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530787 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400788 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400789 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
790 // all the modules initialized and ready to handle incoming ONUs.
791
Thomas Lee S985938d2020-05-04 11:40:41 +0530792 err = dh.initializeDeviceHandlerModules(ctx)
793 if err != nil {
794 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 -0400795 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400796
797 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800798 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530799 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400800 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800801 }
802 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700803
804 go startHeartbeatCheck(ctx, dh)
805
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400806 return nil
807 }
808
Neha Sharma8f4e4322020-08-06 10:51:53 +0000809 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400810 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400811 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400812 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400813 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400814 dh.populateActivePorts(ctx, ports)
815 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
816 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400817 }
818
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400819 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530820 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 -0400821 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530822
cuilin20187b2a8c32019-03-26 19:52:28 -0700823 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800824 go func() {
825 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400826 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800827 }
828 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000829 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000830
831 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000832 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000833 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700834
835 go startHeartbeatCheck(ctx, dh)
836
cuilin20187b2a8c32019-03-26 19:52:28 -0700837 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530838}
839
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400840func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700841 var err error
842 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400843
844 if err != nil {
845 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
846 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700847 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
848 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700849
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700850 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700851 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700852 var i uint32
853 for i = 0; i < dh.totalPonPorts; i++ {
854 // Instantiate resource manager
855 if dh.resourceMgr[i] = rsrcMgr.NewResourceMgr(ctx, i, dh.device.Id, dh.openOLT.KVStoreAddress, dh.openOLT.KVStoreType, dh.device.Type, dh.deviceInfo, dh.cm.Backend.PathPrefix); dh.resourceMgr[i] == nil {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700856 return olterrors.ErrResourceManagerInstantiating
857 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400858 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700859 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
860 // the KV store to manage mcast group data. Provide the first instance (0th index)
861 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
862 return olterrors.ErrGroupManagerInstantiating
863 }
864 for i = 0; i < dh.totalPonPorts; i++ {
865 // Instantiate flow manager
866 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
867 return olterrors.ErrFlowManagerInstantiating
868 }
869 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400870 /* TODO: Instantiate Alarm , stats , BW managers */
871 /* Instantiating Event Manager to handle Alarms and KPIs */
872 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
873
874 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000875 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400876
877 return nil
878
879}
880
Neha Sharma96b7bf22020-06-15 10:37:32 +0000881func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400882 var err error
883 var deviceInfo *oop.DeviceInfo
884
Neha Sharma8f4e4322020-08-06 10:51:53 +0000885 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400886
887 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000888 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400889 }
890 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000891 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400892 }
893
Neha Sharma96b7bf22020-06-15 10:37:32 +0000894 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400895 dh.device.Root = true
896 dh.device.Vendor = deviceInfo.Vendor
897 dh.device.Model = deviceInfo.Model
898 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
899 dh.device.HardwareVersion = deviceInfo.HardwareVersion
900 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
901
902 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000903 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400904 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000905 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400906 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000907 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400908 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000909 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400910 dh.device.MacAddress = genmac
911 } else {
912 dh.device.MacAddress = deviceInfo.DeviceId
913 }
914
915 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000916 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000917 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400918 }
919
920 return deviceInfo, nil
921}
922
Neha Sharma96b7bf22020-06-15 10:37:32 +0000923func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700924 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530925 for {
926 select {
927 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000928 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530929 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000930 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700931
Neha Sharma8f4e4322020-08-06 10:51:53 +0000932 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400933 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700934 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400935 continue
936 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530937 for _, port := range ports {
938 // NNI Stats
939 if port.Type == voltha.Port_ETHERNET_NNI {
940 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
941 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000942 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000943 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000944 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530945 }
946 // PON Stats
947 if port.Type == voltha.Port_PON_OLT {
948 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
949 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
950 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000951 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000952 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530953 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000954 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000955
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700956 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700957 if len(onuGemInfoLst) > 0 {
958 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000959 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500960 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530961 }
962 }
963 }
964}
965
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700966//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530967func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400968 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000969 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530970 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530971
972 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400973 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
974 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530975 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530976}
977
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700978//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530979func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700980 return &ic.SwitchCapability{
981 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530982 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700983 HwDesc: "open_pon",
984 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700985 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700986 },
987 SwitchFeatures: &of.OfpSwitchFeatures{
988 NBuffers: 256,
989 NTables: 2,
990 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
991 of.OfpCapabilities_OFPC_TABLE_STATS |
992 of.OfpCapabilities_OFPC_PORT_STATS |
993 of.OfpCapabilities_OFPC_GROUP_STATS),
994 },
995 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530996}
997
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700998// GetInterAdapterTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
999func (dh *DeviceHandler) GetInterAdapterTechProfileDownloadMessage(ctx context.Context, tpPath string, ponPortNum uint32, onuID uint32, uniID uint32) *ic.InterAdapterTechProfileDownloadMessage {
1000 ifID, err := IntfIDFromPonPortNum(ctx, ponPortNum)
1001 if err != nil {
1002 return nil
1003 }
1004 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, tpPath, ifID, onuID, uniID)
1005}
1006
Neha Sharma96b7bf22020-06-15 10:37:32 +00001007func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
1008 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 -07001009 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001010 var deviceID string
1011 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -07001012
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001013 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001014 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001015 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 -07001016 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1017 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001018
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001019 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301020
1021 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1022
Neha Sharma96b7bf22020-06-15 10:37:32 +00001023 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 -07001024 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001025 kwargs := make(map[string]interface{})
1026 kwargs["onu_id"] = omciInd.OnuId
1027 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -07001028
Neha Sharma8f4e4322020-08-06 10:51:53 +00001029 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001030 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301031 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001032 "intf-id": omciInd.IntfId,
1033 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001034 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001035 deviceType = onuDevice.Type
1036 deviceID = onuDevice.Id
1037 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1038 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301039 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001040 } else {
1041 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001042 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 +05301043 deviceType = onuInCache.(*OnuDevice).deviceType
1044 deviceID = onuInCache.(*OnuDevice).deviceID
1045 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001046 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001047
1048 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001049 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001050 ic.InterAdapterMessageType_OMCI_REQUEST, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001051 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301052 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001053 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001054 "destination": deviceType,
1055 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001056 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001057 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001058 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301059}
1060
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001061//ProcessInterAdapterMessage sends the proxied messages to the target device
1062// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1063// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001064func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1065 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001066 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001067 return dh.handleInterAdapterOmciMsg(ctx, msg)
1068 }
1069 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1070}
cuilin20187b2a8c32019-03-26 19:52:28 -07001071
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001072func (dh *DeviceHandler) handleInterAdapterOmciMsg(ctx context.Context, msg *ic.InterAdapterMessage) error {
1073 msgID := msg.Header.Id
1074 fromTopic := msg.Header.FromTopic
1075 toTopic := msg.Header.ToTopic
1076 toDeviceID := msg.Header.ToDeviceId
1077 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001078
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001079 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 -07001080
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001081 msgBody := msg.GetBody()
1082
1083 omciMsg := &ic.InterAdapterOmciMessage{}
1084 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
1085 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
1086 }
1087
1088 if omciMsg.GetProxyAddress() == nil {
1089 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
1090 if err != nil {
1091 return olterrors.NewErrNotFound("onu", log.Fields{
1092 "device-id": dh.device.Id,
1093 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001094 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001095 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1096 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
1097 return olterrors.NewErrCommunication("send-failed", log.Fields{
1098 "device-id": dh.device.Id,
1099 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001100 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001101 } else {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001102 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1103 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
1104 return olterrors.NewErrCommunication("send-failed", log.Fields{
1105 "device-id": dh.device.Id,
1106 "onu-device-id": toDeviceID}, err)
1107 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001108 }
1109 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301110}
1111
Neha Sharma96b7bf22020-06-15 10:37:32 +00001112func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001113 var intfID uint32
1114 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001115 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001116 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001117 intfID = onuDevice.ProxyAddress.GetChannelId()
1118 onuID = onuDevice.ProxyAddress.GetOnuId()
1119 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001120 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001121 intfID = omciMsg.GetProxyAddress().GetChannelId()
1122 onuID = omciMsg.GetProxyAddress().GetOnuId()
1123 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001124 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001125 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001126 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 -08001127
Thomas Lee S94109f12020-03-03 16:39:29 +05301128 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001129 "intf-id": intfID,
1130 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001131 }
1132
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001133 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1134 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001135 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001136 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1137 hex.Encode(hexPkt, omciMsg.Message)
1138 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1139
1140 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1141 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1142 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001143 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001144 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001145
Neha Sharma8f4e4322020-08-06 10:51:53 +00001146 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001147 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301148 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001149 "intf-id": intfID,
1150 "onu-id": onuID,
1151 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001152 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001153 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001154}
1155
David K. Bainbridge794735f2020-02-11 21:01:37 -08001156func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301157 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 Gowdra37f13fa2021-08-16 10:59:45 -07001158 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001159 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001160 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001161 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301162 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301163 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001164 st, _ := status.FromError(err)
1165 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001166 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1167
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001168 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301169 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001170 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001171 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001172 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001173 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001174 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001175}
1176
Mahir Gunyelb0046752021-02-26 13:51:05 -08001177func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001178 channelID := onuDiscInd.GetIntfId()
1179 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001180
Mahir Gunyelb0046752021-02-26 13:51:05 -08001181 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001182 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301183
cuilin20187b2a8c32019-03-26 19:52:28 -07001184 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001185 if sn != "" {
1186 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001187 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001188 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001189 }
1190
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301191 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001192 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001193 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301194
1195 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1196 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1197 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1198 OnuLosRaise event sent for it */
1199 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1200 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1201 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001202 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301203 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1204 "currentIntfId": onuDiscInd.GetIntfId()})
1205 // TODO:: Should we need to ignore raising OnuLosClear event
1206 // when onu connected to different PON?
1207 }
1208 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1209 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1210 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001211 go func() {
1212 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001213 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001214 }
1215 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301216 }
1217 return true
1218 })
1219
Neha Sharma96b7bf22020-06-15 10:37:32 +00001220 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001221 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001222 }
1223
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001224 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001225
1226 // check the ONU is already know to the OLT
1227 // NOTE the second time the ONU is discovered this should return a device
1228 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1229
1230 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001231 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 -08001232 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001233 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 -08001234 switch e.Code() {
1235 case codes.Internal:
1236 // this probably means NOT FOUND, so just create a new device
1237 onuDevice = nil
1238 case codes.DeadlineExceeded:
1239 // if the call times out, cleanup and exit
1240 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001241 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001242 }
1243 }
1244 }
1245
1246 if onuDevice == nil {
1247 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001248 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001249 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001250 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001251 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001252
Neha Sharma96b7bf22020-06-15 10:37:32 +00001253 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001254
1255 if err != nil {
1256 // if we can't create an ID in resource manager,
1257 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001258 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001259 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001260 "pon-intf-id": ponintfid,
1261 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001262 }
1263
Neha Sharma8f4e4322020-08-06 10:51:53 +00001264 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001265 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001266 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001267 dh.resourceMgr[ponintfid].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 +05301268 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001269 "pon-intf-id": ponintfid,
1270 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001271 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001272 if err := dh.eventMgr.OnuDiscoveryIndication(ctx, onuDiscInd, dh.device.Id, onuDevice.Id, onuID, sn, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001273 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001274 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001275 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301276 log.Fields{"onuDevice": onuDevice,
1277 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001278 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301279 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001280 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001281
1282 // we can now use the existing ONU Id
1283 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001284 //Insert the ONU into cache to use in OnuIndication.
1285 //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 +00001286 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001287 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301288 "intfId": onuDiscInd.GetIntfId(),
1289 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001290 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001291
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301292 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301293 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001294 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301295 log.Fields{"onu": onuDev,
1296 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001297
Kent Hagermane6ff1012020-07-14 15:07:53 -04001298 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301299 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001300 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001301 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001302 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001303 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001304 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301305 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001306 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001307 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001308 }
1309 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001310}
1311
Mahir Gunyelb0046752021-02-26 13:51:05 -08001312func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001313
1314 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001315 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001316 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001317 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001318 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001319 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301320 log.Fields{"onuId": onuInd.OnuId,
1321 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301322 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001323 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001324 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301325
David K. Bainbridge794735f2020-02-11 21:01:37 -08001326 errFields := log.Fields{"device-id": dh.device.Id}
1327
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301328 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1329
Mahir Gunyele77977b2019-06-27 05:36:22 -07001330 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1331 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001332 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001333 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001334 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001335 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1336 if serialNumber != "" {
1337 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001338 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001339 } else {
1340 kwargs["onu_id"] = onuInd.OnuId
1341 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001342 errFields["onu-id"] = onuInd.OnuId
1343 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001344 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001345 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001346 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001347
David K. Bainbridge794735f2020-02-11 21:01:37 -08001348 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001349 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001350 }
1351
David K. Bainbridge794735f2020-02-11 21:01:37 -08001352 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001353 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001354 "previousIntfId": onuDevice.ParentPortNo,
1355 "currentIntfId": ponPort})
1356 }
1357
1358 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001359 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301360 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1361 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301362 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001363 }
1364 if !foundInCache {
1365 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1366
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301367 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 -08001368
1369 }
kesavand7cf3a052020-08-28 12:49:18 +05301370 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001371 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001372 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301373 }
1374 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001375 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001376 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001377 }
1378 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001379}
1380
Neha Sharma96b7bf22020-06-15 10:37:32 +00001381func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001382 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 -07001383 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1384 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1385 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1386 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001387 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001388 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1389 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001390 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001391 onuInd.OperState = "down"
1392 }
1393 }
1394
David K. Bainbridge794735f2020-02-11 21:01:37 -08001395 switch onuInd.OperState {
1396 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001397 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 -07001398 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301399 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001400 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001401 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301402 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001403 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001404 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001405 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001406 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001407 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001408 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001409 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 -04001410 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301411 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001412 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001413 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301414 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001415 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001416 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001417 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001418 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001419 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001420 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001421 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001422 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001423 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001424}
1425
cuilin20187b2a8c32019-03-26 19:52:28 -07001426func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1427 if serialNum != nil {
1428 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001429 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001430 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001431}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001432func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1433 decodedStr, err := hex.DecodeString(serialNum[4:])
1434 if err != nil {
1435 return nil, err
1436 }
1437 return &oop.SerialNumber{
1438 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001439 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001440 }, nil
1441}
cuilin20187b2a8c32019-03-26 19:52:28 -07001442
1443func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001444 if len(vendorSpecific) > 3 {
1445 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1446 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1447 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1448 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1449 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1450 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1451 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1452 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1453 return tmp
1454 }
1455 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001456}
1457
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001458//UpdateFlowsBulk upates the bulk flow
1459func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301460 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001461}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001462
1463//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001464func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1465 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301466 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001467 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301468 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001469 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001470 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001471 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001472 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001473 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001474 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001475 "intf-id": parentPort,
1476 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001477 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001478 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 -08001479 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301480}
1481
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001482// SendPacketInToCore sends packet-in to core
1483// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1484// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001485func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001486 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001487 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001488 "port": logicalPort,
1489 "packet": hex.EncodeToString(packetPayload),
1490 "device-id": dh.device.Id,
1491 })
1492 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001493 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 +05301494 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001495 "source": "adapter",
1496 "destination": "core",
1497 "device-id": dh.device.Id,
1498 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001499 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001500 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001501 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001502 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001503 "packet": hex.EncodeToString(packetPayload),
1504 "device-id": dh.device.Id,
1505 })
1506 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001507 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001508}
1509
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001510// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001511func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001512 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001513
1514 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1515 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001516 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001517 }
1518
Kent Hagermane6ff1012020-07-14 15:07:53 -04001519 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001520 metrics := dh.metrics.GetSubscriberMetrics()
1521 for _, m := range pmConfigs.Metrics {
1522 metrics[m.Name].Enabled = m.Enabled
1523
1524 }
1525 }
1526}
1527
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001528//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301529func (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 +00001530 logger.Debugw(ctx, "received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001531 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001532 var errorsList []error
1533
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001534 if dh.getDeviceDeletionInProgressFlag() {
1535 // The device itself is going to be reset as part of deletion. So nothing to be done.
1536 logger.Infow(ctx, "device-deletion-in-progress--not-handling-flows-or-groups", log.Fields{"device-id": device.Id})
1537 return nil
1538 }
1539
Girish Gowdru0c588b22019-04-23 23:24:56 -04001540 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001541 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001542 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001543
Neha Sharma96b7bf22020-06-15 10:37:32 +00001544 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301545 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001546 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301547 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001548 if flow_utils.HasGroup(flow) {
1549 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1550 } else {
1551 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1552 }
Girish Gowdracefae192020-03-19 18:14:10 -07001553 if err != nil {
1554 errorsList = append(errorsList, err)
1555 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001556 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301557
1558 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001559 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001560 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301561 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001562 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301563 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001564 if flow_utils.HasGroup(flow) {
1565 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1566 } else {
1567 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1568 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001569 if err != nil {
1570 errorsList = append(errorsList, err)
1571 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301572 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001573 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001574
Girish Gowdracefae192020-03-19 18:14:10 -07001575 // 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 +00001576 if groups != nil {
1577 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001578 // err = dh.groupMgr.AddGroup(ctx, group)
1579 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001580 if err != nil {
1581 errorsList = append(errorsList, err)
1582 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001583 }
1584 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001585 // err = dh.groupMgr.ModifyGroup(ctx, group)
1586 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001587 if err != nil {
1588 errorsList = append(errorsList, err)
1589 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001590 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001591 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001592 // err = dh.groupMgr.DeleteGroup(ctx, group)
1593 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001594 if err != nil {
1595 errorsList = append(errorsList, err)
1596 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001597 }
1598 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001599 if len(errorsList) > 0 {
1600 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1601 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001602 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001603 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301604}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001605
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001606//DisableDevice disables the given device
1607//It marks the following for the given device:
1608//Device-Handler Admin-State : down
1609//Device Port-State: UNKNOWN
1610//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001611func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001612 /* On device disable ,admin state update has to be done prior sending request to agent since
1613 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001614 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001615 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001616 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001617 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001618 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001619 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001620 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001621 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001622 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001623 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301624
1625 dh.discOnus = sync.Map{}
1626 dh.onus = sync.Map{}
1627
Thomas Lee S85f37312020-04-03 17:06:12 +05301628 //stopping the stats collector
1629 dh.stopCollector <- true
1630
Neha Sharma96b7bf22020-06-15 10:37:32 +00001631 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001632 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301633 //Update device Admin state
1634 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001635 // 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 +00001636 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 -04001637 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001638 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001639 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001640 return nil
1641}
1642
Neha Sharma96b7bf22020-06-15 10:37:32 +00001643func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001644 // Update onu state as unreachable in onu adapter
1645 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301646 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001647 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001648 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001649 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001650 logger.Errorw(ctx, "failed-to-get-child-devices-information", log.Fields{"device-id": dh.device.Id, "err": err})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001651 }
1652 if onuDevices != nil {
1653 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001654 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001655 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001656 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001657 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001658 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001659 }
1660
1661 }
1662 }
1663
1664}
1665
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001666//ReenableDevice re-enables the olt device after disable
1667//It marks the following for the given device:
1668//Device-Handler Admin-State : up
1669//Device Port-State: ACTIVE
1670//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001671func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001672 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301673 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001674 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301675 }
1676 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001677 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001678
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001679 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001680
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001681 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1682 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001683 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001684 }
1685 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001686 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001687 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001688 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001689 device.OperStatus = voltha.OperStatus_ACTIVE
1690 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001691
Neha Sharma8f4e4322020-08-06 10:51:53 +00001692 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 +05301693 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001694 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001695 "connect-status": device.ConnectStatus,
1696 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001697 }
kesavand39e0aa32020-01-28 20:58:50 -05001698
Neha Sharma96b7bf22020-06-15 10:37:32 +00001699 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001700
1701 return nil
1702}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001703
npujarec5762e2020-01-01 14:08:48 +05301704func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001705 var uniID uint32
1706 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301707 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001708 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001709 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001710 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001711 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001712 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001713 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001714 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001715 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001716 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001717 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001718 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001719 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001720 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001721 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001722 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001723 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001724 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301725 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001726 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1727 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001728 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301729 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001730 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001731 if err = dh.resourceMgr[onu.IntfID].DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001732 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 +00001733 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001734 }
1735 return nil
1736}
1737
Devmalya Paul495b94a2019-08-27 19:42:00 -04001738// DeleteDevice deletes the device instance from openolt handler array. Also clears allocated resource manager resources. Also reboots the OLT hardware!
npujarec5762e2020-01-01 14:08:48 +05301739func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001740 logger.Debugw(ctx, "function-entry-delete-device", log.Fields{"device-id": dh.device.Id})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001741 /* Clear the KV store data associated with the all the UNI ports
1742 This clears up flow data and also resource map data for various
1743 other pon resources like alloc_id and gemport_id
1744 */
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001745
1746 dh.setDeviceDeletionInProgressFlag(true)
1747
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001748 dh.cleanupDeviceResources(ctx)
1749 logger.Debugw(ctx, "removed-device-from-Resource-manager-KV-store", log.Fields{"device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001750 // Stop the Stats collector
1751 dh.stopCollector <- true
1752 // stop the heartbeat check routine
1753 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301754 dh.lockDevice.RLock()
1755 // Stop the read indication only if it the routine is active
1756 if dh.isReadIndicationRoutineActive {
1757 dh.stopIndications <- true
1758 }
1759 dh.lockDevice.RUnlock()
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001760 dh.removeOnuIndicationChannels(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001761 //Reset the state
1762 if dh.Client != nil {
1763 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301764 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001765 }
1766 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001767 // There is no need to update the core about operation status and connection status of the OLT.
1768 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1769 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1770 // because the device does not exist in DB.
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001771
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001772 return nil
1773}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001774func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001775
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001776 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301777 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001778 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001779 var err error
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001780 onuGemData := dh.flowMgr[ponPort].getOnuGemInfoList(ctx)
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001781 for i, onu := range onuGemData {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001782 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001783 if err = dh.clearUNIData(ctx, &onuGemData[i]); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001784 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301785 }
1786 }
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001787 _ = dh.resourceMgr[ponPort].DeleteAllFlowIDsForGemForIntf(ctx, ponPort)
1788 _ = dh.resourceMgr[ponPort].DeleteAllOnuGemInfoForIntf(ctx, ponPort)
1789
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001790 if err := dh.resourceMgr[ponPort].Delete(ctx, ponPort); err != nil {
1791 logger.Debug(ctx, err)
1792 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001793 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001794 }
A R Karthick1f85b802019-10-11 05:06:05 +00001795
Devmalya Paul495b94a2019-08-27 19:42:00 -04001796 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301797 dh.onus.Range(func(key interface{}, value interface{}) bool {
1798 dh.onus.Delete(key)
1799 return true
1800 })
1801
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001802 /*Delete discovered ONU map for the device*/
1803 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1804 dh.discOnus.Delete(key)
1805 return true
1806 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001807}
1808
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001809//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001810func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001811 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301812 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001813 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001814 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001815 return nil
1816}
1817
David K. Bainbridge794735f2020-02-11 21:01:37 -08001818func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001819 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001820 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001821 "packet-indication": *packetIn,
1822 "device-id": dh.device.Id,
1823 "packet": hex.EncodeToString(packetIn.Pkt),
1824 })
1825 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001826 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001827 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001828 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001829 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001830 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001831 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001832 "logical-port-num": logicalPortNum,
1833 "device-id": dh.device.Id,
1834 "packet": hex.EncodeToString(packetIn.Pkt),
1835 })
1836 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001837
Neha Sharma8f4e4322020-08-06 10:51:53 +00001838 if err := dh.coreProxy.SendPacketIn(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301839 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001840 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301841 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001842 "device-id": dh.device.Id,
1843 "packet": hex.EncodeToString(packetIn.Pkt),
1844 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001845 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001846
Matteo Scandolo92186242020-06-12 10:54:18 -07001847 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001848 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001849 "packet": hex.EncodeToString(packetIn.Pkt),
1850 "device-id": dh.device.Id,
1851 })
1852 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001853 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001854}
1855
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001856// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301857func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001858 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001859 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001860 "device-id": dh.device.Id,
1861 "egress-port-no": egressPortNo,
1862 "pkt-length": len(packet.Data),
1863 "packet": hex.EncodeToString(packet.Data),
1864 })
1865 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001866
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001867 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001868 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001869 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1870 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301871 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1872 // Do not packet-out lldp packets on uni port.
1873 // ONOS has no clue about uni/nni ports, it just packets out on all
1874 // available ports on the Logical Switch. It should not be interested
1875 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001876 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001877 "device-id": dh.device.Id,
1878 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301879 return nil
1880 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001881 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1882 if innerEthType == 0x8100 {
1883 // q-in-q 802.1ad or 802.1q double tagged packet.
1884 // slice out the outer tag.
1885 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001886 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001887 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001888 "packet-data": hex.EncodeToString(packet.Data),
1889 "device-id": dh.device.Id,
1890 })
1891 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001892 }
1893 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001894 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1895 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001896 uniID := UniIDFromPortNum(uint32(egressPortNo))
1897
Girish Gowdra9602eb42020-09-09 15:50:39 -07001898 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001899 if err != nil {
1900 // In this case the openolt agent will receive the gemPortID as 0.
1901 // The agent tries to retrieve the gemPortID in this case.
1902 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001903 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001904 "intf-id": intfID,
1905 "onu-id": onuID,
1906 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001907 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301908 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001909 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001910 }
1911
1912 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001913 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001914 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001915 "egress-port-no": egressPortNo,
1916 "intf-id": intfID,
1917 "onu-id": onuID,
1918 "uni-id": uniID,
1919 "gem-port-id": gemPortID,
1920 "packet": hex.EncodeToString(packet.Data),
1921 "device-id": dh.device.Id,
1922 })
1923 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001924
npujarec5762e2020-01-01 14:08:48 +05301925 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301926 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001927 "source": "adapter",
1928 "destination": "onu",
1929 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001930 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001931 "oni-id": onuID,
1932 "uni-id": uniID,
1933 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001934 "packet": hex.EncodeToString(packet.Data),
1935 "device-id": dh.device.Id,
1936 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001937 }
1938 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001939 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001940 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001941 return olterrors.NewErrInvalidValue(log.Fields{
1942 "egress-nni-port": egressPortNo,
1943 "device-id": dh.device.Id,
1944 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001945 }
1946 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001947
Matteo Scandolo92186242020-06-12 10:54:18 -07001948 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001949 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001950 "uplink-pkt": uplinkPkt,
1951 "packet": hex.EncodeToString(packet.Data),
1952 "device-id": dh.device.Id,
1953 })
1954 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001955
npujarec5762e2020-01-01 14:08:48 +05301956 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001957 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1958 "packet": hex.EncodeToString(packet.Data),
1959 "device-id": dh.device.Id,
1960 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001961 }
1962 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001963 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301964 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001965 "egressPortType": egressPortType,
1966 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301967 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001968 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001969 }
1970 return nil
1971}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001972
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001973func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1974 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001975}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301976
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001977func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001978
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301979 // start the heartbeat check towards the OLT.
1980 var timerCheck *time.Timer
1981
1982 for {
1983 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1984 select {
1985 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001986 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001987 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001988 logger.Warnw(ctx, "heartbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301989 if timerCheck == nil {
1990 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001991 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301992 }
1993 } else {
1994 if timerCheck != nil {
1995 if timerCheck.Stop() {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001996 logger.Debugw(ctx, "got-heartbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301997 }
1998 timerCheck = nil
1999 }
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002000 logger.Debugw(ctx, "heartbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05302001 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05302002 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302003 }
2004 cancel()
2005 case <-dh.stopHeartbeatCheck:
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002006 logger.Debugw(ctx, "stopping-heartbeat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302007 return
2008 }
2009 }
2010}
2011
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002012func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
2013 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
2014 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002015 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2016 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2017 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2018 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2019 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002020 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002021 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2022 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002023 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302024
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002025 logger.Debugw(ctx, "update-state-unreachable", log.Fields{"device-id": dh.device.Id, "connect-status": device.ConnectStatus,
2026 "admin-state": device.AdminState, "oper-status": device.OperStatus})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002027 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
2028 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002029 _ = olterrors.NewErrAdapter("device-state-update-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002030 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002031 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002032 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002033 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002034
2035 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002036 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +00002037 device.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2038 device.OperStatus = voltha.OperStatus_UNKNOWN
2039 go dh.eventMgr.oltCommunicationEvent(ctx, device, raisedTs)
2040
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07002041 dh.cleanupDeviceResources(ctx)
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002042 // Stop the Stats collector
2043 dh.stopCollector <- true
2044 // stop the heartbeat check routine
2045 dh.stopHeartbeatCheck <- true
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002046
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002047 dh.lockDevice.RLock()
2048 // Stop the read indication only if it the routine is active
2049 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2050 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2051 // on next execution of the readIndication routine.
2052 if dh.isReadIndicationRoutineActive {
2053 dh.stopIndications <- true
2054 }
2055 dh.lockDevice.RUnlock()
2056
Gamze Abakac2c32a62021-03-11 11:44:18 +00002057 //reset adapter reconcile flag
2058 dh.adapterPreviouslyConnected = false
2059
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002060 dh.transitionMap.Handle(ctx, DeviceInit)
2061
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302062 }
2063}
kesavand39e0aa32020-01-28 20:58:50 -05002064
2065// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002066func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2067 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2068 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002069}
2070
2071// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002072func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2073 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2074 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002075}
2076
kdarapu1afeceb2020-02-12 01:38:09 -05002077//modifyPhyPort is common function to enable and disable the port. parm :enablePort, true to enablePort and false to disablePort.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002078func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2079 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002080 if port.GetType() == voltha.Port_ETHERNET_NNI {
2081 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002082 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302083 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302084 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002085 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002086 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002087 }
2088 // fetch interfaceid from PortNo
2089 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2090 ponIntf := &oop.Interface{IntfId: ponID}
2091 var operStatus voltha.OperStatus_Types
2092 if enablePort {
2093 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302094 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002095
2096 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302097 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002098 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002099 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002100 }
2101 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002102 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002103 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002104 } else {
2105 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302106 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002107 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302108 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002109 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002110 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002111 }
2112 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002113 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002114 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002115 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302116 if err := dh.coreProxy.PortStateUpdate(ctx, dh.device.Id, voltha.Port_PON_OLT, port.PortNo, operStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302117 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302118 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002119 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002120 }
2121 return nil
2122}
2123
kdarapu1afeceb2020-02-12 01:38:09 -05002124//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002125func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002126 // Disable the port and update the oper_port_status to core
2127 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002128 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002129 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002130 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302131 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302132 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002133 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002134 }
2135 }
2136 }
2137 return nil
2138}
2139
2140//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002141func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2142 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2143 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002144 if port.Type == voltha.Port_ETHERNET_NNI {
2145 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002146 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002147 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002148 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002149 }
2150 }
2151 if port.Type == voltha.Port_PON_OLT {
2152 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002153 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002154 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002155 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002156 }
2157 }
2158 }
2159}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002160
2161// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002162func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002163 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002164 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2165 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002166
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002167 var sn *oop.SerialNumber
2168 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002169 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302170 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002171 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302172 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002173 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002174 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002175
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002176 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002177 //clear PON resources associated with ONU
2178 onuGem, err := dh.resourceMgr[intfID].GetOnuGemInfo(ctx, intfID, onuID)
2179 if err != nil || onuGem == nil || onuGem.OnuID != onuID {
2180 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
2181 "device-id": dh.device.Id,
2182 "intf-id": intfID,
2183 "onuID": onuID,
2184 "err": err})
2185 } else {
2186 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
2187 if err := dh.clearUNIData(ctx, onuGem); err != nil {
2188 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
2189 "device-id": dh.device.Id,
2190 "onu-device": onu,
2191 "err": err})
2192 }
2193 // Clear flowids for gem cache.
2194 for _, gem := range onuGem.GemPorts {
2195 dh.resourceMgr[intfID].DeleteFlowIDsForGem(ctx, intfID, gem)
2196 }
Girish Gowdra37f13fa2021-08-16 10:59:45 -07002197 if err := dh.flowMgr[intfID].RemoveOnuInfoFromFlowMgrCacheAndKvStore(ctx, intfID, onuID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002198 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
2199 "intf-id": intfID,
2200 "onu-device": onu,
2201 "onu-gem": onuGem,
2202 "err": err})
2203 //Not returning error on cleanup.
2204 }
2205 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGem})
2206 dh.resourceMgr[intfID].FreeonuID(ctx, intfID, []uint32{onuGem.OnuID})
2207 }
2208 dh.onus.Delete(onuKey)
2209 dh.discOnus.Delete(onuSn)
2210
2211 // Now clear the ONU on the OLT
Neha Sharma8f4e4322020-08-06 10:51:53 +00002212 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302213 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302214 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002215 "onu-id": onuID}, err).Log()
2216 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002217
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002218 return nil
2219}
Girish Gowdracefae192020-03-19 18:14:10 -07002220
2221func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002222 for _, field := range flow_utils.GetOfbFields(flow) {
2223 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002224 return field.GetPort()
2225 }
2226 }
2227 return InvalidPort
2228}
2229
2230func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002231 for _, action := range flow_utils.GetActions(flow) {
2232 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002233 if out := action.GetOutput(); out != nil {
2234 return out.GetPort()
2235 }
2236 }
2237 }
2238 return InvalidPort
2239}
2240
Girish Gowdracefae192020-03-19 18:14:10 -07002241func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2242 inPort := getInPortFromFlow(flow)
2243 outPort := getOutPortFromFlow(flow)
2244
2245 if inPort == InvalidPort || outPort == InvalidPort {
2246 return inPort, outPort
2247 }
2248
2249 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2250 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2251 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002252 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002253 return uniPort, outPort
2254 }
2255 }
2256 } else {
2257 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2258 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002259 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002260 return inPort, uniPort
2261 }
2262 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2263 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002264 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002265 return uniPort, outPort
2266 }
2267 }
2268 }
2269
2270 return InvalidPort, InvalidPort
2271}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002272
2273func extractOmciTransactionID(omciPkt []byte) uint16 {
2274 if len(omciPkt) > 3 {
2275 d := omciPkt[0:2]
2276 transid := binary.BigEndian.Uint16(d)
2277 return transid
2278 }
2279 return 0
2280}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002281
2282// StoreOnuDevice stores the onu parameters to the local cache.
2283func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2284 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2285 dh.onus.Store(onuKey, onuDevice)
2286}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002287
Neha Sharma8f4e4322020-08-06 10:51:53 +00002288func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002289 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002290 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002291 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002292 resp := new(voltha.ReturnValues)
2293 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002294 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002295 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002296 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2297 return nil, err
2298 }
2299 ID = device.ProxyAddress.GetOnuId()
2300 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2301 valueparam.Onu = &Onu
2302 valueparam.Value = value
2303
2304 // This API is unsupported until agent patch is added
2305 resp.Unsupported = uint32(value)
2306 _ = ctx
2307
2308 // Uncomment this code once agent changes are complete and tests
2309 /*
2310 resp, err = dh.Client.GetValue(ctx, valueparam)
2311 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002312 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "err": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002313 return nil, err
2314 }
2315 */
2316
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002317 logger.Infow(ctx, "get-ext-value", log.Fields{"resp": resp, "device-id": dh.device, "onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002318 return resp, nil
2319}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002320
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002321func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002322 // Default to PON0
2323 var intfID uint32
2324 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002325 if inPort != InvalidPort && outPort != InvalidPort {
2326 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2327 }
2328 return intfID
2329}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002330
Mahir Gunyelb0046752021-02-26 13:51:05 -08002331func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2332 dh.perPonOnuIndicationChannelLock.Lock()
2333 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2334 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002335 return ch.indicationChannel
2336 }
2337 channels := onuIndicationChannels{
2338 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002339 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002340 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002341 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002342 stopChannel: make(chan struct{}),
2343 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002344 dh.perPonOnuIndicationChannel[intfID] = channels
2345 dh.perPonOnuIndicationChannelLock.Unlock()
2346 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002347 return channels.indicationChannel
2348
2349}
2350
Mahir Gunyelb0046752021-02-26 13:51:05 -08002351func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2352 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2353 dh.perPonOnuIndicationChannelLock.Lock()
2354 defer dh.perPonOnuIndicationChannelLock.Unlock()
2355 for _, v := range dh.perPonOnuIndicationChannel {
2356 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002357 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002358 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002359}
2360
Mahir Gunyelb0046752021-02-26 13:51:05 -08002361func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2362 ind := onuIndicationMsg{
2363 ctx: ctx,
2364 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002365 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002366 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002367 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002368 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002369}
2370
Mahir Gunyelb0046752021-02-26 13:51:05 -08002371func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002372 for {
2373 select {
2374 // process one indication per onu, before proceeding to the next one
2375 case onuInd := <-onuChannels.indicationChannel:
2376 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002377 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002378 switch onuInd.indication.Data.(type) {
2379 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002380 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002381 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2382 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002383 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002384 }
2385 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002386 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002387 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2388 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002389 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002390 }
2391 }
2392 case <-onuChannels.stopChannel:
2393 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2394 close(onuChannels.indicationChannel)
2395 return
2396 }
2397 }
2398}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002399
2400// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2401// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2402func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2403 // Step1 : Fill McastFlowOrGroupControlBlock
2404 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2405 // Step3 : Wait on response channel for response
2406 // Step4 : Return error value
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002407 startTime := time.Now()
Girish Gowdra491a9c62021-01-06 16:43:07 -08002408 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2409 errChan := make(chan error)
2410 var groupID uint32
2411 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2412 ctx: ctx,
2413 flowOrGroupAction: action,
2414 flow: flow,
2415 group: group,
2416 errChan: &errChan,
2417 }
2418 if flow != nil {
2419 groupID = flow_utils.GetGroup(flow)
2420 } else if group != nil {
2421 groupID = group.Desc.GroupId
2422 } else {
2423 return errors.New("flow-and-group-both-nil")
2424 }
2425 // Derive the appropriate go routine to handle the request by a simple module operation.
2426 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2427 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2428 // Wait for handler to return error value
2429 err := <-errChan
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002430 logger.Debugw(ctx, "process-flow-or-group--received-resp", log.Fields{"err": err, "totalTimeInSeconds": time.Since(startTime).Milliseconds()})
Girish Gowdra491a9c62021-01-06 16:43:07 -08002431 return err
2432}
2433
2434// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
2435func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock) {
2436 for {
2437 // block on the channel to receive an incoming mcast flow/group
2438 // process the flow completely before proceeding to handle the next flow
2439 mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel
2440 if mcastFlowOrGroupCb.flow != nil {
2441 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2442 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2443 log.Fields{"device-id": dh.device.Id,
2444 "flowToAdd": mcastFlowOrGroupCb.flow})
2445 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2446 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2447 // Pass the return value over the return channel
2448 *mcastFlowOrGroupCb.errChan <- err
2449 } else { // flow remove
2450 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2451 log.Fields{"device-id": dh.device.Id,
2452 "flowToRemove": mcastFlowOrGroupCb.flow})
2453 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2454 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2455 // Pass the return value over the return channel
2456 *mcastFlowOrGroupCb.errChan <- err
2457 }
2458 } else { // mcast group
2459 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2460 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2461 log.Fields{"device-id": dh.device.Id,
2462 "groupToAdd": mcastFlowOrGroupCb.group})
2463 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2464 // Pass the return value over the return channel
2465 *mcastFlowOrGroupCb.errChan <- err
2466 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2467 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2468 log.Fields{"device-id": dh.device.Id,
2469 "groupToModify": mcastFlowOrGroupCb.group})
2470 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2471 // Pass the return value over the return channel
2472 *mcastFlowOrGroupCb.errChan <- err
2473 } else { // group remove
2474 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2475 log.Fields{"device-id": dh.device.Id,
2476 "groupToRemove": mcastFlowOrGroupCb.group})
2477 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2478 // Pass the return value over the return channel
2479 *mcastFlowOrGroupCb.errChan <- err
2480 }
2481 }
2482 }
2483}
kesavand62126212021-01-12 04:56:06 -05002484
2485func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2486
2487 singleValResp := extension.SingleGetValueResponse{
2488 Response: &extension.GetValueResponse{
2489 Response: &extension.GetValueResponse_PortCoutners{
2490 PortCoutners: &extension.GetOltPortCountersResponse{},
2491 },
2492 },
2493 }
2494
2495 errResp := func(status extension.GetValueResponse_Status,
2496 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2497 return &extension.SingleGetValueResponse{
2498 Response: &extension.GetValueResponse{
2499 Status: status,
2500 ErrReason: reason,
2501 },
2502 }
2503 }
2504
2505 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2506 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2507 //send error response
2508 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2509 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2510 }
2511 statIndChn := make(chan bool, 1)
2512 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2513 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2514 //request openOlt agent to send the the port statistics indication
2515
2516 go func() {
2517 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2518 if err != nil {
2519 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2520 }
2521 }()
2522 select {
2523 case <-statIndChn:
2524 //indication received for ports stats
2525 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2526 case <-time.After(oltPortInfoTimeout * time.Second):
2527 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2528 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2529 case <-ctx.Done():
2530 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2531 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2532 }
2533 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2534 //get nni stats
2535 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
2536 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2537 cmnni := dh.portStats.collectNNIMetrics(intfID)
2538 if cmnni == nil {
2539 //TODO define the error reason
2540 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2541 }
2542 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2543 return &singleValResp
2544
2545 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2546 // get pon stats
2547 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
2548 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2549 cmpon := dh.portStats.collectPONMetrics(intfID)
2550 if cmpon == nil {
2551 //TODO define the error reason
2552 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2553 }
2554 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2555 return &singleValResp
2556 }
2557 }
2558 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2559}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +05302560
2561func (dh *DeviceHandler) getOnuPonCounters(ctx context.Context, onuPonInfo *extension.GetOnuCountersRequest) *extension.SingleGetValueResponse {
2562
2563 singleValResp := extension.SingleGetValueResponse{
2564 Response: &extension.GetValueResponse{
2565 Response: &extension.GetValueResponse_OnuPonCounters{
2566 OnuPonCounters: &extension.GetOnuCountersResponse{},
2567 },
2568 },
2569 }
2570
2571 errResp := func(status extension.GetValueResponse_Status,
2572 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2573 return &extension.SingleGetValueResponse{
2574 Response: &extension.GetValueResponse{
2575 Status: status,
2576 ErrReason: reason,
2577 },
2578 }
2579 }
2580 intfID := onuPonInfo.IntfId
2581 onuID := onuPonInfo.OnuId
2582 onuKey := dh.formOnuKey(intfID, onuID)
2583
2584 if _, ok := dh.onus.Load(onuKey); !ok {
2585 logger.Errorw(ctx, "get-onui-pon-counters-request-invalid-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2586 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2587 }
2588 logger.Debugw(ctx, "get-onui-pon-counters-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2589 cmnni := dh.portStats.collectOnDemandOnuStats(ctx, intfID, onuID)
2590 if cmnni == nil {
2591 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2592 }
2593 dh.portStats.updateGetOnuPonCountersResponse(ctx, &singleValResp, cmnni)
2594 return &singleValResp
2595
2596}
Gamze Abaka85e9a142021-05-26 13:41:39 +00002597
2598func (dh *DeviceHandler) getRxPower(ctx context.Context, rxPowerRequest *extension.GetRxPowerRequest) *extension.SingleGetValueResponse {
2599
2600 Onu := oop.Onu{IntfId: rxPowerRequest.IntfId, OnuId: rxPowerRequest.OnuId}
2601 rxPower, err := dh.Client.GetPonRxPower(ctx, &Onu)
2602 if err != nil {
2603 logger.Errorw(ctx, "error-while-getting-rx-power", log.Fields{"Onu": Onu, "err": err})
2604 return generateSingleGetValueErrorResponse(err)
2605 }
2606 return &extension.SingleGetValueResponse{
2607 Response: &extension.GetValueResponse{
2608 Status: extension.GetValueResponse_OK,
2609 Response: &extension.GetValueResponse_RxPower{
2610 RxPower: &extension.GetRxPowerResponse{
2611 IntfId: rxPowerRequest.IntfId,
2612 OnuId: rxPowerRequest.OnuId,
2613 Status: rxPower.Status,
2614 FailReason: rxPower.FailReason.String(),
2615 RxPower: rxPower.RxPowerMeanDbm,
2616 },
2617 },
2618 },
2619 }
2620}
2621
2622func generateSingleGetValueErrorResponse(err error) *extension.SingleGetValueResponse {
2623 errResp := func(status extension.GetValueResponse_Status,
2624 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2625 return &extension.SingleGetValueResponse{
2626 Response: &extension.GetValueResponse{
2627 Status: status,
2628 ErrReason: reason,
2629 },
2630 }
2631 }
2632
2633 if err != nil {
2634 if e, ok := status.FromError(err); ok {
2635 switch e.Code() {
2636 case codes.Internal:
2637 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2638 case codes.DeadlineExceeded:
2639 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2640 case codes.Unimplemented:
2641 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_UNSUPPORTED)
2642 case codes.NotFound:
2643 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2644 }
2645 }
2646 }
2647
2648 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_REASON_UNDEFINED)
2649}
Girish Gowdra1cd96d82021-11-05 09:56:26 -07002650
2651func (dh *DeviceHandler) setDeviceDeletionInProgressFlag(flag bool) {
2652 dh.lockDevice.Lock()
2653 defer dh.lockDevice.Unlock()
2654 dh.isDeviceDeletionInProgress = flag
2655}
2656
2657func (dh *DeviceHandler) getDeviceDeletionInProgressFlag() bool {
2658 dh.lockDevice.RLock()
2659 defer dh.lockDevice.RUnlock()
2660 return dh.isDeviceDeletionInProgress
2661}