blob: bc6ca7c1cee0a049b9774c0745a38dd158a7193b [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 Gowdru0c588b22019-04-23 23:24:56 -0400646 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530647 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400648 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000649 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400650 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000651
652 //Clear olt communication failure event
653 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
654 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700655 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000656 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
657
Gamze Abakac2c32a62021-03-11 11:44:18 +0000658 //check adapter and agent reconcile status
659 //reboot olt if needed (olt disconnection case)
660 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
661 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
662 log.Fields{
663 "device-id": dh.device.Id,
664 "adapter-status": dh.adapterPreviouslyConnected,
665 "agent-status": dh.agentPreviouslyConnected,
666 })
667 _ = dh.RebootDevice(ctx, dh.device)
668 }
669
Girish Gowdru0c588b22019-04-23 23:24:56 -0400670 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530671}
672
673// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530674func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000675 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400676
npujarec5762e2020-01-01 14:08:48 +0530677 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400678 if err != nil || device == nil {
679 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000680 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400681 }
682
683 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400684
685 //Update the device oper state and connection status
686 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800687 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400688 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800689 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400690
David K. Bainbridge794735f2020-02-11 21:01:37 -0800691 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000692 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400693 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400694
695 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530696 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400697 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000698 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400699 }
700 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400701 // Update onu state as down in onu adapter
702 onuInd := oop.OnuIndication{}
703 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800704 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300705 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800706 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400707 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300708 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800709 "onu-indicator": onuInd,
710 "device-type": onuDevice.Type,
711 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700712 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800713 } else {
714 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 -0700715 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400716 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800717 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700718 /* Discovered ONUs entries need to be cleared , since after OLT
719 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530720 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800721 dh.lockDevice.Unlock()
722
Neha Sharma96b7bf22020-06-15 10:37:32 +0000723 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700724 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530725}
726
727// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530728func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400729 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000730
731 // if the connection is already available, close the previous connection (olt reboot case)
732 if dh.clientCon != nil {
733 if err = dh.clientCon.Close(); err != nil {
734 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
735 } else {
736 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
737 }
738 }
739
740 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000741 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
742 grpc.WithInsecure(),
743 grpc.WithBlock(),
744 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000745 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000746 )),
747 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000748 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000749 )))
750
751 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530752 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530753 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000754 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400755 }
756 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530757}
758
759// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530760func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400761 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530762 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400763 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530764}
765
766// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530767func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530768 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000769 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400770
771 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530772 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
773 if err != nil || device == nil {
774 /*TODO: needs to handle error scenarios */
775 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
776 }
777 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000778 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400779
780 cloned := proto.Clone(device).(*voltha.Device)
781 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
782 cloned.OperStatus = voltha.OperStatus_UNKNOWN
783 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530784 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
785 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 -0400786 }
787
Chaitrashree G S44124192019-08-07 20:21:36 -0400788 // 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 +0530789 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400790 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530791 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400792 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400793 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
794 // all the modules initialized and ready to handle incoming ONUs.
795
Thomas Lee S985938d2020-05-04 11:40:41 +0530796 err = dh.initializeDeviceHandlerModules(ctx)
797 if err != nil {
798 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 -0400799 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400800
801 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800802 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530803 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400804 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800805 }
806 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700807
808 go startHeartbeatCheck(ctx, dh)
809
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400810 return nil
811 }
812
Neha Sharma8f4e4322020-08-06 10:51:53 +0000813 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400814 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400815 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400816 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400817 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400818 dh.populateActivePorts(ctx, ports)
819 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
820 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400821 }
822
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400823 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530824 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 -0400825 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530826
cuilin20187b2a8c32019-03-26 19:52:28 -0700827 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800828 go func() {
829 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400830 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800831 }
832 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000833 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000834
835 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000836 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000837 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700838
839 go startHeartbeatCheck(ctx, dh)
840
cuilin20187b2a8c32019-03-26 19:52:28 -0700841 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530842}
843
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400844func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700845 var err error
846 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400847
848 if err != nil {
849 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
850 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700851 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
852 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700853
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700854 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700855 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700856 var i uint32
857 for i = 0; i < dh.totalPonPorts; i++ {
858 // Instantiate resource manager
859 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 -0700860 return olterrors.ErrResourceManagerInstantiating
861 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400862 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700863 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
864 // the KV store to manage mcast group data. Provide the first instance (0th index)
865 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
866 return olterrors.ErrGroupManagerInstantiating
867 }
868 for i = 0; i < dh.totalPonPorts; i++ {
869 // Instantiate flow manager
870 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
871 return olterrors.ErrFlowManagerInstantiating
872 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700873 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700874 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400875 /* TODO: Instantiate Alarm , stats , BW managers */
876 /* Instantiating Event Manager to handle Alarms and KPIs */
877 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
878
879 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000880 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400881
882 return nil
883
884}
885
Neha Sharma96b7bf22020-06-15 10:37:32 +0000886func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400887 var err error
888 var deviceInfo *oop.DeviceInfo
889
Neha Sharma8f4e4322020-08-06 10:51:53 +0000890 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400891
892 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000893 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400894 }
895 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000896 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400897 }
898
Neha Sharma96b7bf22020-06-15 10:37:32 +0000899 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400900 dh.device.Root = true
901 dh.device.Vendor = deviceInfo.Vendor
902 dh.device.Model = deviceInfo.Model
903 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
904 dh.device.HardwareVersion = deviceInfo.HardwareVersion
905 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
906
907 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000908 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400909 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000910 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400911 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000912 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400913 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000914 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400915 dh.device.MacAddress = genmac
916 } else {
917 dh.device.MacAddress = deviceInfo.DeviceId
918 }
919
920 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000921 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000922 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400923 }
924
925 return deviceInfo, nil
926}
927
Neha Sharma96b7bf22020-06-15 10:37:32 +0000928func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700929 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530930 for {
931 select {
932 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000933 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530934 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000935 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700936
Neha Sharma8f4e4322020-08-06 10:51:53 +0000937 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400938 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700939 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400940 continue
941 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530942 for _, port := range ports {
943 // NNI Stats
944 if port.Type == voltha.Port_ETHERNET_NNI {
945 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
946 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000947 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000948 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000949 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530950 }
951 // PON Stats
952 if port.Type == voltha.Port_PON_OLT {
953 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
954 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
955 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000956 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000957 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530958 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000959 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000960
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700961 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700962 if len(onuGemInfoLst) > 0 {
963 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000964 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500965 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530966 }
967 }
968 }
969}
970
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700971//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530972func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400973 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000974 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530975 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530976
977 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400978 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
979 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530980 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530981}
982
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700983//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530984func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700985 return &ic.SwitchCapability{
986 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530987 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700988 HwDesc: "open_pon",
989 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700990 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700991 },
992 SwitchFeatures: &of.OfpSwitchFeatures{
993 NBuffers: 256,
994 NTables: 2,
995 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
996 of.OfpCapabilities_OFPC_TABLE_STATS |
997 of.OfpCapabilities_OFPC_PORT_STATS |
998 of.OfpCapabilities_OFPC_GROUP_STATS),
999 },
1000 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301001}
1002
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001003// GetInterAdapterTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
1004func (dh *DeviceHandler) GetInterAdapterTechProfileDownloadMessage(ctx context.Context, tpPath string, ponPortNum uint32, onuID uint32, uniID uint32) *ic.InterAdapterTechProfileDownloadMessage {
1005 ifID, err := IntfIDFromPonPortNum(ctx, ponPortNum)
1006 if err != nil {
1007 return nil
1008 }
1009 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, tpPath, ifID, onuID, uniID)
1010}
1011
Neha Sharma96b7bf22020-06-15 10:37:32 +00001012func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
1013 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 -07001014 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001015 var deviceID string
1016 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -07001017
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001018 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001019 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001020 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 -07001021 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1022 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001023
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001024 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301025
1026 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1027
Neha Sharma96b7bf22020-06-15 10:37:32 +00001028 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 -07001029 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001030 kwargs := make(map[string]interface{})
1031 kwargs["onu_id"] = omciInd.OnuId
1032 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -07001033
Neha Sharma8f4e4322020-08-06 10:51:53 +00001034 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001035 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301036 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001037 "intf-id": omciInd.IntfId,
1038 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001039 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001040 deviceType = onuDevice.Type
1041 deviceID = onuDevice.Id
1042 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1043 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301044 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001045 } else {
1046 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001047 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 +05301048 deviceType = onuInCache.(*OnuDevice).deviceType
1049 deviceID = onuInCache.(*OnuDevice).deviceID
1050 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001051 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001052
1053 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001054 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001055 ic.InterAdapterMessageType_OMCI_RESPONSE, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001056 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301057 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001058 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001059 "destination": deviceType,
1060 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001061 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001062 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001063 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301064}
1065
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001066//ProcessInterAdapterMessage sends the proxied messages to the target device
1067// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1068// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001069func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1070 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001071 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001072 return dh.handleInterAdapterOmciMsg(ctx, msg)
1073 }
1074 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1075}
cuilin20187b2a8c32019-03-26 19:52:28 -07001076
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001077func (dh *DeviceHandler) handleInterAdapterOmciMsg(ctx context.Context, msg *ic.InterAdapterMessage) error {
1078 msgID := msg.Header.Id
1079 fromTopic := msg.Header.FromTopic
1080 toTopic := msg.Header.ToTopic
1081 toDeviceID := msg.Header.ToDeviceId
1082 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001083
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001084 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 -07001085
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001086 msgBody := msg.GetBody()
1087
1088 omciMsg := &ic.InterAdapterOmciMessage{}
1089 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
1090 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
1091 }
1092
1093 if omciMsg.GetProxyAddress() == nil {
1094 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
1095 if err != nil {
1096 return olterrors.NewErrNotFound("onu", log.Fields{
1097 "device-id": dh.device.Id,
1098 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001099 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001100 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 -07001101 if err := dh.sendProxiedOmciMessage(ctx, onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001102 return olterrors.NewErrCommunication("send-failed", log.Fields{
1103 "device-id": dh.device.Id,
1104 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001105 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001106 } else {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001107 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 -07001108 if err := dh.sendProxiedOmciMessage(ctx, nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001109 return olterrors.NewErrCommunication("send-failed", log.Fields{
1110 "device-id": dh.device.Id,
1111 "onu-device-id": toDeviceID}, err)
1112 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001113 }
1114 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301115}
1116
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001117func (dh *DeviceHandler) sendProxiedOmciMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001118 var intfID uint32
1119 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001120 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001121 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001122 intfID = onuDevice.ProxyAddress.GetChannelId()
1123 onuID = onuDevice.ProxyAddress.GetOnuId()
1124 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001125 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001126 intfID = omciMsg.GetProxyAddress().GetChannelId()
1127 onuID = omciMsg.GetProxyAddress().GetOnuId()
1128 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001129 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001130 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001131 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 -08001132
Thomas Lee S94109f12020-03-03 16:39:29 +05301133 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001134 "intf-id": intfID,
1135 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001136 }
1137
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001138 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1139 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001140 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001141 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1142 hex.Encode(hexPkt, omciMsg.Message)
1143 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1144
1145 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1146 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1147 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001148 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001149 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001150
Neha Sharma8f4e4322020-08-06 10:51:53 +00001151 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001152 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301153 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001154 "intf-id": intfID,
1155 "onu-id": onuID,
1156 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001157 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001158 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001159}
1160
David K. Bainbridge794735f2020-02-11 21:01:37 -08001161func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301162 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 -07001163 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001164 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001165 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001166 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301167 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301168 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001169 st, _ := status.FromError(err)
1170 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001171 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1172
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001173 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301174 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001175 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001176 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001177 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001178 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001179 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001180}
1181
Mahir Gunyelb0046752021-02-26 13:51:05 -08001182func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001183 channelID := onuDiscInd.GetIntfId()
1184 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001185
Mahir Gunyelb0046752021-02-26 13:51:05 -08001186 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001187 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301188
cuilin20187b2a8c32019-03-26 19:52:28 -07001189 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001190 if sn != "" {
1191 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001192 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001193 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001194 }
1195
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301196 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001197 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001198 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301199
1200 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1201 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1202 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1203 OnuLosRaise event sent for it */
1204 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1205 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1206 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001207 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301208 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1209 "currentIntfId": onuDiscInd.GetIntfId()})
1210 // TODO:: Should we need to ignore raising OnuLosClear event
1211 // when onu connected to different PON?
1212 }
1213 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1214 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1215 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001216 go func() {
1217 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001218 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001219 }
1220 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301221 }
1222 return true
1223 })
1224
Neha Sharma96b7bf22020-06-15 10:37:32 +00001225 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001226 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001227 }
1228
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001229 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001230
1231 // check the ONU is already know to the OLT
1232 // NOTE the second time the ONU is discovered this should return a device
1233 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1234
1235 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001236 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 -08001237 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001238 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 -08001239 switch e.Code() {
1240 case codes.Internal:
1241 // this probably means NOT FOUND, so just create a new device
1242 onuDevice = nil
1243 case codes.DeadlineExceeded:
1244 // if the call times out, cleanup and exit
1245 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001246 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001247 }
1248 }
1249 }
1250
1251 if onuDevice == nil {
1252 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001253 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001254 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001255 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001256 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001257
Neha Sharma96b7bf22020-06-15 10:37:32 +00001258 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001259
1260 if err != nil {
1261 // if we can't create an ID in resource manager,
1262 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001263 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001264 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001265 "pon-intf-id": ponintfid,
1266 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001267 }
1268
Neha Sharma8f4e4322020-08-06 10:51:53 +00001269 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001270 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001271 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001272 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 +05301273 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001274 "pon-intf-id": ponintfid,
1275 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001276 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001277 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 -07001278 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001279 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001280 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301281 log.Fields{"onuDevice": onuDevice,
1282 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001283 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301284 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001285 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001286
1287 // we can now use the existing ONU Id
1288 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001289 //Insert the ONU into cache to use in OnuIndication.
1290 //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 +00001291 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001292 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301293 "intfId": onuDiscInd.GetIntfId(),
1294 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001295 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001296
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301297 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301298 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001299 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301300 log.Fields{"onu": onuDev,
1301 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001302
Kent Hagermane6ff1012020-07-14 15:07:53 -04001303 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301304 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001305 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001306 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001307 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001308 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001309 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301310 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001311 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001312 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001313 }
1314 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001315}
1316
Mahir Gunyelb0046752021-02-26 13:51:05 -08001317func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001318
1319 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001320 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001321 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001322 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001323 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001324 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301325 log.Fields{"onuId": onuInd.OnuId,
1326 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301327 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001328 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001329 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301330
David K. Bainbridge794735f2020-02-11 21:01:37 -08001331 errFields := log.Fields{"device-id": dh.device.Id}
1332
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301333 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1334
Mahir Gunyele77977b2019-06-27 05:36:22 -07001335 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1336 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001337 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001338 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001339 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001340 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1341 if serialNumber != "" {
1342 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001343 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001344 } else {
1345 kwargs["onu_id"] = onuInd.OnuId
1346 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001347 errFields["onu-id"] = onuInd.OnuId
1348 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001349 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001350 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001351 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001352
David K. Bainbridge794735f2020-02-11 21:01:37 -08001353 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001354 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001355 }
1356
David K. Bainbridge794735f2020-02-11 21:01:37 -08001357 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001358 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001359 "previousIntfId": onuDevice.ParentPortNo,
1360 "currentIntfId": ponPort})
1361 }
1362
1363 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001364 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301365 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1366 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301367 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001368 }
1369 if !foundInCache {
1370 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1371
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301372 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 -08001373
1374 }
kesavand7cf3a052020-08-28 12:49:18 +05301375 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001376 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001377 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301378 }
1379 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001380 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001381 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001382 }
1383 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001384}
1385
Neha Sharma96b7bf22020-06-15 10:37:32 +00001386func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001387 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 -07001388 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1389 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1390 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1391 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001392 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001393 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1394 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001395 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001396 onuInd.OperState = "down"
1397 }
1398 }
1399
David K. Bainbridge794735f2020-02-11 21:01:37 -08001400 switch onuInd.OperState {
1401 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001402 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 -07001403 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301404 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001405 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001406 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301407 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001408 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001409 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001410 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001411 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001412 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001413 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001414 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 -04001415 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301416 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001417 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001418 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301419 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001420 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001421 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001422 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001423 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001424 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001425 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001426 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001427 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001428 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001429}
1430
cuilin20187b2a8c32019-03-26 19:52:28 -07001431func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1432 if serialNum != nil {
1433 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001434 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001435 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001436}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001437func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1438 decodedStr, err := hex.DecodeString(serialNum[4:])
1439 if err != nil {
1440 return nil, err
1441 }
1442 return &oop.SerialNumber{
1443 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001444 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001445 }, nil
1446}
cuilin20187b2a8c32019-03-26 19:52:28 -07001447
1448func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001449 if len(vendorSpecific) > 3 {
1450 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1451 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1452 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1453 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1454 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1455 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1456 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1457 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1458 return tmp
1459 }
1460 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001461}
1462
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001463//UpdateFlowsBulk upates the bulk flow
1464func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301465 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001466}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001467
1468//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001469func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1470 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301471 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001472 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301473 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001474 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001475 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001476 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001477 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001478 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001479 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001480 "intf-id": parentPort,
1481 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001482 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001483 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 -08001484 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301485}
1486
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001487// SendPacketInToCore sends packet-in to core
1488// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1489// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001490func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001491 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001492 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001493 "port": logicalPort,
1494 "packet": hex.EncodeToString(packetPayload),
1495 "device-id": dh.device.Id,
1496 })
1497 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001498 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 +05301499 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001500 "source": "adapter",
1501 "destination": "core",
1502 "device-id": dh.device.Id,
1503 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001504 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001505 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001506 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001507 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001508 "packet": hex.EncodeToString(packetPayload),
1509 "device-id": dh.device.Id,
1510 })
1511 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001512 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001513}
1514
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001515// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001516func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001517 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001518
1519 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1520 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001521 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001522 }
1523
Kent Hagermane6ff1012020-07-14 15:07:53 -04001524 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001525 metrics := dh.metrics.GetSubscriberMetrics()
1526 for _, m := range pmConfigs.Metrics {
1527 metrics[m.Name].Enabled = m.Enabled
1528
1529 }
1530 }
1531}
1532
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001533//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301534func (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 +00001535 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 +01001536
Girish Gowdra491a9c62021-01-06 16:43:07 -08001537 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001538 var errorsList []error
1539
Girish Gowdru0c588b22019-04-23 23:24:56 -04001540 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001541 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001542 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001543
Neha Sharma96b7bf22020-06-15 10:37:32 +00001544 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301545 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001546 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301547 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001548 if flow_utils.HasGroup(flow) {
1549 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1550 } else {
1551 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1552 }
Girish Gowdracefae192020-03-19 18:14:10 -07001553 if err != nil {
1554 errorsList = append(errorsList, err)
1555 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001556 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301557
1558 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001559 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001560 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301561 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001562 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301563 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001564 if flow_utils.HasGroup(flow) {
1565 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1566 } else {
1567 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1568 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001569 if err != nil {
1570 errorsList = append(errorsList, err)
1571 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301572 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001573 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001574
Girish Gowdracefae192020-03-19 18:14:10 -07001575 // Whether we need to synchronize multicast group adds and modifies like flow add and delete needs to be investigated
Esin Karamanccb714b2019-11-29 15:02:06 +00001576 if groups != nil {
1577 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001578 // err = dh.groupMgr.AddGroup(ctx, group)
1579 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001580 if err != nil {
1581 errorsList = append(errorsList, err)
1582 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001583 }
1584 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001585 // err = dh.groupMgr.ModifyGroup(ctx, group)
1586 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001587 if err != nil {
1588 errorsList = append(errorsList, err)
1589 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001590 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001591 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001592 // err = dh.groupMgr.DeleteGroup(ctx, group)
1593 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001594 if err != nil {
1595 errorsList = append(errorsList, err)
1596 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001597 }
1598 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001599 if len(errorsList) > 0 {
1600 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1601 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001602 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001603 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301604}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001605
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001606//DisableDevice disables the given device
1607//It marks the following for the given device:
1608//Device-Handler Admin-State : down
1609//Device Port-State: UNKNOWN
1610//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001611func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001612 /* On device disable ,admin state update has to be done prior sending request to agent since
1613 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001614 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001615 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001616 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001617 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001618 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001619 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001620 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001621 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001622 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001623 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301624
1625 dh.discOnus = sync.Map{}
1626 dh.onus = sync.Map{}
1627
Thomas Lee S85f37312020-04-03 17:06:12 +05301628 //stopping the stats collector
1629 dh.stopCollector <- true
1630
Neha Sharma96b7bf22020-06-15 10:37:32 +00001631 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001632 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301633 //Update device Admin state
1634 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001635 // Update the all pon ports state on that device to disable and NNI remains active as NNI remains active in openolt agent.
Neha Sharma8f4e4322020-08-06 10:51:53 +00001636 if err := dh.coreProxy.PortsStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), cloned.Id, ^uint32(1<<voltha.Port_PON_OLT), voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001637 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001638 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001639 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001640 return nil
1641}
1642
Neha Sharma96b7bf22020-06-15 10:37:32 +00001643func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001644 // Update onu state as unreachable in onu adapter
1645 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301646 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001647 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001648 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001649 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001650 logger.Errorw(ctx, "failed-to-get-child-devices-information", log.Fields{"device-id": dh.device.Id, "err": err})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001651 }
1652 if onuDevices != nil {
1653 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001654 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001655 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001656 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001657 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001658 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001659 }
1660
1661 }
1662 }
1663
1664}
1665
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001666//ReenableDevice re-enables the olt device after disable
1667//It marks the following for the given device:
1668//Device-Handler Admin-State : up
1669//Device Port-State: ACTIVE
1670//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001671func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001672 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301673 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001674 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301675 }
1676 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001677 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001678
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001679 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001680
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001681 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1682 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001683 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001684 }
1685 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001686 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001687 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001688 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001689 device.OperStatus = voltha.OperStatus_ACTIVE
1690 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001691
Neha Sharma8f4e4322020-08-06 10:51:53 +00001692 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), device.Id, device.ConnectStatus, device.OperStatus); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301693 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001694 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001695 "connect-status": device.ConnectStatus,
1696 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001697 }
kesavand39e0aa32020-01-28 20:58:50 -05001698
Neha Sharma96b7bf22020-06-15 10:37:32 +00001699 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001700
1701 return nil
1702}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001703
npujarec5762e2020-01-01 14:08:48 +05301704func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001705 var uniID uint32
1706 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301707 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001708 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001709 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001710 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001711 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001712 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001713 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001714 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001715 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001716 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001717 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001718 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001719 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001720 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001721 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001722 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001723 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001724 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301725 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001726 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1727 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001728 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301729 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001730 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001731 if err = dh.resourceMgr[onu.IntfID].DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001732 logger.Debugw(ctx, "failed-to-remove-gemport-pkt-in", log.Fields{"intfid": onu.IntfID, "onuid": onu.OnuID, "uniId": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001733 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001734 }
1735 return nil
1736}
1737
Devmalya Paul495b94a2019-08-27 19:42:00 -04001738// DeleteDevice deletes the device instance from openolt handler array. Also clears allocated resource manager resources. Also reboots the OLT hardware!
npujarec5762e2020-01-01 14:08:48 +05301739func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001740 logger.Debugw(ctx, "function-entry-delete-device", log.Fields{"device-id": dh.device.Id})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001741 /* Clear the KV store data associated with the all the UNI ports
1742 This clears up flow data and also resource map data for various
1743 other pon resources like alloc_id and gemport_id
1744 */
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001745 dh.cleanupDeviceResources(ctx)
1746 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 -04001747 // Stop the Stats collector
1748 dh.stopCollector <- true
1749 // stop the heartbeat check routine
1750 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301751 dh.lockDevice.RLock()
1752 // Stop the read indication only if it the routine is active
1753 if dh.isReadIndicationRoutineActive {
1754 dh.stopIndications <- true
1755 }
1756 dh.lockDevice.RUnlock()
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001757 dh.removeOnuIndicationChannels(ctx)
Girish Gowdra4736e5c2021-08-25 15:19:10 -07001758 go dh.StopAllMcastHandlerRoutines(ctx)
1759 for _, flMgr := range dh.flowMgr {
1760 go flMgr.StopAllFlowHandlerRoutines(ctx)
1761 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001762 //Reset the state
1763 if dh.Client != nil {
1764 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301765 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001766 }
1767 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001768 // There is no need to update the core about operation status and connection status of the OLT.
1769 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1770 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1771 // because the device does not exist in DB.
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001772
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001773 return nil
1774}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001775func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001776
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001777 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301778 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001779 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001780 var err error
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001781 onuGemData := dh.flowMgr[ponPort].getOnuGemInfoList(ctx)
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001782 for i, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301783 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001784 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001785 if err = dh.clearUNIData(ctx, &onuGemData[i]); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001786 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301787 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301788 // Clear flowids for gem cache.
1789 for _, gem := range onu.GemPorts {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001790 dh.resourceMgr[ponPort].DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301791 }
1792 onuID[0] = onu.OnuID
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001793 dh.resourceMgr[ponPort].FreeonuID(ctx, ponPort, onuID)
1794 err = dh.resourceMgr[ponPort].DelOnuGemInfo(ctx, ponPort, onu.OnuID)
1795 if err != nil {
1796 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
1797 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301798 }
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001799 if err := dh.resourceMgr[ponPort].Delete(ctx, ponPort); err != nil {
1800 logger.Debug(ctx, err)
1801 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001802 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001803 }
A R Karthick1f85b802019-10-11 05:06:05 +00001804
Devmalya Paul495b94a2019-08-27 19:42:00 -04001805 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301806 dh.onus.Range(func(key interface{}, value interface{}) bool {
1807 dh.onus.Delete(key)
1808 return true
1809 })
1810
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001811 /*Delete discovered ONU map for the device*/
1812 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1813 dh.discOnus.Delete(key)
1814 return true
1815 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001816}
1817
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001818//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001819func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001820 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301821 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001822 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001823 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001824 return nil
1825}
1826
David K. Bainbridge794735f2020-02-11 21:01:37 -08001827func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001828 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001829 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001830 "packet-indication": *packetIn,
1831 "device-id": dh.device.Id,
1832 "packet": hex.EncodeToString(packetIn.Pkt),
1833 })
1834 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001835 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001836 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001837 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001838 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001839 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001840 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001841 "logical-port-num": logicalPortNum,
1842 "device-id": dh.device.Id,
1843 "packet": hex.EncodeToString(packetIn.Pkt),
1844 })
1845 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001846
Neha Sharma8f4e4322020-08-06 10:51:53 +00001847 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 +05301848 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001849 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301850 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001851 "device-id": dh.device.Id,
1852 "packet": hex.EncodeToString(packetIn.Pkt),
1853 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001854 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001855
Matteo Scandolo92186242020-06-12 10:54:18 -07001856 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001857 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001858 "packet": hex.EncodeToString(packetIn.Pkt),
1859 "device-id": dh.device.Id,
1860 })
1861 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001862 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001863}
1864
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001865// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301866func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001867 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001868 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001869 "device-id": dh.device.Id,
1870 "egress-port-no": egressPortNo,
1871 "pkt-length": len(packet.Data),
1872 "packet": hex.EncodeToString(packet.Data),
1873 })
1874 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001875
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001876 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001877 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001878 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1879 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301880 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1881 // Do not packet-out lldp packets on uni port.
1882 // ONOS has no clue about uni/nni ports, it just packets out on all
1883 // available ports on the Logical Switch. It should not be interested
1884 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001885 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001886 "device-id": dh.device.Id,
1887 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301888 return nil
1889 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001890 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1891 if innerEthType == 0x8100 {
1892 // q-in-q 802.1ad or 802.1q double tagged packet.
1893 // slice out the outer tag.
1894 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001895 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001896 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001897 "packet-data": hex.EncodeToString(packet.Data),
1898 "device-id": dh.device.Id,
1899 })
1900 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001901 }
1902 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001903 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1904 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001905 uniID := UniIDFromPortNum(uint32(egressPortNo))
1906
Girish Gowdra9602eb42020-09-09 15:50:39 -07001907 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001908 if err != nil {
1909 // In this case the openolt agent will receive the gemPortID as 0.
1910 // The agent tries to retrieve the gemPortID in this case.
1911 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001912 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001913 "intf-id": intfID,
1914 "onu-id": onuID,
1915 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001916 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301917 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001918 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001919 }
1920
1921 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001922 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001923 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001924 "egress-port-no": egressPortNo,
1925 "intf-id": intfID,
1926 "onu-id": onuID,
1927 "uni-id": uniID,
1928 "gem-port-id": gemPortID,
1929 "packet": hex.EncodeToString(packet.Data),
1930 "device-id": dh.device.Id,
1931 })
1932 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001933
npujarec5762e2020-01-01 14:08:48 +05301934 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301935 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001936 "source": "adapter",
1937 "destination": "onu",
1938 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001939 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001940 "oni-id": onuID,
1941 "uni-id": uniID,
1942 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001943 "packet": hex.EncodeToString(packet.Data),
1944 "device-id": dh.device.Id,
1945 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001946 }
1947 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001948 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001949 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001950 return olterrors.NewErrInvalidValue(log.Fields{
1951 "egress-nni-port": egressPortNo,
1952 "device-id": dh.device.Id,
1953 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001954 }
1955 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001956
Matteo Scandolo92186242020-06-12 10:54:18 -07001957 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001958 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001959 "uplink-pkt": uplinkPkt,
1960 "packet": hex.EncodeToString(packet.Data),
1961 "device-id": dh.device.Id,
1962 })
1963 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001964
npujarec5762e2020-01-01 14:08:48 +05301965 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001966 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1967 "packet": hex.EncodeToString(packet.Data),
1968 "device-id": dh.device.Id,
1969 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001970 }
1971 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001972 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301973 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001974 "egressPortType": egressPortType,
1975 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301976 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001977 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001978 }
1979 return nil
1980}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001981
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001982func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1983 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001984}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301985
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001986func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001987
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301988 // start the heartbeat check towards the OLT.
1989 var timerCheck *time.Timer
1990
1991 for {
1992 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1993 select {
1994 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001995 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001996 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001997 logger.Warnw(ctx, "heartbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301998 if timerCheck == nil {
1999 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002000 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302001 }
2002 } else {
2003 if timerCheck != nil {
2004 if timerCheck.Stop() {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002005 logger.Debugw(ctx, "got-heartbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302006 }
2007 timerCheck = nil
2008 }
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002009 logger.Debugw(ctx, "heartbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05302010 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05302011 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302012 }
2013 cancel()
2014 case <-dh.stopHeartbeatCheck:
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002015 logger.Debugw(ctx, "stopping-heartbeat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302016 return
2017 }
2018 }
2019}
2020
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002021func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
2022 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
2023 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002024 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2025 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2026 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2027 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2028 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002029 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002030 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2031 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002032 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302033
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002034 logger.Debugw(ctx, "update-state-unreachable", log.Fields{"device-id": dh.device.Id, "connect-status": device.ConnectStatus,
2035 "admin-state": device.AdminState, "oper-status": device.OperStatus})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002036 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
2037 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002038 _ = 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 -04002039 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002040 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002041 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002042 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002043
2044 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002045 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +00002046 device.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2047 device.OperStatus = voltha.OperStatus_UNKNOWN
2048 go dh.eventMgr.oltCommunicationEvent(ctx, device, raisedTs)
2049
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07002050 dh.cleanupDeviceResources(ctx)
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002051 // Stop the Stats collector
2052 dh.stopCollector <- true
2053 // stop the heartbeat check routine
2054 dh.stopHeartbeatCheck <- true
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002055
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002056 dh.lockDevice.RLock()
2057 // Stop the read indication only if it the routine is active
2058 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2059 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2060 // on next execution of the readIndication routine.
2061 if dh.isReadIndicationRoutineActive {
2062 dh.stopIndications <- true
2063 }
2064 dh.lockDevice.RUnlock()
2065
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002066 go dh.StopAllMcastHandlerRoutines(ctx)
2067 for _, flMgr := range dh.flowMgr {
2068 go flMgr.StopAllFlowHandlerRoutines(ctx)
2069 }
2070
Gamze Abakac2c32a62021-03-11 11:44:18 +00002071 //reset adapter reconcile flag
2072 dh.adapterPreviouslyConnected = false
2073
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002074 dh.transitionMap.Handle(ctx, DeviceInit)
2075
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302076 }
2077}
kesavand39e0aa32020-01-28 20:58:50 -05002078
2079// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002080func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2081 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2082 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002083}
2084
2085// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002086func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2087 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2088 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002089}
2090
kdarapu1afeceb2020-02-12 01:38:09 -05002091//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 +00002092func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2093 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002094 if port.GetType() == voltha.Port_ETHERNET_NNI {
2095 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002096 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302097 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302098 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002099 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002100 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002101 }
2102 // fetch interfaceid from PortNo
2103 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2104 ponIntf := &oop.Interface{IntfId: ponID}
2105 var operStatus voltha.OperStatus_Types
2106 if enablePort {
2107 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302108 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002109
2110 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302111 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002112 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002113 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002114 }
2115 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002116 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002117 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002118 } else {
2119 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302120 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002121 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302122 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002123 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002124 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002125 }
2126 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002127 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002128 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002129 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302130 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 +05302131 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302132 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002133 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002134 }
2135 return nil
2136}
2137
kdarapu1afeceb2020-02-12 01:38:09 -05002138//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002139func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002140 // Disable the port and update the oper_port_status to core
2141 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002142 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002143 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002144 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302145 return olterrors.NewErrAdapter("port-disable-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}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002148 }
2149 }
2150 }
2151 return nil
2152}
2153
2154//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002155func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2156 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2157 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002158 if port.Type == voltha.Port_ETHERNET_NNI {
2159 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002160 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002161 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002162 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002163 }
2164 }
2165 if port.Type == voltha.Port_PON_OLT {
2166 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002167 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002168 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002169 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002170 }
2171 }
2172 }
2173}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002174
2175// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002176func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002177 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002178 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2179 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002180
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002181 var sn *oop.SerialNumber
2182 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002183 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302184 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002185 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302186 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002187 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002188 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002189
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002190 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002191 //clear PON resources associated with ONU
2192 onuGem, err := dh.resourceMgr[intfID].GetOnuGemInfo(ctx, intfID, onuID)
2193 if err != nil || onuGem == nil || onuGem.OnuID != onuID {
2194 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
2195 "device-id": dh.device.Id,
2196 "intf-id": intfID,
2197 "onuID": onuID,
2198 "err": err})
2199 } else {
2200 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
2201 if err := dh.clearUNIData(ctx, onuGem); err != nil {
2202 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
2203 "device-id": dh.device.Id,
2204 "onu-device": onu,
2205 "err": err})
2206 }
2207 // Clear flowids for gem cache.
2208 for _, gem := range onuGem.GemPorts {
2209 dh.resourceMgr[intfID].DeleteFlowIDsForGem(ctx, intfID, gem)
2210 }
Girish Gowdra197acc12021-08-16 10:59:45 -07002211 if err := dh.flowMgr[intfID].RemoveOnuInfoFromFlowMgrCacheAndKvStore(ctx, intfID, onuID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002212 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
2213 "intf-id": intfID,
2214 "onu-device": onu,
2215 "onu-gem": onuGem,
2216 "err": err})
2217 //Not returning error on cleanup.
2218 }
2219 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGem})
2220 dh.resourceMgr[intfID].FreeonuID(ctx, intfID, []uint32{onuGem.OnuID})
2221 }
2222 dh.onus.Delete(onuKey)
2223 dh.discOnus.Delete(onuSn)
2224
2225 // Now clear the ONU on the OLT
Neha Sharma8f4e4322020-08-06 10:51:53 +00002226 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302227 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302228 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002229 "onu-id": onuID}, err).Log()
2230 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002231
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002232 return nil
2233}
Girish Gowdracefae192020-03-19 18:14:10 -07002234
2235func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002236 for _, field := range flow_utils.GetOfbFields(flow) {
2237 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002238 return field.GetPort()
2239 }
2240 }
2241 return InvalidPort
2242}
2243
2244func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002245 for _, action := range flow_utils.GetActions(flow) {
2246 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002247 if out := action.GetOutput(); out != nil {
2248 return out.GetPort()
2249 }
2250 }
2251 }
2252 return InvalidPort
2253}
2254
Girish Gowdracefae192020-03-19 18:14:10 -07002255func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2256 inPort := getInPortFromFlow(flow)
2257 outPort := getOutPortFromFlow(flow)
2258
2259 if inPort == InvalidPort || outPort == InvalidPort {
2260 return inPort, outPort
2261 }
2262
2263 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2264 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2265 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002266 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002267 return uniPort, outPort
2268 }
2269 }
2270 } else {
2271 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2272 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002273 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002274 return inPort, uniPort
2275 }
2276 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2277 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002278 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002279 return uniPort, outPort
2280 }
2281 }
2282 }
2283
2284 return InvalidPort, InvalidPort
2285}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002286
2287func extractOmciTransactionID(omciPkt []byte) uint16 {
2288 if len(omciPkt) > 3 {
2289 d := omciPkt[0:2]
2290 transid := binary.BigEndian.Uint16(d)
2291 return transid
2292 }
2293 return 0
2294}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002295
2296// StoreOnuDevice stores the onu parameters to the local cache.
2297func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2298 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2299 dh.onus.Store(onuKey, onuDevice)
2300}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002301
Neha Sharma8f4e4322020-08-06 10:51:53 +00002302func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002303 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002304 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002305 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002306 resp := new(voltha.ReturnValues)
2307 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002308 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002309 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002310 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2311 return nil, err
2312 }
2313 ID = device.ProxyAddress.GetOnuId()
2314 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2315 valueparam.Onu = &Onu
2316 valueparam.Value = value
2317
2318 // This API is unsupported until agent patch is added
2319 resp.Unsupported = uint32(value)
2320 _ = ctx
2321
2322 // Uncomment this code once agent changes are complete and tests
2323 /*
2324 resp, err = dh.Client.GetValue(ctx, valueparam)
2325 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002326 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "err": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002327 return nil, err
2328 }
2329 */
2330
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002331 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 -08002332 return resp, nil
2333}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002334
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002335func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002336 // Default to PON0
2337 var intfID uint32
2338 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002339 if inPort != InvalidPort && outPort != InvalidPort {
2340 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2341 }
2342 return intfID
2343}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002344
Mahir Gunyelb0046752021-02-26 13:51:05 -08002345func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2346 dh.perPonOnuIndicationChannelLock.Lock()
2347 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2348 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002349 return ch.indicationChannel
2350 }
2351 channels := onuIndicationChannels{
2352 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002353 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002354 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002355 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002356 stopChannel: make(chan struct{}),
2357 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002358 dh.perPonOnuIndicationChannel[intfID] = channels
2359 dh.perPonOnuIndicationChannelLock.Unlock()
2360 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002361 return channels.indicationChannel
2362
2363}
2364
Mahir Gunyelb0046752021-02-26 13:51:05 -08002365func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2366 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2367 dh.perPonOnuIndicationChannelLock.Lock()
2368 defer dh.perPonOnuIndicationChannelLock.Unlock()
2369 for _, v := range dh.perPonOnuIndicationChannel {
2370 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002371 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002372 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002373}
2374
Mahir Gunyelb0046752021-02-26 13:51:05 -08002375func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2376 ind := onuIndicationMsg{
2377 ctx: ctx,
2378 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002379 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002380 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002381 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002382 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002383}
2384
Mahir Gunyelb0046752021-02-26 13:51:05 -08002385func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002386 for {
2387 select {
2388 // process one indication per onu, before proceeding to the next one
2389 case onuInd := <-onuChannels.indicationChannel:
2390 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002391 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002392 switch onuInd.indication.Data.(type) {
2393 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002394 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002395 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2396 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002397 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002398 }
2399 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002400 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002401 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2402 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002403 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002404 }
2405 }
2406 case <-onuChannels.stopChannel:
2407 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2408 close(onuChannels.indicationChannel)
2409 return
2410 }
2411 }
2412}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002413
2414// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2415// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2416func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2417 // Step1 : Fill McastFlowOrGroupControlBlock
2418 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2419 // Step3 : Wait on response channel for response
2420 // Step4 : Return error value
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002421 startTime := time.Now()
Girish Gowdra491a9c62021-01-06 16:43:07 -08002422 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2423 errChan := make(chan error)
2424 var groupID uint32
2425 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2426 ctx: ctx,
2427 flowOrGroupAction: action,
2428 flow: flow,
2429 group: group,
2430 errChan: &errChan,
2431 }
2432 if flow != nil {
2433 groupID = flow_utils.GetGroup(flow)
2434 } else if group != nil {
2435 groupID = group.Desc.GroupId
2436 } else {
2437 return errors.New("flow-and-group-both-nil")
2438 }
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002439 mcastRoutineIdx := groupID % MaxNumOfGroupHandlerChannels
2440 if dh.mcastHandlerRoutineActive[mcastRoutineIdx] {
2441 // Derive the appropriate go routine to handle the request by a simple module operation.
2442 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2443 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2444 // Wait for handler to return error value
2445 err := <-errChan
2446 logger.Debugw(ctx, "process-flow-or-group--received-resp", log.Fields{"err": err, "totalTimeInSeconds": time.Since(startTime).Milliseconds()})
2447 return err
2448 }
2449 logger.Errorw(ctx, "mcast handler routine not active for onu", log.Fields{"mcastRoutineIdx": mcastRoutineIdx})
2450 return fmt.Errorf("mcast-handler-routine-not-active-for-index-%v", mcastRoutineIdx)
Girish Gowdra491a9c62021-01-06 16:43:07 -08002451}
2452
2453// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002454func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(routineIndex int, mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock, stopHandler chan bool) {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002455 for {
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002456 select {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002457 // block on the channel to receive an incoming mcast flow/group
2458 // process the flow completely before proceeding to handle the next flow
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002459 case mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel:
2460 if mcastFlowOrGroupCb.flow != nil {
2461 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2462 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2463 log.Fields{"device-id": dh.device.Id,
2464 "flowToAdd": mcastFlowOrGroupCb.flow})
2465 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2466 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2467 // Pass the return value over the return channel
2468 *mcastFlowOrGroupCb.errChan <- err
2469 } else { // flow remove
2470 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2471 log.Fields{"device-id": dh.device.Id,
2472 "flowToRemove": mcastFlowOrGroupCb.flow})
2473 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2474 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2475 // Pass the return value over the return channel
2476 *mcastFlowOrGroupCb.errChan <- err
2477 }
2478 } else { // mcast group
2479 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2480 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2481 log.Fields{"device-id": dh.device.Id,
2482 "groupToAdd": mcastFlowOrGroupCb.group})
2483 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2484 // Pass the return value over the return channel
2485 *mcastFlowOrGroupCb.errChan <- err
2486 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2487 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2488 log.Fields{"device-id": dh.device.Id,
2489 "groupToModify": mcastFlowOrGroupCb.group})
2490 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2491 // Pass the return value over the return channel
2492 *mcastFlowOrGroupCb.errChan <- err
2493 } else { // group remove
2494 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2495 log.Fields{"device-id": dh.device.Id,
2496 "groupToRemove": mcastFlowOrGroupCb.group})
2497 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2498 // Pass the return value over the return channel
2499 *mcastFlowOrGroupCb.errChan <- err
2500 }
Girish Gowdra491a9c62021-01-06 16:43:07 -08002501 }
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002502 case <-stopHandler:
2503 dh.mcastHandlerRoutineActive[routineIndex] = false
2504 return
Girish Gowdra491a9c62021-01-06 16:43:07 -08002505 }
2506 }
2507}
kesavand62126212021-01-12 04:56:06 -05002508
Girish Gowdra4736e5c2021-08-25 15:19:10 -07002509// StopAllMcastHandlerRoutines stops all flow handler routines. Call this when device is being rebooted or deleted
2510func (dh *DeviceHandler) StopAllMcastHandlerRoutines(ctx context.Context) {
2511 for i, v := range dh.stopMcastHandlerRoutine {
2512 if dh.mcastHandlerRoutineActive[i] {
2513 v <- true
2514 }
2515 }
2516 logger.Debug(ctx, "stopped all mcast handler routines")
2517}
2518
kesavand62126212021-01-12 04:56:06 -05002519func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2520
2521 singleValResp := extension.SingleGetValueResponse{
2522 Response: &extension.GetValueResponse{
2523 Response: &extension.GetValueResponse_PortCoutners{
2524 PortCoutners: &extension.GetOltPortCountersResponse{},
2525 },
2526 },
2527 }
2528
2529 errResp := func(status extension.GetValueResponse_Status,
2530 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2531 return &extension.SingleGetValueResponse{
2532 Response: &extension.GetValueResponse{
2533 Status: status,
2534 ErrReason: reason,
2535 },
2536 }
2537 }
2538
2539 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2540 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2541 //send error response
2542 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2543 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2544 }
2545 statIndChn := make(chan bool, 1)
2546 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2547 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2548 //request openOlt agent to send the the port statistics indication
2549
2550 go func() {
2551 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2552 if err != nil {
2553 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2554 }
2555 }()
2556 select {
2557 case <-statIndChn:
2558 //indication received for ports stats
2559 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2560 case <-time.After(oltPortInfoTimeout * time.Second):
2561 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2562 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2563 case <-ctx.Done():
2564 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2565 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2566 }
2567 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2568 //get nni stats
2569 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
2570 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2571 cmnni := dh.portStats.collectNNIMetrics(intfID)
2572 if cmnni == nil {
2573 //TODO define the error reason
2574 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2575 }
2576 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2577 return &singleValResp
2578
2579 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2580 // get pon stats
2581 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
2582 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2583 cmpon := dh.portStats.collectPONMetrics(intfID)
2584 if cmpon == nil {
2585 //TODO define the error reason
2586 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2587 }
2588 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2589 return &singleValResp
2590 }
2591 }
2592 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2593}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +05302594
2595func (dh *DeviceHandler) getOnuPonCounters(ctx context.Context, onuPonInfo *extension.GetOnuCountersRequest) *extension.SingleGetValueResponse {
2596
2597 singleValResp := extension.SingleGetValueResponse{
2598 Response: &extension.GetValueResponse{
2599 Response: &extension.GetValueResponse_OnuPonCounters{
2600 OnuPonCounters: &extension.GetOnuCountersResponse{},
2601 },
2602 },
2603 }
2604
2605 errResp := func(status extension.GetValueResponse_Status,
2606 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2607 return &extension.SingleGetValueResponse{
2608 Response: &extension.GetValueResponse{
2609 Status: status,
2610 ErrReason: reason,
2611 },
2612 }
2613 }
2614 intfID := onuPonInfo.IntfId
2615 onuID := onuPonInfo.OnuId
2616 onuKey := dh.formOnuKey(intfID, onuID)
2617
2618 if _, ok := dh.onus.Load(onuKey); !ok {
2619 logger.Errorw(ctx, "get-onui-pon-counters-request-invalid-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2620 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2621 }
2622 logger.Debugw(ctx, "get-onui-pon-counters-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2623 cmnni := dh.portStats.collectOnDemandOnuStats(ctx, intfID, onuID)
2624 if cmnni == nil {
2625 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2626 }
2627 dh.portStats.updateGetOnuPonCountersResponse(ctx, &singleValResp, cmnni)
2628 return &singleValResp
2629
2630}
Gamze Abaka85e9a142021-05-26 13:41:39 +00002631
2632func (dh *DeviceHandler) getRxPower(ctx context.Context, rxPowerRequest *extension.GetRxPowerRequest) *extension.SingleGetValueResponse {
2633
2634 Onu := oop.Onu{IntfId: rxPowerRequest.IntfId, OnuId: rxPowerRequest.OnuId}
2635 rxPower, err := dh.Client.GetPonRxPower(ctx, &Onu)
2636 if err != nil {
2637 logger.Errorw(ctx, "error-while-getting-rx-power", log.Fields{"Onu": Onu, "err": err})
2638 return generateSingleGetValueErrorResponse(err)
2639 }
2640 return &extension.SingleGetValueResponse{
2641 Response: &extension.GetValueResponse{
2642 Status: extension.GetValueResponse_OK,
2643 Response: &extension.GetValueResponse_RxPower{
2644 RxPower: &extension.GetRxPowerResponse{
2645 IntfId: rxPowerRequest.IntfId,
2646 OnuId: rxPowerRequest.OnuId,
2647 Status: rxPower.Status,
2648 FailReason: rxPower.FailReason.String(),
2649 RxPower: rxPower.RxPowerMeanDbm,
2650 },
2651 },
2652 },
2653 }
2654}
2655
2656func generateSingleGetValueErrorResponse(err error) *extension.SingleGetValueResponse {
2657 errResp := func(status extension.GetValueResponse_Status,
2658 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2659 return &extension.SingleGetValueResponse{
2660 Response: &extension.GetValueResponse{
2661 Status: status,
2662 ErrReason: reason,
2663 },
2664 }
2665 }
2666
2667 if err != nil {
2668 if e, ok := status.FromError(err); ok {
2669 switch e.Code() {
2670 case codes.Internal:
2671 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2672 case codes.DeadlineExceeded:
2673 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2674 case codes.Unimplemented:
2675 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_UNSUPPORTED)
2676 case codes.NotFound:
2677 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2678 }
2679 }
2680 }
2681
2682 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_REASON_UNDEFINED)
2683}