blob: 3dc62b494d5b05cc8e1476dca221e7895c94d1cd [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 Gowdra4c3d4602021-07-22 16:33:37 -070038 "github.com/opencord/voltha-lib-go/v6/pkg/adapters/adapterif"
39 "github.com/opencord/voltha-lib-go/v6/pkg/config"
40 "github.com/opencord/voltha-lib-go/v6/pkg/events/eventif"
41 flow_utils "github.com/opencord/voltha-lib-go/v6/pkg/flows"
42 "github.com/opencord/voltha-lib-go/v6/pkg/log"
43 "github.com/opencord/voltha-lib-go/v6/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).
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700105 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
106 stopMcastHandlerRoutine []chan bool
107 mcastHandlerRoutineActive []bool
Gamze Abakac2c32a62021-03-11 11:44:18 +0000108
109 adapterPreviouslyConnected bool
110 agentPreviouslyConnected 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)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700191 dh.stopMcastHandlerRoutine = make([]chan bool, MaxNumOfGroupHandlerChannels)
192 dh.mcastHandlerRoutineActive = make([]bool, MaxNumOfGroupHandlerChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800193 for i := range dh.incomingMcastFlowOrGroup {
194 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700195 dh.stopMcastHandlerRoutine[i] = make(chan bool, 1)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800196 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
197 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
198 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
199 // for incoming mcast flow/group to be processed serially.
Girish Gowdra4736e5c2021-08-25 15:19:10 -0700200 dh.mcastHandlerRoutineActive[i] = true
201 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
Girish Gowdra491a9c62021-01-06 16:43:07 -0800202 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700203 //TODO initialize the support classes.
204 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530205}
206
207// start save the device to the data model
208func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700209 dh.lockDevice.Lock()
210 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000211 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700212 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000213 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530214}
215
216// stop stops the device dh. Not much to do for now
217func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700218 dh.lockDevice.Lock()
219 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000220 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700221 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000222 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530223}
224
ssiddiqui04386ee2021-08-23 21:58:25 +0530225func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
226 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
227 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
228 if pooledIntfID == intfID {
229 return resourceRanges.GetTechnology()
230 }
231 }
232 }
233 return ""
234}
235
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400236func macifyIP(ip net.IP) string {
237 if len(ip) > 0 {
238 oct1 := strconv.FormatInt(int64(ip[12]), 16)
239 oct2 := strconv.FormatInt(int64(ip[13]), 16)
240 oct3 := strconv.FormatInt(int64(ip[14]), 16)
241 oct4 := strconv.FormatInt(int64(ip[15]), 16)
242 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
243 }
244 return ""
245}
246
Neha Sharma96b7bf22020-06-15 10:37:32 +0000247func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400248 var genmac string
249 var addr net.IP
250 var ips []string
251 var err error
252
Neha Sharma96b7bf22020-06-15 10:37:32 +0000253 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400254
255 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000256 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400257
258 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000259 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400260 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000261 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400262 }
263 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000264 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530265 log.Fields{"host": ips[0],
266 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400267 return genmac, nil
268 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000269 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400270 }
271
272 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000273 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530274 log.Fields{"host": host,
275 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400276 return genmac, nil
277}
278
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530279func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700280 slist := strings.Split(mac, ":")
281 result := make([]uint32, len(slist))
282 var err error
283 var tmp int64
284 for index, val := range slist {
285 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
286 return []uint32{1, 2, 3, 4, 5, 6}
287 }
288 result[index] = uint32(tmp)
289 }
290 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530291}
292
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700293//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 -0800294func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530295
David K. Bainbridge794735f2020-02-11 21:01:37 -0800296 switch portType {
297 case voltha.Port_ETHERNET_NNI:
298 return fmt.Sprintf("nni-%d", portNum), nil
299 case voltha.Port_PON_OLT:
300 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700301 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800302
Girish Kumarf26e4882020-03-05 06:49:10 +0000303 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530304}
305
Neha Sharma96b7bf22020-06-15 10:37:32 +0000306func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000307 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700308 if state == "up" {
309 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500310 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500311 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700312 } else {
313 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500314 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700315 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700316 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400317 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800318 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000319 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400320 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500321
Neha Sharma8f4e4322020-08-06 10:51:53 +0000322 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 +0000323 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000324 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 -0400325 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
326 "device-id": dh.device.Id,
327 "port-type": portType,
328 "port-number": portNum,
329 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500330 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400331 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500332 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400333 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700334 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400335 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700336 PortNo: portNum,
337 Label: label,
338 Type: portType,
339 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700340 OfpPort: &of.OfpPort{
341 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
342 Config: 0,
343 State: uint32(of.OfpPortState_OFPPS_LIVE),
344 Curr: capacity,
345 Advertised: capacity,
346 Peer: capacity,
347 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
348 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
349 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700350 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000351 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700352 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000353 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000354 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800355 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000356 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400357 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000358 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530359 return nil
360}
361
Kent Hagermane6ff1012020-07-14 15:07:53 -0400362func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000363 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530364 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400365 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
366 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530367 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800368 dh.lockDevice.Lock()
369 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530370 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530371}
372
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700373// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530374// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800375func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000376 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700377 defer func() {
378 dh.lockDevice.Lock()
379 dh.isReadIndicationRoutineActive = false
380 dh.lockDevice.Unlock()
381 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700382 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700383 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700384 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700385 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400386
David Bainbridgef5879ca2019-12-13 21:17:54 +0000387 // Create an exponential backoff around re-enabling indications. The
388 // maximum elapsed time for the back off is set to 0 so that we will
389 // continue to retry. The max interval defaults to 1m, but is set
390 // here for code clarity
391 indicationBackoff := backoff.NewExponentialBackOff()
392 indicationBackoff.MaxElapsedTime = 0
393 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700394
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700395 dh.lockDevice.Lock()
396 dh.isReadIndicationRoutineActive = true
397 dh.lockDevice.Unlock()
398
Girish Gowdra3f974912020-03-23 20:35:18 -0700399Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700400 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400401 select {
402 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000403 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700404 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400405 default:
406 indication, err := indications.Recv()
407 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000408 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530409 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530410 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400411 // Use an exponential back off to prevent getting into a tight loop
412 duration := indicationBackoff.NextBackOff()
413 if duration == backoff.Stop {
414 // If we reach a maximum then warn and reset the backoff
415 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000416 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530417 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530418 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400419 indicationBackoff.Reset()
420 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700421
422 // On failure process a backoff timer while watching for stopIndications
423 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700424 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700425 select {
426 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000427 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700428 if !backoffTimer.Stop() {
429 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700430 }
431 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700432 case <-backoffTimer.C:
433 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700434 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700435 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
436 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400437 }
438 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000439 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530440 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000441 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530442 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530443 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700444 // Close the stream, and re-initialize it
445 if err = indications.CloseSend(); err != nil {
446 // Ok to ignore here, because we landed here due to a problem on the stream
447 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000448 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530449 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530450 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700451 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000452 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700453 return err
454 }
455 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400456 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530457 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400458 // Reset backoff if we have a successful receive
459 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400460 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700461 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000462 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530463 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530464 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400465 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400466 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400467 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700468 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700469 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700470 // Close the send stream
471 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700472
Girish Gowdra3f974912020-03-23 20:35:18 -0700473 return nil
474}
475
476func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700477 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700478 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
479 if err != nil {
480 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
481 }
482 if indications == nil {
483 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
484 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700485 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700486 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400487}
488
489// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
490func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
491 switch indication.Data.(type) {
492 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
493 return true
494
495 default:
496 return false
497 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700498}
499
David K. Bainbridge794735f2020-02-11 21:01:37 -0800500func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700501 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000502 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530503 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700504 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530505 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700506 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000507 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000508 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530509 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000510 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800511 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000512 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800513 }
514 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700515}
516
David K. Bainbridge794735f2020-02-11 21:01:37 -0800517// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530518func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700519 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700520 switch indication.Data.(type) {
521 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000522 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
523 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700524 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 -0800525 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400526 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800527 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700528 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000529 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
530 defer span.Finish()
531
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700532 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800533 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000534 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400535 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800536 }
537 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000538 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700539 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000540 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
541 defer span.Finish()
542
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700543 intfOperInd := indication.GetIntfOperInd()
544 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800545 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000546 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400547 _ = 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 -0800548 }
549 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700550 } else if intfOperInd.GetType() == "pon" {
551 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
552 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800553 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000554 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400555 _ = 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 -0800556 }
557 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000558 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700559 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000560 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530561 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530562 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700563 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000564 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
565 defer span.Finish()
566
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700567 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000568 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800569 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800570 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700571 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000572 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
573 defer span.Finish()
574
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700575 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000576 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800577 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800578 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700579 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000580 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
581 defer span.Finish()
582
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700583 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000584 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 -0800585 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000586 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400587 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800588 }
589 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700590 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000591 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
592 defer span.Finish()
593
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700594 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000595 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700596 "intf-type": pktInd.IntfId,
597 "intf-id": pktInd.IntfId,
598 "gem-port-id": pktInd.GemportId,
599 "port-no": pktInd.PortNo,
600 "device-id": dh.device.Id,
601 })
602
603 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000604 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700605 "intf-type": pktInd.IntfId,
606 "intf-id": pktInd.IntfId,
607 "gem-port-id": pktInd.GemportId,
608 "port-no": pktInd.PortNo,
609 "packet": hex.EncodeToString(pktInd.Pkt),
610 "device-id": dh.device.Id,
611 })
612 }
613
David K. Bainbridge794735f2020-02-11 21:01:37 -0800614 go func() {
615 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400616 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800617 }
618 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700619 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000620 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
621 defer span.Finish()
622
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700623 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700624 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700625 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000626 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
627 defer span.Finish()
628
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700629 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700631 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000632 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
633 defer span.Finish()
634
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700635 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000636 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
637 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700638 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530639}
640
641// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530642func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530643 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000644 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530645
Girish Gowdra618fa572021-09-01 17:19:29 -0700646 // instantiate the mcast handler routines.
647 for i := range dh.incomingMcastFlowOrGroup {
648 // We land inside the below "if" code path, after the OLT comes back from a reboot, otherwise the routines
649 // are already active when the DeviceHandler module is first instantiated (as part of Adopt_device RPC invocation).
650 if !dh.mcastHandlerRoutineActive[i] {
651 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
652 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
653 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
654 // for incoming mcast flow/group to be processed serially.
655 dh.mcastHandlerRoutineActive[i] = true
656 go dh.mcastFlowOrGroupChannelHandlerRoutine(i, dh.incomingMcastFlowOrGroup[i], dh.stopMcastHandlerRoutine[i])
657 }
658 }
659
Girish Gowdru0c588b22019-04-23 23:24:56 -0400660 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530661 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400662 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000663 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400664 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000665
666 //Clear olt communication failure event
667 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
668 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700669 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000670 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
671
Gamze Abakac2c32a62021-03-11 11:44:18 +0000672 //check adapter and agent reconcile status
673 //reboot olt if needed (olt disconnection case)
674 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
675 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
676 log.Fields{
677 "device-id": dh.device.Id,
678 "adapter-status": dh.adapterPreviouslyConnected,
679 "agent-status": dh.agentPreviouslyConnected,
680 })
681 _ = dh.RebootDevice(ctx, dh.device)
682 }
683
Girish Gowdru0c588b22019-04-23 23:24:56 -0400684 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530685}
686
687// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530688func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000689 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400690
npujarec5762e2020-01-01 14:08:48 +0530691 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400692 if err != nil || device == nil {
693 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000694 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400695 }
696
697 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400698
699 //Update the device oper state and connection status
700 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800701 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400702 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800703 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400704
David K. Bainbridge794735f2020-02-11 21:01:37 -0800705 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000706 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400707 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400708
709 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530710 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400711 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000712 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400713 }
714 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400715 // Update onu state as down in onu adapter
716 onuInd := oop.OnuIndication{}
717 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800718 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300719 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800720 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400721 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300722 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800723 "onu-indicator": onuInd,
724 "device-type": onuDevice.Type,
725 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700726 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800727 } else {
728 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 -0700729 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400730 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800731 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700732 /* Discovered ONUs entries need to be cleared , since after OLT
733 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530734 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800735 dh.lockDevice.Unlock()
736
Neha Sharma96b7bf22020-06-15 10:37:32 +0000737 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700738 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530739}
740
741// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530742func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400743 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000744
745 // if the connection is already available, close the previous connection (olt reboot case)
746 if dh.clientCon != nil {
747 if err = dh.clientCon.Close(); err != nil {
748 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
749 } else {
750 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
751 }
752 }
753
754 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000755 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
756 grpc.WithInsecure(),
757 grpc.WithBlock(),
758 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000759 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000760 )),
761 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000762 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000763 )))
764
765 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530766 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530767 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000768 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400769 }
770 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530771}
772
773// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530774func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400775 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530776 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400777 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530778}
779
780// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530781func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530782 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000783 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400784
785 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530786 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
787 if err != nil || device == nil {
788 /*TODO: needs to handle error scenarios */
789 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
790 }
791 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000792 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400793
794 cloned := proto.Clone(device).(*voltha.Device)
795 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
796 cloned.OperStatus = voltha.OperStatus_UNKNOWN
797 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530798 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
799 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 -0400800 }
801
Chaitrashree G S44124192019-08-07 20:21:36 -0400802 // 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 +0530803 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400804 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530805 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400806 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400807 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
808 // all the modules initialized and ready to handle incoming ONUs.
809
Thomas Lee S985938d2020-05-04 11:40:41 +0530810 err = dh.initializeDeviceHandlerModules(ctx)
811 if err != nil {
812 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 -0400813 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400814
815 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800816 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530817 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400818 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800819 }
820 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700821
822 go startHeartbeatCheck(ctx, dh)
823
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400824 return nil
825 }
826
Neha Sharma8f4e4322020-08-06 10:51:53 +0000827 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400828 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400829 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400830 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400831 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400832 dh.populateActivePorts(ctx, ports)
833 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
834 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400835 }
836
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400837 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530838 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 -0400839 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530840
cuilin20187b2a8c32019-03-26 19:52:28 -0700841 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800842 go func() {
843 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400844 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800845 }
846 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000847 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000848
849 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000850 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000851 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700852
853 go startHeartbeatCheck(ctx, dh)
854
cuilin20187b2a8c32019-03-26 19:52:28 -0700855 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530856}
857
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400858func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700859 var err error
860 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400861
862 if err != nil {
863 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
864 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700865 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
866 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700867
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700868 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700869 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700870 var i uint32
871 for i = 0; i < dh.totalPonPorts; i++ {
872 // Instantiate resource manager
873 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 -0700874 return olterrors.ErrResourceManagerInstantiating
875 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400876 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700877 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
878 // the KV store to manage mcast group data. Provide the first instance (0th index)
879 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
880 return olterrors.ErrGroupManagerInstantiating
881 }
882 for i = 0; i < dh.totalPonPorts; i++ {
883 // Instantiate flow manager
884 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
885 return olterrors.ErrFlowManagerInstantiating
886 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700887 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700888 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400889 /* TODO: Instantiate Alarm , stats , BW managers */
890 /* Instantiating Event Manager to handle Alarms and KPIs */
891 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
892
893 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000894 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400895
896 return nil
897
898}
899
Neha Sharma96b7bf22020-06-15 10:37:32 +0000900func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400901 var err error
902 var deviceInfo *oop.DeviceInfo
903
Neha Sharma8f4e4322020-08-06 10:51:53 +0000904 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400905
906 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000907 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400908 }
909 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000910 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400911 }
912
Neha Sharma96b7bf22020-06-15 10:37:32 +0000913 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400914 dh.device.Root = true
915 dh.device.Vendor = deviceInfo.Vendor
916 dh.device.Model = deviceInfo.Model
917 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
918 dh.device.HardwareVersion = deviceInfo.HardwareVersion
919 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
920
921 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000922 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400923 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000924 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400925 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000926 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400927 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000928 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400929 dh.device.MacAddress = genmac
930 } else {
931 dh.device.MacAddress = deviceInfo.DeviceId
932 }
933
934 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000935 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000936 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400937 }
938
939 return deviceInfo, nil
940}
941
Neha Sharma96b7bf22020-06-15 10:37:32 +0000942func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700943 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530944 for {
945 select {
946 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000947 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530948 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000949 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700950
Neha Sharma8f4e4322020-08-06 10:51:53 +0000951 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400952 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700953 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400954 continue
955 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530956 for _, port := range ports {
957 // NNI Stats
958 if port.Type == voltha.Port_ETHERNET_NNI {
959 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
960 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000961 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000962 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000963 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530964 }
965 // PON Stats
966 if port.Type == voltha.Port_PON_OLT {
967 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
968 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
969 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000970 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000971 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530972 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000973 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000974
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700975 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700976 if len(onuGemInfoLst) > 0 {
977 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000978 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500979 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530980 }
981 }
982 }
983}
984
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700985//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530986func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400987 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000988 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530989 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530990
991 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400992 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
993 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530994 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530995}
996
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700997//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530998func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700999 return &ic.SwitchCapability{
1000 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +05301001 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -07001002 HwDesc: "open_pon",
1003 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001004 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -07001005 },
1006 SwitchFeatures: &of.OfpSwitchFeatures{
1007 NBuffers: 256,
1008 NTables: 2,
1009 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
1010 of.OfpCapabilities_OFPC_TABLE_STATS |
1011 of.OfpCapabilities_OFPC_PORT_STATS |
1012 of.OfpCapabilities_OFPC_GROUP_STATS),
1013 },
1014 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301015}
1016
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001017// GetInterAdapterTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
1018func (dh *DeviceHandler) GetInterAdapterTechProfileDownloadMessage(ctx context.Context, tpPath string, ponPortNum uint32, onuID uint32, uniID uint32) *ic.InterAdapterTechProfileDownloadMessage {
1019 ifID, err := IntfIDFromPonPortNum(ctx, ponPortNum)
1020 if err != nil {
1021 return nil
1022 }
1023 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, tpPath, ifID, onuID, uniID)
1024}
1025
Neha Sharma96b7bf22020-06-15 10:37:32 +00001026func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
1027 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 -07001028 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001029 var deviceID string
1030 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -07001031
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001032 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001033 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001034 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 -07001035 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1036 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001037
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001038 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301039
1040 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1041
Neha Sharma96b7bf22020-06-15 10:37:32 +00001042 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 -07001043 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001044 kwargs := make(map[string]interface{})
1045 kwargs["onu_id"] = omciInd.OnuId
1046 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -07001047
Neha Sharma8f4e4322020-08-06 10:51:53 +00001048 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001049 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301050 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001051 "intf-id": omciInd.IntfId,
1052 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001053 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001054 deviceType = onuDevice.Type
1055 deviceID = onuDevice.Id
1056 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1057 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301058 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001059 } else {
1060 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001061 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 +05301062 deviceType = onuInCache.(*OnuDevice).deviceType
1063 deviceID = onuInCache.(*OnuDevice).deviceID
1064 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001065 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001066
1067 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001068 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001069 ic.InterAdapterMessageType_OMCI_RESPONSE, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001070 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301071 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001072 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001073 "destination": deviceType,
1074 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001075 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001076 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001077 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301078}
1079
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001080//ProcessInterAdapterMessage sends the proxied messages to the target device
1081// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1082// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001083func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1084 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001085 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001086 return dh.handleInterAdapterOmciMsg(ctx, msg)
1087 }
1088 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1089}
cuilin20187b2a8c32019-03-26 19:52:28 -07001090
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001091func (dh *DeviceHandler) handleInterAdapterOmciMsg(ctx context.Context, msg *ic.InterAdapterMessage) error {
1092 msgID := msg.Header.Id
1093 fromTopic := msg.Header.FromTopic
1094 toTopic := msg.Header.ToTopic
1095 toDeviceID := msg.Header.ToDeviceId
1096 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001097
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001098 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 -07001099
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001100 msgBody := msg.GetBody()
1101
1102 omciMsg := &ic.InterAdapterOmciMessage{}
1103 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
1104 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
1105 }
1106
1107 if omciMsg.GetProxyAddress() == nil {
1108 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
1109 if err != nil {
1110 return olterrors.NewErrNotFound("onu", log.Fields{
1111 "device-id": dh.device.Id,
1112 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001113 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001114 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001115 if err := dh.sendProxiedOmciMessage(ctx, onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001116 return olterrors.NewErrCommunication("send-failed", log.Fields{
1117 "device-id": dh.device.Id,
1118 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001119 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001120 } else {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001121 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001122 if err := dh.sendProxiedOmciMessage(ctx, nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001123 return olterrors.NewErrCommunication("send-failed", log.Fields{
1124 "device-id": dh.device.Id,
1125 "onu-device-id": toDeviceID}, err)
1126 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001127 }
1128 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301129}
1130
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001131func (dh *DeviceHandler) sendProxiedOmciMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001132 var intfID uint32
1133 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001134 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001135 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001136 intfID = onuDevice.ProxyAddress.GetChannelId()
1137 onuID = onuDevice.ProxyAddress.GetOnuId()
1138 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001139 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001140 intfID = omciMsg.GetProxyAddress().GetChannelId()
1141 onuID = omciMsg.GetProxyAddress().GetOnuId()
1142 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001143 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001144 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001145 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 -08001146
Thomas Lee S94109f12020-03-03 16:39:29 +05301147 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001148 "intf-id": intfID,
1149 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001150 }
1151
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001152 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1153 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001154 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001155 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1156 hex.Encode(hexPkt, omciMsg.Message)
1157 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1158
1159 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1160 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1161 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001162 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001163 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001164
Neha Sharma8f4e4322020-08-06 10:51:53 +00001165 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001166 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301167 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001168 "intf-id": intfID,
1169 "onu-id": onuID,
1170 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001171 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001172 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001173}
1174
David K. Bainbridge794735f2020-02-11 21:01:37 -08001175func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301176 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 Gowdra197acc12021-08-16 10:59:45 -07001177 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001178 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001179 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001180 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301181 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301182 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001183 st, _ := status.FromError(err)
1184 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001185 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1186
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001187 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301188 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001189 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001190 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001191 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001192 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001193 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001194}
1195
Mahir Gunyelb0046752021-02-26 13:51:05 -08001196func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001197 channelID := onuDiscInd.GetIntfId()
1198 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001199
Mahir Gunyelb0046752021-02-26 13:51:05 -08001200 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001201 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301202
cuilin20187b2a8c32019-03-26 19:52:28 -07001203 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001204 if sn != "" {
1205 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001206 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001207 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001208 }
1209
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301210 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001211 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001212 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301213
1214 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1215 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1216 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1217 OnuLosRaise event sent for it */
1218 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1219 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1220 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001221 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301222 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1223 "currentIntfId": onuDiscInd.GetIntfId()})
1224 // TODO:: Should we need to ignore raising OnuLosClear event
1225 // when onu connected to different PON?
1226 }
1227 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1228 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1229 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001230 go func() {
1231 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001232 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001233 }
1234 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301235 }
1236 return true
1237 })
1238
Neha Sharma96b7bf22020-06-15 10:37:32 +00001239 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001240 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001241 }
1242
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001243 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001244
1245 // check the ONU is already know to the OLT
1246 // NOTE the second time the ONU is discovered this should return a device
1247 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1248
1249 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001250 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 -08001251 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001252 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 -08001253 switch e.Code() {
1254 case codes.Internal:
1255 // this probably means NOT FOUND, so just create a new device
1256 onuDevice = nil
1257 case codes.DeadlineExceeded:
1258 // if the call times out, cleanup and exit
1259 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001260 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001261 }
1262 }
1263 }
1264
1265 if onuDevice == nil {
1266 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001267 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001268 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001269 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001270 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001271
Neha Sharma96b7bf22020-06-15 10:37:32 +00001272 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001273
1274 if err != nil {
1275 // if we can't create an ID in resource manager,
1276 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001277 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001278 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001279 "pon-intf-id": ponintfid,
1280 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001281 }
1282
Neha Sharma8f4e4322020-08-06 10:51:53 +00001283 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001284 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001285 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001286 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 +05301287 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001288 "pon-intf-id": ponintfid,
1289 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001290 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001291 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 -07001292 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001293 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001294 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301295 log.Fields{"onuDevice": onuDevice,
1296 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001297 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301298 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001299 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001300
1301 // we can now use the existing ONU Id
1302 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001303 //Insert the ONU into cache to use in OnuIndication.
1304 //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 +00001305 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001306 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301307 "intfId": onuDiscInd.GetIntfId(),
1308 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001309 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001310
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301311 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301312 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001313 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301314 log.Fields{"onu": onuDev,
1315 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001316
Kent Hagermane6ff1012020-07-14 15:07:53 -04001317 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301318 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001319 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001320 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001321 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001322 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001323 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301324 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001325 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001326 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001327 }
1328 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001329}
1330
Mahir Gunyelb0046752021-02-26 13:51:05 -08001331func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001332
1333 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001334 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001335 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001336 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001337 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001338 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301339 log.Fields{"onuId": onuInd.OnuId,
1340 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301341 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001342 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001343 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301344
David K. Bainbridge794735f2020-02-11 21:01:37 -08001345 errFields := log.Fields{"device-id": dh.device.Id}
1346
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301347 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1348
Mahir Gunyele77977b2019-06-27 05:36:22 -07001349 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1350 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001351 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001352 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001353 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001354 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1355 if serialNumber != "" {
1356 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001357 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001358 } else {
1359 kwargs["onu_id"] = onuInd.OnuId
1360 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001361 errFields["onu-id"] = onuInd.OnuId
1362 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001363 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001364 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001365 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001366
David K. Bainbridge794735f2020-02-11 21:01:37 -08001367 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001368 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001369 }
1370
David K. Bainbridge794735f2020-02-11 21:01:37 -08001371 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001372 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001373 "previousIntfId": onuDevice.ParentPortNo,
1374 "currentIntfId": ponPort})
1375 }
1376
1377 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001378 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301379 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1380 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301381 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001382 }
1383 if !foundInCache {
1384 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1385
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301386 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 -08001387
1388 }
kesavand7cf3a052020-08-28 12:49:18 +05301389 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001390 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001391 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301392 }
1393 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001394 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001395 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001396 }
1397 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001398}
1399
Neha Sharma96b7bf22020-06-15 10:37:32 +00001400func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001401 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 -07001402 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1403 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1404 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1405 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001406 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001407 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1408 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001409 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001410 onuInd.OperState = "down"
1411 }
1412 }
1413
David K. Bainbridge794735f2020-02-11 21:01:37 -08001414 switch onuInd.OperState {
1415 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001416 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 -07001417 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301418 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001419 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001420 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301421 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001422 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001423 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001424 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001425 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001426 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001427 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001428 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 -04001429 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301430 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001431 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001432 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301433 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001434 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001435 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001436 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001437 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001438 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001439 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001440 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001441 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001442 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001443}
1444
cuilin20187b2a8c32019-03-26 19:52:28 -07001445func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1446 if serialNum != nil {
1447 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001448 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001449 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001450}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001451func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1452 decodedStr, err := hex.DecodeString(serialNum[4:])
1453 if err != nil {
1454 return nil, err
1455 }
1456 return &oop.SerialNumber{
1457 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001458 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001459 }, nil
1460}
cuilin20187b2a8c32019-03-26 19:52:28 -07001461
1462func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001463 if len(vendorSpecific) > 3 {
1464 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1465 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1466 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1467 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1468 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1469 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1470 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1471 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1472 return tmp
1473 }
1474 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001475}
1476
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001477//UpdateFlowsBulk upates the bulk flow
1478func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301479 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001480}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001481
1482//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001483func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1484 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301485 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001486 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301487 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001488 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001489 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001490 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001491 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001492 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001493 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001494 "intf-id": parentPort,
1495 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001496 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001497 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 -08001498 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301499}
1500
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001501// SendPacketInToCore sends packet-in to core
1502// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1503// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001504func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001505 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001506 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001507 "port": logicalPort,
1508 "packet": hex.EncodeToString(packetPayload),
1509 "device-id": dh.device.Id,
1510 })
1511 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001512 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 +05301513 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001514 "source": "adapter",
1515 "destination": "core",
1516 "device-id": dh.device.Id,
1517 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001518 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001519 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001520 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001521 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001522 "packet": hex.EncodeToString(packetPayload),
1523 "device-id": dh.device.Id,
1524 })
1525 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001526 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001527}
1528
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001529// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001530func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001531 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001532
1533 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1534 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001535 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001536 }
1537
Kent Hagermane6ff1012020-07-14 15:07:53 -04001538 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001539 metrics := dh.metrics.GetSubscriberMetrics()
1540 for _, m := range pmConfigs.Metrics {
1541 metrics[m.Name].Enabled = m.Enabled
1542
1543 }
1544 }
1545}
1546
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001547//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301548func (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 +00001549 logger.Debugw(ctx, "received-incremental-flowupdate-in-device-handler", log.Fields{"device-id": device.Id, "flows": flows, "groups": groups, "flowMetadata": flowMetadata})
Andrea Campanellac63bba92020-03-10 17:01:04 +01001550
Girish Gowdra491a9c62021-01-06 16:43:07 -08001551 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001552 var errorsList []error
1553
Girish Gowdru0c588b22019-04-23 23:24:56 -04001554 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001555 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001556 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001557
Neha Sharma96b7bf22020-06-15 10:37:32 +00001558 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301559 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001560 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301561 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001562 if flow_utils.HasGroup(flow) {
1563 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1564 } else {
1565 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1566 }
Girish Gowdracefae192020-03-19 18:14:10 -07001567 if err != nil {
1568 errorsList = append(errorsList, err)
1569 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001570 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301571
1572 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001573 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001574 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301575 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001576 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301577 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001578 if flow_utils.HasGroup(flow) {
1579 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1580 } else {
1581 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1582 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001583 if err != nil {
1584 errorsList = append(errorsList, err)
1585 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301586 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001587 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001588
Girish Gowdracefae192020-03-19 18:14:10 -07001589 // 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 +00001590 if groups != nil {
1591 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001592 // err = dh.groupMgr.AddGroup(ctx, group)
1593 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001594 if err != nil {
1595 errorsList = append(errorsList, err)
1596 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001597 }
1598 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001599 // err = dh.groupMgr.ModifyGroup(ctx, group)
1600 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001601 if err != nil {
1602 errorsList = append(errorsList, err)
1603 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001604 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001605 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001606 // err = dh.groupMgr.DeleteGroup(ctx, group)
1607 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001608 if err != nil {
1609 errorsList = append(errorsList, err)
1610 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001611 }
1612 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001613 if len(errorsList) > 0 {
1614 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1615 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001616 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001617 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301618}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001619
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001620//DisableDevice disables the given device
1621//It marks the following for the given device:
1622//Device-Handler Admin-State : down
1623//Device Port-State: UNKNOWN
1624//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001625func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001626 /* On device disable ,admin state update has to be done prior sending request to agent since
1627 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001628 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001629 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001630 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001631 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001632 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001633 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001634 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001635 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001636 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001637 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301638
1639 dh.discOnus = sync.Map{}
1640 dh.onus = sync.Map{}
1641
Thomas Lee S85f37312020-04-03 17:06:12 +05301642 //stopping the stats collector
1643 dh.stopCollector <- true
1644
Neha Sharma96b7bf22020-06-15 10:37:32 +00001645 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001646 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301647 //Update device Admin state
1648 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001649 // 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 +00001650 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 -04001651 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001652 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001653 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001654 return nil
1655}
1656
Neha Sharma96b7bf22020-06-15 10:37:32 +00001657func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001658 // Update onu state as unreachable in onu adapter
1659 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301660 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001661 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001662 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001663 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001664 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 -04001665 }
1666 if onuDevices != nil {
1667 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001668 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001669 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001670 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001671 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001672 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001673 }
1674
1675 }
1676 }
1677
1678}
1679
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001680//ReenableDevice re-enables the olt device after disable
1681//It marks the following for the given device:
1682//Device-Handler Admin-State : up
1683//Device Port-State: ACTIVE
1684//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001685func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001686 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301687 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001688 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301689 }
1690 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001691 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001692
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001693 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001694
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001695 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1696 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001697 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001698 }
1699 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001700 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001701 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001702 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001703 device.OperStatus = voltha.OperStatus_ACTIVE
1704 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001705
Neha Sharma8f4e4322020-08-06 10:51:53 +00001706 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 +05301707 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001708 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001709 "connect-status": device.ConnectStatus,
1710 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001711 }
kesavand39e0aa32020-01-28 20:58:50 -05001712
Neha Sharma96b7bf22020-06-15 10:37:32 +00001713 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001714
1715 return nil
1716}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001717
npujarec5762e2020-01-01 14:08:48 +05301718func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001719 var uniID uint32
1720 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301721 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001722 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001723 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001724 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001725 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001726 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001727 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001728 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001729 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001730 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001731 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001732 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001733 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001734 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001735 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001736 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001737 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001738 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301739 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001740 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1741 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001742 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301743 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001744 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001745 if err = dh.resourceMgr[onu.IntfID].DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001746 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 +00001747 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001748 }
1749 return nil
1750}
1751
Devmalya Paul495b94a2019-08-27 19:42:00 -04001752// 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 +05301753func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001754 logger.Debugw(ctx, "function-entry-delete-device", log.Fields{"device-id": dh.device.Id})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001755 /* Clear the KV store data associated with the all the UNI ports
1756 This clears up flow data and also resource map data for various
1757 other pon resources like alloc_id and gemport_id
1758 */
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001759 dh.cleanupDeviceResources(ctx)
1760 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 -04001761 // Stop the Stats collector
1762 dh.stopCollector <- true
1763 // stop the heartbeat check routine
1764 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301765 dh.lockDevice.RLock()
1766 // Stop the read indication only if it the routine is active
1767 if dh.isReadIndicationRoutineActive {
1768 dh.stopIndications <- true
1769 }
1770 dh.lockDevice.RUnlock()
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001771 dh.removeOnuIndicationChannels(ctx)
Girish Gowdra4736e5c2021-08-25 15:19:10 -07001772 go dh.StopAllMcastHandlerRoutines(ctx)
1773 for _, flMgr := range dh.flowMgr {
1774 go flMgr.StopAllFlowHandlerRoutines(ctx)
1775 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001776 //Reset the state
1777 if dh.Client != nil {
1778 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301779 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001780 }
1781 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001782 // There is no need to update the core about operation status and connection status of the OLT.
1783 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1784 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1785 // because the device does not exist in DB.
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001786
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001787 return nil
1788}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001789func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001790
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001791 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301792 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001793 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001794 var err error
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001795 onuGemData := dh.flowMgr[ponPort].getOnuGemInfoList(ctx)
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001796 for i, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301797 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001798 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001799 if err = dh.clearUNIData(ctx, &onuGemData[i]); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001800 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301801 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301802 // Clear flowids for gem cache.
1803 for _, gem := range onu.GemPorts {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001804 dh.resourceMgr[ponPort].DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301805 }
1806 onuID[0] = onu.OnuID
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001807 dh.resourceMgr[ponPort].FreeonuID(ctx, ponPort, onuID)
1808 err = dh.resourceMgr[ponPort].DelOnuGemInfo(ctx, ponPort, onu.OnuID)
1809 if err != nil {
1810 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
1811 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301812 }
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001813 if err := dh.resourceMgr[ponPort].Delete(ctx, ponPort); err != nil {
1814 logger.Debug(ctx, err)
1815 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001816 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001817 }
A R Karthick1f85b802019-10-11 05:06:05 +00001818
Devmalya Paul495b94a2019-08-27 19:42:00 -04001819 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301820 dh.onus.Range(func(key interface{}, value interface{}) bool {
1821 dh.onus.Delete(key)
1822 return true
1823 })
1824
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001825 /*Delete discovered ONU map for the device*/
1826 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1827 dh.discOnus.Delete(key)
1828 return true
1829 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001830}
1831
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001832//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001833func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001834 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301835 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001836 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001837 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001838 return nil
1839}
1840
David K. Bainbridge794735f2020-02-11 21:01:37 -08001841func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001842 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001843 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001844 "packet-indication": *packetIn,
1845 "device-id": dh.device.Id,
1846 "packet": hex.EncodeToString(packetIn.Pkt),
1847 })
1848 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001849 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001850 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001851 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001852 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001853 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001854 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001855 "logical-port-num": logicalPortNum,
1856 "device-id": dh.device.Id,
1857 "packet": hex.EncodeToString(packetIn.Pkt),
1858 })
1859 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001860
Neha Sharma8f4e4322020-08-06 10:51:53 +00001861 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 +05301862 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001863 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301864 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001865 "device-id": dh.device.Id,
1866 "packet": hex.EncodeToString(packetIn.Pkt),
1867 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001868 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001869
Matteo Scandolo92186242020-06-12 10:54:18 -07001870 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001871 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001872 "packet": hex.EncodeToString(packetIn.Pkt),
1873 "device-id": dh.device.Id,
1874 })
1875 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001876 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001877}
1878
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001879// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301880func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001881 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001882 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001883 "device-id": dh.device.Id,
1884 "egress-port-no": egressPortNo,
1885 "pkt-length": len(packet.Data),
1886 "packet": hex.EncodeToString(packet.Data),
1887 })
1888 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001889
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001890 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001891 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001892 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1893 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301894 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1895 // Do not packet-out lldp packets on uni port.
1896 // ONOS has no clue about uni/nni ports, it just packets out on all
1897 // available ports on the Logical Switch. It should not be interested
1898 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001899 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001900 "device-id": dh.device.Id,
1901 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301902 return nil
1903 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001904 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1905 if innerEthType == 0x8100 {
1906 // q-in-q 802.1ad or 802.1q double tagged packet.
1907 // slice out the outer tag.
1908 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001909 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001910 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001911 "packet-data": hex.EncodeToString(packet.Data),
1912 "device-id": dh.device.Id,
1913 })
1914 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001915 }
1916 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001917 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1918 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001919 uniID := UniIDFromPortNum(uint32(egressPortNo))
1920
Girish Gowdra9602eb42020-09-09 15:50:39 -07001921 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001922 if err != nil {
1923 // In this case the openolt agent will receive the gemPortID as 0.
1924 // The agent tries to retrieve the gemPortID in this case.
1925 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001926 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001927 "intf-id": intfID,
1928 "onu-id": onuID,
1929 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001930 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301931 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001932 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001933 }
1934
1935 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001936 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001937 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001938 "egress-port-no": egressPortNo,
1939 "intf-id": intfID,
1940 "onu-id": onuID,
1941 "uni-id": uniID,
1942 "gem-port-id": gemPortID,
1943 "packet": hex.EncodeToString(packet.Data),
1944 "device-id": dh.device.Id,
1945 })
1946 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001947
npujarec5762e2020-01-01 14:08:48 +05301948 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301949 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001950 "source": "adapter",
1951 "destination": "onu",
1952 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001953 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001954 "oni-id": onuID,
1955 "uni-id": uniID,
1956 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001957 "packet": hex.EncodeToString(packet.Data),
1958 "device-id": dh.device.Id,
1959 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001960 }
1961 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001962 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001963 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001964 return olterrors.NewErrInvalidValue(log.Fields{
1965 "egress-nni-port": egressPortNo,
1966 "device-id": dh.device.Id,
1967 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001968 }
1969 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001970
Matteo Scandolo92186242020-06-12 10:54:18 -07001971 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001972 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001973 "uplink-pkt": uplinkPkt,
1974 "packet": hex.EncodeToString(packet.Data),
1975 "device-id": dh.device.Id,
1976 })
1977 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001978
npujarec5762e2020-01-01 14:08:48 +05301979 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001980 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1981 "packet": hex.EncodeToString(packet.Data),
1982 "device-id": dh.device.Id,
1983 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001984 }
1985 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001986 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301987 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001988 "egressPortType": egressPortType,
1989 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301990 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001991 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001992 }
1993 return nil
1994}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001995
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001996func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1997 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001998}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301999
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002000func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00002001
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302002 // start the heartbeat check towards the OLT.
2003 var timerCheck *time.Timer
2004
2005 for {
2006 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
2007 select {
2008 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00002009 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002010 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002011 logger.Warnw(ctx, "heartbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302012 if timerCheck == nil {
2013 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002014 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302015 }
2016 } else {
2017 if timerCheck != nil {
2018 if timerCheck.Stop() {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002019 logger.Debugw(ctx, "got-heartbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302020 }
2021 timerCheck = nil
2022 }
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002023 logger.Debugw(ctx, "heartbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05302024 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05302025 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302026 }
2027 cancel()
2028 case <-dh.stopHeartbeatCheck:
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002029 logger.Debugw(ctx, "stopping-heartbeat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302030 return
2031 }
2032 }
2033}
2034
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002035func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
2036 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
2037 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002038 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2039 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2040 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2041 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2042 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002043 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002044 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2045 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002046 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302047
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002048 logger.Debugw(ctx, "update-state-unreachable", log.Fields{"device-id": dh.device.Id, "connect-status": device.ConnectStatus,
2049 "admin-state": device.AdminState, "oper-status": device.OperStatus})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002050 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
2051 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002052 _ = 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 -04002053 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002054 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002055 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002056 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002057
2058 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002059 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +00002060 device.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2061 device.OperStatus = voltha.OperStatus_UNKNOWN
2062 go dh.eventMgr.oltCommunicationEvent(ctx, device, raisedTs)
2063
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07002064 dh.cleanupDeviceResources(ctx)
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002065 // Stop the Stats collector
2066 dh.stopCollector <- true
2067 // stop the heartbeat check routine
2068 dh.stopHeartbeatCheck <- true
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002069
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002070 dh.lockDevice.RLock()
2071 // Stop the read indication only if it the routine is active
2072 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2073 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2074 // on next execution of the readIndication routine.
2075 if dh.isReadIndicationRoutineActive {
2076 dh.stopIndications <- true
2077 }
2078 dh.lockDevice.RUnlock()
2079
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002080 go dh.StopAllMcastHandlerRoutines(ctx)
2081 for _, flMgr := range dh.flowMgr {
2082 go flMgr.StopAllFlowHandlerRoutines(ctx)
2083 }
2084
Gamze Abakac2c32a62021-03-11 11:44:18 +00002085 //reset adapter reconcile flag
2086 dh.adapterPreviouslyConnected = false
2087
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002088 dh.transitionMap.Handle(ctx, DeviceInit)
2089
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302090 }
2091}
kesavand39e0aa32020-01-28 20:58:50 -05002092
2093// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002094func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2095 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2096 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002097}
2098
2099// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002100func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2101 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2102 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002103}
2104
kdarapu1afeceb2020-02-12 01:38:09 -05002105//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 +00002106func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2107 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002108 if port.GetType() == voltha.Port_ETHERNET_NNI {
2109 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002110 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302111 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302112 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002113 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002114 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002115 }
2116 // fetch interfaceid from PortNo
2117 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2118 ponIntf := &oop.Interface{IntfId: ponID}
2119 var operStatus voltha.OperStatus_Types
2120 if enablePort {
2121 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302122 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002123
2124 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302125 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002126 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002127 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002128 }
2129 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002130 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002131 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002132 } else {
2133 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302134 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002135 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302136 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002137 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002138 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002139 }
2140 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002141 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002142 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002143 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302144 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 +05302145 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302146 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002147 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002148 }
2149 return nil
2150}
2151
kdarapu1afeceb2020-02-12 01:38:09 -05002152//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002153func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002154 // Disable the port and update the oper_port_status to core
2155 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002156 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002157 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002158 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302159 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302160 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002161 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002162 }
2163 }
2164 }
2165 return nil
2166}
2167
2168//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002169func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2170 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2171 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002172 if port.Type == voltha.Port_ETHERNET_NNI {
2173 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002174 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002175 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002176 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002177 }
2178 }
2179 if port.Type == voltha.Port_PON_OLT {
2180 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002181 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002182 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002183 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002184 }
2185 }
2186 }
2187}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002188
2189// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002190func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002191 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002192 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2193 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002194
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002195 var sn *oop.SerialNumber
2196 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002197 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302198 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002199 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302200 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002201 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002202 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002203
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002204 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002205 //clear PON resources associated with ONU
2206 onuGem, err := dh.resourceMgr[intfID].GetOnuGemInfo(ctx, intfID, onuID)
2207 if err != nil || onuGem == nil || onuGem.OnuID != onuID {
2208 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
2209 "device-id": dh.device.Id,
2210 "intf-id": intfID,
2211 "onuID": onuID,
2212 "err": err})
2213 } else {
2214 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
2215 if err := dh.clearUNIData(ctx, onuGem); err != nil {
2216 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
2217 "device-id": dh.device.Id,
2218 "onu-device": onu,
2219 "err": err})
2220 }
2221 // Clear flowids for gem cache.
2222 for _, gem := range onuGem.GemPorts {
2223 dh.resourceMgr[intfID].DeleteFlowIDsForGem(ctx, intfID, gem)
2224 }
Girish Gowdra197acc12021-08-16 10:59:45 -07002225 if err := dh.flowMgr[intfID].RemoveOnuInfoFromFlowMgrCacheAndKvStore(ctx, intfID, onuID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002226 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
2227 "intf-id": intfID,
2228 "onu-device": onu,
2229 "onu-gem": onuGem,
2230 "err": err})
2231 //Not returning error on cleanup.
2232 }
2233 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGem})
2234 dh.resourceMgr[intfID].FreeonuID(ctx, intfID, []uint32{onuGem.OnuID})
2235 }
2236 dh.onus.Delete(onuKey)
2237 dh.discOnus.Delete(onuSn)
2238
2239 // Now clear the ONU on the OLT
Neha Sharma8f4e4322020-08-06 10:51:53 +00002240 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302241 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302242 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002243 "onu-id": onuID}, err).Log()
2244 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002245
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002246 return nil
2247}
Girish Gowdracefae192020-03-19 18:14:10 -07002248
2249func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002250 for _, field := range flow_utils.GetOfbFields(flow) {
2251 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002252 return field.GetPort()
2253 }
2254 }
2255 return InvalidPort
2256}
2257
2258func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002259 for _, action := range flow_utils.GetActions(flow) {
2260 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002261 if out := action.GetOutput(); out != nil {
2262 return out.GetPort()
2263 }
2264 }
2265 }
2266 return InvalidPort
2267}
2268
Girish Gowdracefae192020-03-19 18:14:10 -07002269func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2270 inPort := getInPortFromFlow(flow)
2271 outPort := getOutPortFromFlow(flow)
2272
2273 if inPort == InvalidPort || outPort == InvalidPort {
2274 return inPort, outPort
2275 }
2276
2277 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2278 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2279 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002280 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002281 return uniPort, outPort
2282 }
2283 }
2284 } else {
2285 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2286 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002287 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002288 return inPort, uniPort
2289 }
2290 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2291 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002292 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002293 return uniPort, outPort
2294 }
2295 }
2296 }
2297
2298 return InvalidPort, InvalidPort
2299}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002300
2301func extractOmciTransactionID(omciPkt []byte) uint16 {
2302 if len(omciPkt) > 3 {
2303 d := omciPkt[0:2]
2304 transid := binary.BigEndian.Uint16(d)
2305 return transid
2306 }
2307 return 0
2308}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002309
2310// StoreOnuDevice stores the onu parameters to the local cache.
2311func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2312 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2313 dh.onus.Store(onuKey, onuDevice)
2314}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002315
Neha Sharma8f4e4322020-08-06 10:51:53 +00002316func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002317 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002318 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002319 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002320 resp := new(voltha.ReturnValues)
2321 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002322 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002323 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002324 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2325 return nil, err
2326 }
2327 ID = device.ProxyAddress.GetOnuId()
2328 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2329 valueparam.Onu = &Onu
2330 valueparam.Value = value
2331
2332 // This API is unsupported until agent patch is added
2333 resp.Unsupported = uint32(value)
2334 _ = ctx
2335
2336 // Uncomment this code once agent changes are complete and tests
2337 /*
2338 resp, err = dh.Client.GetValue(ctx, valueparam)
2339 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002340 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "err": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002341 return nil, err
2342 }
2343 */
2344
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002345 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 -08002346 return resp, nil
2347}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002348
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002349func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002350 // Default to PON0
2351 var intfID uint32
2352 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002353 if inPort != InvalidPort && outPort != InvalidPort {
2354 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2355 }
2356 return intfID
2357}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002358
Mahir Gunyelb0046752021-02-26 13:51:05 -08002359func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2360 dh.perPonOnuIndicationChannelLock.Lock()
2361 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2362 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002363 return ch.indicationChannel
2364 }
2365 channels := onuIndicationChannels{
2366 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002367 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002368 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002369 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002370 stopChannel: make(chan struct{}),
2371 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002372 dh.perPonOnuIndicationChannel[intfID] = channels
2373 dh.perPonOnuIndicationChannelLock.Unlock()
2374 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002375 return channels.indicationChannel
2376
2377}
2378
Mahir Gunyelb0046752021-02-26 13:51:05 -08002379func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2380 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2381 dh.perPonOnuIndicationChannelLock.Lock()
2382 defer dh.perPonOnuIndicationChannelLock.Unlock()
2383 for _, v := range dh.perPonOnuIndicationChannel {
2384 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002385 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002386 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002387}
2388
Mahir Gunyelb0046752021-02-26 13:51:05 -08002389func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2390 ind := onuIndicationMsg{
2391 ctx: ctx,
2392 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002393 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002394 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002395 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002396 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002397}
2398
Mahir Gunyelb0046752021-02-26 13:51:05 -08002399func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002400 for {
2401 select {
2402 // process one indication per onu, before proceeding to the next one
2403 case onuInd := <-onuChannels.indicationChannel:
2404 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002405 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002406 switch onuInd.indication.Data.(type) {
2407 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002408 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002409 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2410 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002411 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002412 }
2413 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002414 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002415 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2416 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002417 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002418 }
2419 }
2420 case <-onuChannels.stopChannel:
2421 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2422 close(onuChannels.indicationChannel)
2423 return
2424 }
2425 }
2426}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002427
2428// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2429// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2430func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2431 // Step1 : Fill McastFlowOrGroupControlBlock
2432 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2433 // Step3 : Wait on response channel for response
2434 // Step4 : Return error value
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002435 startTime := time.Now()
Girish Gowdra491a9c62021-01-06 16:43:07 -08002436 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2437 errChan := make(chan error)
2438 var groupID uint32
2439 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2440 ctx: ctx,
2441 flowOrGroupAction: action,
2442 flow: flow,
2443 group: group,
2444 errChan: &errChan,
2445 }
2446 if flow != nil {
2447 groupID = flow_utils.GetGroup(flow)
2448 } else if group != nil {
2449 groupID = group.Desc.GroupId
2450 } else {
2451 return errors.New("flow-and-group-both-nil")
2452 }
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002453 mcastRoutineIdx := groupID % MaxNumOfGroupHandlerChannels
2454 if dh.mcastHandlerRoutineActive[mcastRoutineIdx] {
2455 // Derive the appropriate go routine to handle the request by a simple module operation.
2456 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2457 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2458 // Wait for handler to return error value
2459 err := <-errChan
2460 logger.Debugw(ctx, "process-flow-or-group--received-resp", log.Fields{"err": err, "totalTimeInSeconds": time.Since(startTime).Milliseconds()})
2461 return err
2462 }
2463 logger.Errorw(ctx, "mcast handler routine not active for onu", log.Fields{"mcastRoutineIdx": mcastRoutineIdx})
2464 return fmt.Errorf("mcast-handler-routine-not-active-for-index-%v", mcastRoutineIdx)
Girish Gowdra491a9c62021-01-06 16:43:07 -08002465}
2466
2467// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002468func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(routineIndex int, mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock, stopHandler chan bool) {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002469 for {
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002470 select {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002471 // block on the channel to receive an incoming mcast flow/group
2472 // process the flow completely before proceeding to handle the next flow
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002473 case mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel:
2474 if mcastFlowOrGroupCb.flow != nil {
2475 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2476 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2477 log.Fields{"device-id": dh.device.Id,
2478 "flowToAdd": mcastFlowOrGroupCb.flow})
2479 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2480 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2481 // Pass the return value over the return channel
2482 *mcastFlowOrGroupCb.errChan <- err
2483 } else { // flow remove
2484 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2485 log.Fields{"device-id": dh.device.Id,
2486 "flowToRemove": mcastFlowOrGroupCb.flow})
2487 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2488 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2489 // Pass the return value over the return channel
2490 *mcastFlowOrGroupCb.errChan <- err
2491 }
2492 } else { // mcast group
2493 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2494 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2495 log.Fields{"device-id": dh.device.Id,
2496 "groupToAdd": mcastFlowOrGroupCb.group})
2497 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2498 // Pass the return value over the return channel
2499 *mcastFlowOrGroupCb.errChan <- err
2500 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2501 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2502 log.Fields{"device-id": dh.device.Id,
2503 "groupToModify": mcastFlowOrGroupCb.group})
2504 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2505 // Pass the return value over the return channel
2506 *mcastFlowOrGroupCb.errChan <- err
2507 } else { // group remove
2508 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2509 log.Fields{"device-id": dh.device.Id,
2510 "groupToRemove": mcastFlowOrGroupCb.group})
2511 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2512 // Pass the return value over the return channel
2513 *mcastFlowOrGroupCb.errChan <- err
2514 }
Girish Gowdra491a9c62021-01-06 16:43:07 -08002515 }
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002516 case <-stopHandler:
2517 dh.mcastHandlerRoutineActive[routineIndex] = false
2518 return
Girish Gowdra491a9c62021-01-06 16:43:07 -08002519 }
2520 }
2521}
kesavand62126212021-01-12 04:56:06 -05002522
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002523// StopAllMcastHandlerRoutines stops all flow handler routines. Call this when device is being rebooted or deleted
2524func (dh *DeviceHandler) StopAllMcastHandlerRoutines(ctx context.Context) {
2525 for i, v := range dh.stopMcastHandlerRoutine {
2526 if dh.mcastHandlerRoutineActive[i] {
2527 v <- true
2528 }
2529 }
2530 logger.Debug(ctx, "stopped all mcast handler routines")
2531}
2532
kesavand62126212021-01-12 04:56:06 -05002533func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2534
2535 singleValResp := extension.SingleGetValueResponse{
2536 Response: &extension.GetValueResponse{
2537 Response: &extension.GetValueResponse_PortCoutners{
2538 PortCoutners: &extension.GetOltPortCountersResponse{},
2539 },
2540 },
2541 }
2542
2543 errResp := func(status extension.GetValueResponse_Status,
2544 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2545 return &extension.SingleGetValueResponse{
2546 Response: &extension.GetValueResponse{
2547 Status: status,
2548 ErrReason: reason,
2549 },
2550 }
2551 }
2552
2553 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2554 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2555 //send error response
2556 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2557 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2558 }
2559 statIndChn := make(chan bool, 1)
2560 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2561 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2562 //request openOlt agent to send the the port statistics indication
2563
2564 go func() {
2565 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2566 if err != nil {
2567 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2568 }
2569 }()
2570 select {
2571 case <-statIndChn:
2572 //indication received for ports stats
2573 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2574 case <-time.After(oltPortInfoTimeout * time.Second):
2575 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2576 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2577 case <-ctx.Done():
2578 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2579 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2580 }
2581 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2582 //get nni stats
2583 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
2584 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2585 cmnni := dh.portStats.collectNNIMetrics(intfID)
2586 if cmnni == nil {
2587 //TODO define the error reason
2588 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2589 }
2590 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2591 return &singleValResp
2592
2593 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2594 // get pon stats
2595 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
2596 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2597 cmpon := dh.portStats.collectPONMetrics(intfID)
2598 if cmpon == nil {
2599 //TODO define the error reason
2600 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2601 }
2602 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2603 return &singleValResp
2604 }
2605 }
2606 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2607}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +05302608
2609func (dh *DeviceHandler) getOnuPonCounters(ctx context.Context, onuPonInfo *extension.GetOnuCountersRequest) *extension.SingleGetValueResponse {
2610
2611 singleValResp := extension.SingleGetValueResponse{
2612 Response: &extension.GetValueResponse{
2613 Response: &extension.GetValueResponse_OnuPonCounters{
2614 OnuPonCounters: &extension.GetOnuCountersResponse{},
2615 },
2616 },
2617 }
2618
2619 errResp := func(status extension.GetValueResponse_Status,
2620 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2621 return &extension.SingleGetValueResponse{
2622 Response: &extension.GetValueResponse{
2623 Status: status,
2624 ErrReason: reason,
2625 },
2626 }
2627 }
2628 intfID := onuPonInfo.IntfId
2629 onuID := onuPonInfo.OnuId
2630 onuKey := dh.formOnuKey(intfID, onuID)
2631
2632 if _, ok := dh.onus.Load(onuKey); !ok {
2633 logger.Errorw(ctx, "get-onui-pon-counters-request-invalid-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2634 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2635 }
2636 logger.Debugw(ctx, "get-onui-pon-counters-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2637 cmnni := dh.portStats.collectOnDemandOnuStats(ctx, intfID, onuID)
2638 if cmnni == nil {
2639 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2640 }
2641 dh.portStats.updateGetOnuPonCountersResponse(ctx, &singleValResp, cmnni)
2642 return &singleValResp
2643
2644}
Gamze Abaka85e9a142021-05-26 13:41:39 +00002645
2646func (dh *DeviceHandler) getRxPower(ctx context.Context, rxPowerRequest *extension.GetRxPowerRequest) *extension.SingleGetValueResponse {
2647
2648 Onu := oop.Onu{IntfId: rxPowerRequest.IntfId, OnuId: rxPowerRequest.OnuId}
2649 rxPower, err := dh.Client.GetPonRxPower(ctx, &Onu)
2650 if err != nil {
2651 logger.Errorw(ctx, "error-while-getting-rx-power", log.Fields{"Onu": Onu, "err": err})
2652 return generateSingleGetValueErrorResponse(err)
2653 }
2654 return &extension.SingleGetValueResponse{
2655 Response: &extension.GetValueResponse{
2656 Status: extension.GetValueResponse_OK,
2657 Response: &extension.GetValueResponse_RxPower{
2658 RxPower: &extension.GetRxPowerResponse{
2659 IntfId: rxPowerRequest.IntfId,
2660 OnuId: rxPowerRequest.OnuId,
2661 Status: rxPower.Status,
2662 FailReason: rxPower.FailReason.String(),
2663 RxPower: rxPower.RxPowerMeanDbm,
2664 },
2665 },
2666 },
2667 }
2668}
2669
2670func generateSingleGetValueErrorResponse(err error) *extension.SingleGetValueResponse {
2671 errResp := func(status extension.GetValueResponse_Status,
2672 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2673 return &extension.SingleGetValueResponse{
2674 Response: &extension.GetValueResponse{
2675 Status: status,
2676 ErrReason: reason,
2677 },
2678 }
2679 }
2680
2681 if err != nil {
2682 if e, ok := status.FromError(err); ok {
2683 switch e.Code() {
2684 case codes.Internal:
2685 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2686 case codes.DeadlineExceeded:
2687 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2688 case codes.Unimplemented:
2689 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_UNSUPPORTED)
2690 case codes.NotFound:
2691 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2692 }
2693 }
2694 }
2695
2696 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_REASON_UNDEFINED)
2697}