blob: af93713354688564f61babe65ed618dbe8962254 [file] [log] [blame]
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
Phaneendra Manda4c62c802019-03-06 21:37:49 +053019
20import (
cuilin20187b2a8c32019-03-26 19:52:28 -070021 "context"
Matt Jeanneretceea2e02020-03-27 14:19:57 -040022 "encoding/binary"
Matt Jeanneret1359c732019-08-01 21:40:02 -040023 "encoding/hex"
Girish Gowdra491a9c62021-01-06 16:43:07 -080024 "errors"
cuilin20187b2a8c32019-03-26 19:52:28 -070025 "fmt"
26 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040027 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070028 "strconv"
29 "strings"
30 "sync"
31 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053032
Matteo Scandolo945e4012019-12-12 14:16:11 -080033 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070034 "github.com/gogo/protobuf/proto"
35 "github.com/golang/protobuf/ptypes"
Girish Kumar93e91742020-07-27 16:43:19 +000036 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
37 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070038 "github.com/opencord/voltha-lib-go/v5/pkg/adapters/adapterif"
39 "github.com/opencord/voltha-lib-go/v5/pkg/config"
40 "github.com/opencord/voltha-lib-go/v5/pkg/events/eventif"
41 flow_utils "github.com/opencord/voltha-lib-go/v5/pkg/flows"
42 "github.com/opencord/voltha-lib-go/v5/pkg/log"
43 "github.com/opencord/voltha-lib-go/v5/pkg/pmmetrics"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080044
Thomas Lee S94109f12020-03-03 16:39:29 +053045 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080046 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070047 "github.com/opencord/voltha-protos/v4/go/common"
kesavand62126212021-01-12 04:56:06 -050048 "github.com/opencord/voltha-protos/v4/go/extension"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070049 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
50 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
51 oop "github.com/opencord/voltha-protos/v4/go/openolt"
52 "github.com/opencord/voltha-protos/v4/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070053 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040054 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040055 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053056)
57
salmansiddiqui7ac62132019-08-22 03:58:50 +000058// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040059const (
Girish Gowdra491a9c62021-01-06 16:43:07 -080060 InvalidPort = 0xffffffff
61 MaxNumOfGroupHandlerChannels = 256
62
63 McastFlowOrGroupAdd = "McastFlowOrGroupAdd"
64 McastFlowOrGroupModify = "McastFlowOrGroupModify"
65 McastFlowOrGroupRemove = "McastFlowOrGroupRemove"
kesavand62126212021-01-12 04:56:06 -050066 oltPortInfoTimeout = 3
Manikkaraj kb1d51442019-07-23 10:41:02 -040067)
68
Phaneendra Manda4c62c802019-03-06 21:37:49 +053069//DeviceHandler will interact with the OLT device.
70type DeviceHandler struct {
Matteo Scandolodfa7a972020-11-06 13:03:40 -080071 cm *config.ConfigManager
cuilin20187b2a8c32019-03-26 19:52:28 -070072 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053073 coreProxy adapterif.CoreProxy
74 AdapterProxy adapterif.AdapterProxy
Himani Chawlacd407802020-12-10 12:08:59 +053075 EventProxy eventif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070076 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070077 exitChannel chan int
78 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053079 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070080 transitionMap *TransitionMap
81 clientCon *grpc.ClientConn
Girish Gowdra9602eb42020-09-09 15:50:39 -070082 flowMgr []*OpenOltFlowMgr
83 groupMgr *OpenOltGroupMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040084 eventMgr *OpenOltEventMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070085 resourceMgr []*rsrcMgr.OpenOltResourceMgr
86
87 deviceInfo *oop.DeviceInfo
Naga Manjunatha8dc9372019-10-31 23:01:18 +053088
Girish Gowdra3ab6d212020-03-24 17:33:15 -070089 discOnus sync.Map
90 onus sync.Map
91 portStats *OpenOltStatisticsMgr
92 metrics *pmmetrics.PmMetrics
93 stopCollector chan bool
94 stopHeartbeatCheck chan bool
95 activePorts sync.Map
96 stopIndications chan bool
97 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070098
Mahir Gunyelb0046752021-02-26 13:51:05 -080099 totalPonPorts uint32
100 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
101 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800102
103 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
104 // A go routine per index, waits on a unique channel for incoming mcast flow or group (add/modify/remove).
105 incomingMcastFlowOrGroup []chan McastFlowOrGroupControlBlock
Gamze Abakac2c32a62021-03-11 11:44:18 +0000106
107 adapterPreviouslyConnected bool
108 agentPreviouslyConnected bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700109}
110
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700111//OnuDevice represents ONU related info
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700112type OnuDevice struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700113 deviceID string
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700114 deviceType string
115 serialNumber string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700116 onuID uint32
117 intfID uint32
118 proxyDeviceID string
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530119 losRaised bool
Devmalya Paula1efa642020-04-20 01:36:43 -0400120 rdiRaised bool
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700121}
122
Mahir Gunyelb0046752021-02-26 13:51:05 -0800123type onuIndicationMsg struct {
124 ctx context.Context
125 indication *oop.Indication
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800126}
127
128type onuIndicationChannels struct {
Mahir Gunyelb0046752021-02-26 13:51:05 -0800129 indicationChannel chan onuIndicationMsg
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800130 stopChannel chan struct{}
131}
132
Girish Gowdra491a9c62021-01-06 16:43:07 -0800133//McastFlowOrGroupControlBlock is created per mcast flow/group add/modify/remove and pushed on the incomingMcastFlowOrGroup channel slice
134//The McastFlowOrGroupControlBlock is then picked by the mcastFlowOrGroupChannelHandlerRoutine for further processing.
135//There are MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine routines which monitor for any incoming mcast flow/group messages
136//and process them serially. The mcast flow/group are assigned these routines based on formula (group-id modulo MaxNumOfGroupHandlerChannels)
137type McastFlowOrGroupControlBlock struct {
138 ctx context.Context // Flow/group handler context
139 flowOrGroupAction string // one of McastFlowOrGroupAdd, McastFlowOrGroupModify or McastFlowOrGroupDelete
140 flow *voltha.OfpFlowStats // Flow message (can be nil or valid flow)
141 group *voltha.OfpGroupEntry // Group message (can be nil or valid group)
142 errChan *chan error // channel to report the mcast Flow/group handling error
143}
144
Naga Manjunath7615e552019-10-11 22:35:47 +0530145var pmNames = []string{
146 "rx_bytes",
147 "rx_packets",
148 "rx_mcast_packets",
149 "rx_bcast_packets",
150 "tx_bytes",
151 "tx_packets",
152 "tx_mcast_packets",
153 "tx_bcast_packets",
154}
155
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700156//NewOnuDevice creates a new Onu Device
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530157func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string, losRaised bool) *OnuDevice {
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700158 var device OnuDevice
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700159 device.deviceID = devID
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700160 device.deviceType = deviceTp
161 device.serialNumber = serialNum
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700162 device.onuID = onuID
163 device.intfID = intfID
164 device.proxyDeviceID = proxyDevID
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +0530165 device.losRaised = losRaised
Mahir Gunyela3f9add2019-06-06 15:13:19 -0700166 return &device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530167}
168
169//NewDeviceHandler creates a new device handler
Himani Chawlacd407802020-12-10 12:08:59 +0530170func 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 -0700171 var dh DeviceHandler
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800172 dh.cm = cm
cuilin20187b2a8c32019-03-26 19:52:28 -0700173 dh.coreProxy = cp
Girish Gowdru0c588b22019-04-23 23:24:56 -0400174 dh.AdapterProxy = ap
Devmalya Paulfb990a52019-07-09 10:01:49 -0400175 dh.EventProxy = ep
cuilin20187b2a8c32019-03-26 19:52:28 -0700176 cloned := (proto.Clone(device)).(*voltha.Device)
cuilin20187b2a8c32019-03-26 19:52:28 -0700177 dh.device = cloned
178 dh.openOLT = adapter
179 dh.exitChannel = make(chan int, 1)
180 dh.lockDevice = sync.RWMutex{}
Naga Manjunath7615e552019-10-11 22:35:47 +0530181 dh.stopCollector = make(chan bool, 2)
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +0530182 dh.stopHeartbeatCheck = make(chan bool, 2)
Naga Manjunath7615e552019-10-11 22:35:47 +0530183 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 -0500184 dh.activePorts = sync.Map{}
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400185 dh.stopIndications = make(chan bool, 1)
Mahir Gunyelb0046752021-02-26 13:51:05 -0800186 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Girish Gowdra491a9c62021-01-06 16:43:07 -0800187 // Create a slice of buffered channels for handling concurrent mcast flow/group.
188 dh.incomingMcastFlowOrGroup = make([]chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
189 for i := range dh.incomingMcastFlowOrGroup {
190 dh.incomingMcastFlowOrGroup[i] = make(chan McastFlowOrGroupControlBlock, MaxNumOfGroupHandlerChannels)
191 // Spin up a go routine to handling incoming mcast flow/group (add/modify/remove).
192 // There will be MaxNumOfGroupHandlerChannels number of mcastFlowOrGroupChannelHandlerRoutine go routines.
193 // These routines will be blocked on the dh.incomingMcastFlowOrGroup[mcast-group-id modulo MaxNumOfGroupHandlerChannels] channel
194 // for incoming mcast flow/group to be processed serially.
195 go dh.mcastFlowOrGroupChannelHandlerRoutine(dh.incomingMcastFlowOrGroup[i])
196 }
cuilin20187b2a8c32019-03-26 19:52:28 -0700197 //TODO initialize the support classes.
198 return &dh
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530199}
200
201// start save the device to the data model
202func (dh *DeviceHandler) start(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700203 dh.lockDevice.Lock()
204 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000205 logger.Debugw(ctx, "starting-device-agent", log.Fields{"device": dh.device})
cuilin20187b2a8c32019-03-26 19:52:28 -0700206 // Add the initial device to the local model
Neha Sharma96b7bf22020-06-15 10:37:32 +0000207 logger.Debug(ctx, "device-agent-started")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530208}
209
210// stop stops the device dh. Not much to do for now
211func (dh *DeviceHandler) stop(ctx context.Context) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700212 dh.lockDevice.Lock()
213 defer dh.lockDevice.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000214 logger.Debug(ctx, "stopping-device-agent")
cuilin20187b2a8c32019-03-26 19:52:28 -0700215 dh.exitChannel <- 1
Neha Sharma96b7bf22020-06-15 10:37:32 +0000216 logger.Debug(ctx, "device-agent-stopped")
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530217}
218
ssiddiqui5dcd2312021-08-23 21:58:25 +0530219func (dh *DeviceHandler) getPonTechnology(intfID uint32) string {
220 for _, resourceRanges := range dh.deviceInfo.GetRanges() {
221 for _, pooledIntfID := range resourceRanges.GetIntfIds() {
222 if pooledIntfID == intfID {
223 return resourceRanges.GetTechnology()
224 }
225 }
226 }
227 return ""
228}
229
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400230func macifyIP(ip net.IP) string {
231 if len(ip) > 0 {
232 oct1 := strconv.FormatInt(int64(ip[12]), 16)
233 oct2 := strconv.FormatInt(int64(ip[13]), 16)
234 oct3 := strconv.FormatInt(int64(ip[14]), 16)
235 oct4 := strconv.FormatInt(int64(ip[15]), 16)
236 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
237 }
238 return ""
239}
240
Neha Sharma96b7bf22020-06-15 10:37:32 +0000241func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400242 var genmac string
243 var addr net.IP
244 var ips []string
245 var err error
246
Neha Sharma96b7bf22020-06-15 10:37:32 +0000247 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400248
249 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000250 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400251
252 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000253 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400254 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000255 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400256 }
257 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000258 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530259 log.Fields{"host": ips[0],
260 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400261 return genmac, nil
262 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000263 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400264 }
265
266 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000267 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530268 log.Fields{"host": host,
269 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400270 return genmac, nil
271}
272
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530273func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700274 slist := strings.Split(mac, ":")
275 result := make([]uint32, len(slist))
276 var err error
277 var tmp int64
278 for index, val := range slist {
279 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
280 return []uint32{1, 2, 3, 4, 5, 6}
281 }
282 result[index] = uint32(tmp)
283 }
284 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530285}
286
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700287//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 -0800288func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530289
David K. Bainbridge794735f2020-02-11 21:01:37 -0800290 switch portType {
291 case voltha.Port_ETHERNET_NNI:
292 return fmt.Sprintf("nni-%d", portNum), nil
293 case voltha.Port_PON_OLT:
294 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700295 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800296
Girish Kumarf26e4882020-03-05 06:49:10 +0000297 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530298}
299
Neha Sharma96b7bf22020-06-15 10:37:32 +0000300func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000301 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700302 if state == "up" {
303 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500304 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500305 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700306 } else {
307 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500308 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700309 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700310 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400311 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800312 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000313 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400314 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500315
Neha Sharma8f4e4322020-08-06 10:51:53 +0000316 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 +0000317 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000318 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 -0400319 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
320 "device-id": dh.device.Id,
321 "port-type": portType,
322 "port-number": portNum,
323 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500324 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400325 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500326 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400327 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700328 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400329 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700330 PortNo: portNum,
331 Label: label,
332 Type: portType,
333 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700334 OfpPort: &of.OfpPort{
335 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
336 Config: 0,
337 State: uint32(of.OfpPortState_OFPPS_LIVE),
338 Curr: capacity,
339 Advertised: capacity,
340 Peer: capacity,
341 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
342 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
343 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700344 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000345 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700346 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000347 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000348 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800349 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000350 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400351 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000352 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530353 return nil
354}
355
Kent Hagermane6ff1012020-07-14 15:07:53 -0400356func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000357 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530358 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400359 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
360 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530361 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800362 dh.lockDevice.Lock()
363 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530364 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530365}
366
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700367// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530368// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800369func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000370 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700371 defer func() {
372 dh.lockDevice.Lock()
373 dh.isReadIndicationRoutineActive = false
374 dh.lockDevice.Unlock()
375 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700376 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700377 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700378 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700379 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400380
David Bainbridgef5879ca2019-12-13 21:17:54 +0000381 // Create an exponential backoff around re-enabling indications. The
382 // maximum elapsed time for the back off is set to 0 so that we will
383 // continue to retry. The max interval defaults to 1m, but is set
384 // here for code clarity
385 indicationBackoff := backoff.NewExponentialBackOff()
386 indicationBackoff.MaxElapsedTime = 0
387 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700388
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700389 dh.lockDevice.Lock()
390 dh.isReadIndicationRoutineActive = true
391 dh.lockDevice.Unlock()
392
Girish Gowdra3f974912020-03-23 20:35:18 -0700393Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700394 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400395 select {
396 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000397 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700398 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400399 default:
400 indication, err := indications.Recv()
401 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000402 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530403 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530404 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400405 // Use an exponential back off to prevent getting into a tight loop
406 duration := indicationBackoff.NextBackOff()
407 if duration == backoff.Stop {
408 // If we reach a maximum then warn and reset the backoff
409 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000410 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530411 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530412 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400413 indicationBackoff.Reset()
414 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700415
416 // On failure process a backoff timer while watching for stopIndications
417 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700418 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700419 select {
420 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000421 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700422 if !backoffTimer.Stop() {
423 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700424 }
425 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700426 case <-backoffTimer.C:
427 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700428 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700429 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
430 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400431 }
432 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000433 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530434 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000435 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530436 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530437 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700438 // Close the stream, and re-initialize it
439 if err = indications.CloseSend(); err != nil {
440 // Ok to ignore here, because we landed here due to a problem on the stream
441 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000442 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530443 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530444 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700445 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000446 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700447 return err
448 }
449 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400450 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530451 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400452 // Reset backoff if we have a successful receive
453 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400454 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700455 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000456 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530457 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530458 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400459 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400460 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400461 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700462 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700463 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700464 // Close the send stream
465 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700466
Girish Gowdra3f974912020-03-23 20:35:18 -0700467 return nil
468}
469
470func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700471 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700472 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
473 if err != nil {
474 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
475 }
476 if indications == nil {
477 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
478 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700479 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700480 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400481}
482
483// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
484func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
485 switch indication.Data.(type) {
486 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
487 return true
488
489 default:
490 return false
491 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700492}
493
David K. Bainbridge794735f2020-02-11 21:01:37 -0800494func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700495 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000496 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530497 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700498 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530499 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700500 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000501 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000502 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530503 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000504 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800505 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000506 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800507 }
508 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700509}
510
David K. Bainbridge794735f2020-02-11 21:01:37 -0800511// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530512func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700513 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700514 switch indication.Data.(type) {
515 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000516 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
517 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700518 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 -0800519 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400520 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800521 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700522 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000523 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
524 defer span.Finish()
525
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700526 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800527 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000528 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400529 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800530 }
531 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000532 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700533 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000534 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
535 defer span.Finish()
536
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700537 intfOperInd := indication.GetIntfOperInd()
538 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800539 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000540 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400541 _ = 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 -0800542 }
543 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700544 } else if intfOperInd.GetType() == "pon" {
545 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
546 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800547 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000548 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400549 _ = 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 -0800550 }
551 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000552 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700553 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000554 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530555 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530556 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700557 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000558 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
559 defer span.Finish()
560
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700561 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000562 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800563 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800564 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700565 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000566 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
567 defer span.Finish()
568
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700569 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000570 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800571 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800572 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700573 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000574 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
575 defer span.Finish()
576
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700577 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000578 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 -0800579 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000580 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400581 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800582 }
583 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700584 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000585 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
586 defer span.Finish()
587
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700588 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000589 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700590 "intf-type": pktInd.IntfId,
591 "intf-id": pktInd.IntfId,
592 "gem-port-id": pktInd.GemportId,
593 "port-no": pktInd.PortNo,
594 "device-id": dh.device.Id,
595 })
596
597 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000598 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700599 "intf-type": pktInd.IntfId,
600 "intf-id": pktInd.IntfId,
601 "gem-port-id": pktInd.GemportId,
602 "port-no": pktInd.PortNo,
603 "packet": hex.EncodeToString(pktInd.Pkt),
604 "device-id": dh.device.Id,
605 })
606 }
607
David K. Bainbridge794735f2020-02-11 21:01:37 -0800608 go func() {
609 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400610 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800611 }
612 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700613 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000614 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
615 defer span.Finish()
616
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700617 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700618 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700619 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000620 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
621 defer span.Finish()
622
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700623 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000624 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700625 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000626 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
627 defer span.Finish()
628
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700629 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
631 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700632 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530633}
634
635// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530636func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530637 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000638 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530639
Girish Gowdru0c588b22019-04-23 23:24:56 -0400640 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530641 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400642 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000643 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400644 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000645
646 //Clear olt communication failure event
647 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
648 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700649 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000650 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
651
Gamze Abakac2c32a62021-03-11 11:44:18 +0000652 //check adapter and agent reconcile status
653 //reboot olt if needed (olt disconnection case)
654 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
655 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
656 log.Fields{
657 "device-id": dh.device.Id,
658 "adapter-status": dh.adapterPreviouslyConnected,
659 "agent-status": dh.agentPreviouslyConnected,
660 })
661 _ = dh.RebootDevice(ctx, dh.device)
662 }
663
Girish Gowdru0c588b22019-04-23 23:24:56 -0400664 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530665}
666
667// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530668func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000669 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400670
npujarec5762e2020-01-01 14:08:48 +0530671 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400672 if err != nil || device == nil {
673 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000674 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400675 }
676
677 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400678
679 //Update the device oper state and connection status
680 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800681 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400682 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800683 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400684
David K. Bainbridge794735f2020-02-11 21:01:37 -0800685 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000686 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400687 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400688
689 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530690 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400691 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000692 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400693 }
694 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400695 // Update onu state as down in onu adapter
696 onuInd := oop.OnuIndication{}
697 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800698 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300699 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800700 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400701 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300702 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800703 "onu-indicator": onuInd,
704 "device-type": onuDevice.Type,
705 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700706 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800707 } else {
708 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 -0700709 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400710 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800711 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700712 /* Discovered ONUs entries need to be cleared , since after OLT
713 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530714 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800715 dh.lockDevice.Unlock()
716
Neha Sharma96b7bf22020-06-15 10:37:32 +0000717 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700718 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530719}
720
721// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530722func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400723 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000724
725 // if the connection is already available, close the previous connection (olt reboot case)
726 if dh.clientCon != nil {
727 if err = dh.clientCon.Close(); err != nil {
728 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
729 } else {
730 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
731 }
732 }
733
734 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000735 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
736 grpc.WithInsecure(),
737 grpc.WithBlock(),
738 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000739 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000740 )),
741 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000742 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000743 )))
744
745 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530746 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530747 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000748 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400749 }
750 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530751}
752
753// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530754func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400755 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530756 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400757 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530758}
759
760// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530761func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530762 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000763 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400764
765 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530766 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
767 if err != nil || device == nil {
768 /*TODO: needs to handle error scenarios */
769 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
770 }
771 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000772 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400773
774 cloned := proto.Clone(device).(*voltha.Device)
775 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
776 cloned.OperStatus = voltha.OperStatus_UNKNOWN
777 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530778 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
779 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 -0400780 }
781
Chaitrashree G S44124192019-08-07 20:21:36 -0400782 // 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 +0530783 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400784 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530785 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400786 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400787 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
788 // all the modules initialized and ready to handle incoming ONUs.
789
Thomas Lee S985938d2020-05-04 11:40:41 +0530790 err = dh.initializeDeviceHandlerModules(ctx)
791 if err != nil {
792 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 -0400793 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400794
795 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800796 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530797 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400798 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800799 }
800 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700801
802 go startHeartbeatCheck(ctx, dh)
803
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400804 return nil
805 }
806
Neha Sharma8f4e4322020-08-06 10:51:53 +0000807 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400808 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400809 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400810 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400811 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400812 dh.populateActivePorts(ctx, ports)
813 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
814 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400815 }
816
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400817 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530818 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 -0400819 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530820
cuilin20187b2a8c32019-03-26 19:52:28 -0700821 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800822 go func() {
823 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400824 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800825 }
826 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000827 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000828
829 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000830 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000831 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700832
833 go startHeartbeatCheck(ctx, dh)
834
cuilin20187b2a8c32019-03-26 19:52:28 -0700835 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530836}
837
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400838func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700839 var err error
840 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400841
842 if err != nil {
843 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
844 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700845 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
846 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700847
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700848 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700849 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700850 var i uint32
851 for i = 0; i < dh.totalPonPorts; i++ {
852 // Instantiate resource manager
853 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 -0700854 return olterrors.ErrResourceManagerInstantiating
855 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400856 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700857 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
858 // the KV store to manage mcast group data. Provide the first instance (0th index)
859 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
860 return olterrors.ErrGroupManagerInstantiating
861 }
862 for i = 0; i < dh.totalPonPorts; i++ {
863 // Instantiate flow manager
864 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
865 return olterrors.ErrFlowManagerInstantiating
866 }
867 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400868 /* TODO: Instantiate Alarm , stats , BW managers */
869 /* Instantiating Event Manager to handle Alarms and KPIs */
870 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
871
872 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000873 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400874
875 return nil
876
877}
878
Neha Sharma96b7bf22020-06-15 10:37:32 +0000879func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400880 var err error
881 var deviceInfo *oop.DeviceInfo
882
Neha Sharma8f4e4322020-08-06 10:51:53 +0000883 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400884
885 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000886 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400887 }
888 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000889 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400890 }
891
Neha Sharma96b7bf22020-06-15 10:37:32 +0000892 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400893 dh.device.Root = true
894 dh.device.Vendor = deviceInfo.Vendor
895 dh.device.Model = deviceInfo.Model
896 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
897 dh.device.HardwareVersion = deviceInfo.HardwareVersion
898 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
899
900 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000901 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400902 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000903 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400904 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000905 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400906 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000907 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400908 dh.device.MacAddress = genmac
909 } else {
910 dh.device.MacAddress = deviceInfo.DeviceId
911 }
912
913 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000914 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000915 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400916 }
917
918 return deviceInfo, nil
919}
920
Neha Sharma96b7bf22020-06-15 10:37:32 +0000921func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700922 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530923 for {
924 select {
925 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000926 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530927 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000928 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700929
Neha Sharma8f4e4322020-08-06 10:51:53 +0000930 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400931 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700932 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400933 continue
934 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530935 for _, port := range ports {
936 // NNI Stats
937 if port.Type == voltha.Port_ETHERNET_NNI {
938 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
939 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000940 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000941 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000942 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530943 }
944 // PON Stats
945 if port.Type == voltha.Port_PON_OLT {
946 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
947 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
948 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000949 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000950 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530951 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000952 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000953
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700954 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700955 if len(onuGemInfoLst) > 0 {
956 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000957 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500958 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530959 }
960 }
961 }
962}
963
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700964//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530965func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400966 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000967 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530968 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530969
970 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400971 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
972 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530973 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530974}
975
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700976//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530977func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700978 return &ic.SwitchCapability{
979 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530980 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700981 HwDesc: "open_pon",
982 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700983 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700984 },
985 SwitchFeatures: &of.OfpSwitchFeatures{
986 NBuffers: 256,
987 NTables: 2,
988 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
989 of.OfpCapabilities_OFPC_TABLE_STATS |
990 of.OfpCapabilities_OFPC_PORT_STATS |
991 of.OfpCapabilities_OFPC_GROUP_STATS),
992 },
993 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530994}
995
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700996// GetInterAdapterTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
997func (dh *DeviceHandler) GetInterAdapterTechProfileDownloadMessage(ctx context.Context, tpPath string, ponPortNum uint32, onuID uint32, uniID uint32) *ic.InterAdapterTechProfileDownloadMessage {
998 ifID, err := IntfIDFromPonPortNum(ctx, ponPortNum)
999 if err != nil {
1000 return nil
1001 }
1002 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, tpPath, ifID, onuID, uniID)
1003}
1004
Neha Sharma96b7bf22020-06-15 10:37:32 +00001005func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
1006 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 -07001007 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001008 var deviceID string
1009 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -07001010
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001011 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001012 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001013 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 -07001014 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1015 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001016
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001017 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301018
1019 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1020
Neha Sharma96b7bf22020-06-15 10:37:32 +00001021 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 -07001022 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001023 kwargs := make(map[string]interface{})
1024 kwargs["onu_id"] = omciInd.OnuId
1025 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -07001026
Neha Sharma8f4e4322020-08-06 10:51:53 +00001027 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001028 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301029 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001030 "intf-id": omciInd.IntfId,
1031 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001032 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001033 deviceType = onuDevice.Type
1034 deviceID = onuDevice.Id
1035 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1036 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301037 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001038 } else {
1039 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001040 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 +05301041 deviceType = onuInCache.(*OnuDevice).deviceType
1042 deviceID = onuInCache.(*OnuDevice).deviceID
1043 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001044 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001045
1046 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001047 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001048 ic.InterAdapterMessageType_OMCI_REQUEST, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001049 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301050 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001051 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001052 "destination": deviceType,
1053 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001054 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001055 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001056 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301057}
1058
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001059//ProcessInterAdapterMessage sends the proxied messages to the target device
1060// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1061// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001062func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1063 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001064 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001065 return dh.handleInterAdapterOmciMsg(ctx, msg)
1066 }
1067 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1068}
cuilin20187b2a8c32019-03-26 19:52:28 -07001069
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001070func (dh *DeviceHandler) handleInterAdapterOmciMsg(ctx context.Context, msg *ic.InterAdapterMessage) error {
1071 msgID := msg.Header.Id
1072 fromTopic := msg.Header.FromTopic
1073 toTopic := msg.Header.ToTopic
1074 toDeviceID := msg.Header.ToDeviceId
1075 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001076
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001077 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 -07001078
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001079 msgBody := msg.GetBody()
1080
1081 omciMsg := &ic.InterAdapterOmciMessage{}
1082 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
1083 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
1084 }
1085
1086 if omciMsg.GetProxyAddress() == nil {
1087 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
1088 if err != nil {
1089 return olterrors.NewErrNotFound("onu", log.Fields{
1090 "device-id": dh.device.Id,
1091 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001092 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001093 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1094 if err := dh.sendProxiedMessage(ctx, onuDevice, omciMsg); err != nil {
1095 return olterrors.NewErrCommunication("send-failed", log.Fields{
1096 "device-id": dh.device.Id,
1097 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001098 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001099 } else {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001100 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
1101 if err := dh.sendProxiedMessage(ctx, nil, omciMsg); err != nil {
1102 return olterrors.NewErrCommunication("send-failed", log.Fields{
1103 "device-id": dh.device.Id,
1104 "onu-device-id": toDeviceID}, err)
1105 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001106 }
1107 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301108}
1109
Neha Sharma96b7bf22020-06-15 10:37:32 +00001110func (dh *DeviceHandler) sendProxiedMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001111 var intfID uint32
1112 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001113 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001114 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001115 intfID = onuDevice.ProxyAddress.GetChannelId()
1116 onuID = onuDevice.ProxyAddress.GetOnuId()
1117 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001118 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001119 intfID = omciMsg.GetProxyAddress().GetChannelId()
1120 onuID = omciMsg.GetProxyAddress().GetOnuId()
1121 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001122 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001123 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001124 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 -08001125
Thomas Lee S94109f12020-03-03 16:39:29 +05301126 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001127 "intf-id": intfID,
1128 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001129 }
1130
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001131 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1132 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001133 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001134 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1135 hex.Encode(hexPkt, omciMsg.Message)
1136 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1137
1138 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1139 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1140 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001141 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001142 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001143
Neha Sharma8f4e4322020-08-06 10:51:53 +00001144 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001145 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301146 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001147 "intf-id": intfID,
1148 "onu-id": onuID,
1149 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001150 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001151 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001152}
1153
David K. Bainbridge794735f2020-02-11 21:01:37 -08001154func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301155 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra37f13fa2021-08-16 10:59:45 -07001156 if err := dh.flowMgr[intfID].AddOnuInfoToFlowMgrCacheAndKvStore(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001157 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001158 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001159 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301160 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301161 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001162 st, _ := status.FromError(err)
1163 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001164 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1165
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001166 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301167 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001168 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001169 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001170 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001171 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001172 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001173}
1174
Mahir Gunyelb0046752021-02-26 13:51:05 -08001175func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001176 channelID := onuDiscInd.GetIntfId()
1177 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001178
Mahir Gunyelb0046752021-02-26 13:51:05 -08001179 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001180 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301181
cuilin20187b2a8c32019-03-26 19:52:28 -07001182 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001183 if sn != "" {
1184 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001185 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001186 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001187 }
1188
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301189 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001190 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001191 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301192
1193 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1194 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1195 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1196 OnuLosRaise event sent for it */
1197 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1198 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1199 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001200 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301201 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1202 "currentIntfId": onuDiscInd.GetIntfId()})
1203 // TODO:: Should we need to ignore raising OnuLosClear event
1204 // when onu connected to different PON?
1205 }
1206 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1207 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1208 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001209 go func() {
1210 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001211 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001212 }
1213 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301214 }
1215 return true
1216 })
1217
Neha Sharma96b7bf22020-06-15 10:37:32 +00001218 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001219 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001220 }
1221
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001222 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001223
1224 // check the ONU is already know to the OLT
1225 // NOTE the second time the ONU is discovered this should return a device
1226 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1227
1228 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001229 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 -08001230 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001231 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 -08001232 switch e.Code() {
1233 case codes.Internal:
1234 // this probably means NOT FOUND, so just create a new device
1235 onuDevice = nil
1236 case codes.DeadlineExceeded:
1237 // if the call times out, cleanup and exit
1238 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001239 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001240 }
1241 }
1242 }
1243
1244 if onuDevice == nil {
1245 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001246 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001247 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001248 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001249 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001250
Neha Sharma96b7bf22020-06-15 10:37:32 +00001251 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001252
1253 if err != nil {
1254 // if we can't create an ID in resource manager,
1255 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001256 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001257 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001258 "pon-intf-id": ponintfid,
1259 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001260 }
1261
Neha Sharma8f4e4322020-08-06 10:51:53 +00001262 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001263 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001264 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001265 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 +05301266 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001267 "pon-intf-id": ponintfid,
1268 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001269 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001270 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 -07001271 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001272 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001273 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301274 log.Fields{"onuDevice": onuDevice,
1275 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001276 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301277 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001278 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001279
1280 // we can now use the existing ONU Id
1281 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001282 //Insert the ONU into cache to use in OnuIndication.
1283 //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 +00001284 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001285 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301286 "intfId": onuDiscInd.GetIntfId(),
1287 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001288 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001289
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301290 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301291 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001292 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301293 log.Fields{"onu": onuDev,
1294 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001295
Kent Hagermane6ff1012020-07-14 15:07:53 -04001296 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301297 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001298 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001299 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001300 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001301 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001302 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301303 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001304 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001305 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001306 }
1307 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001308}
1309
Mahir Gunyelb0046752021-02-26 13:51:05 -08001310func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001311
1312 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001313 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001314 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001315 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001316 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001317 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301318 log.Fields{"onuId": onuInd.OnuId,
1319 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301320 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001321 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001322 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301323
David K. Bainbridge794735f2020-02-11 21:01:37 -08001324 errFields := log.Fields{"device-id": dh.device.Id}
1325
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301326 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1327
Mahir Gunyele77977b2019-06-27 05:36:22 -07001328 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1329 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001330 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001331 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001332 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001333 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1334 if serialNumber != "" {
1335 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001336 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001337 } else {
1338 kwargs["onu_id"] = onuInd.OnuId
1339 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001340 errFields["onu-id"] = onuInd.OnuId
1341 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001342 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001343 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001344 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001345
David K. Bainbridge794735f2020-02-11 21:01:37 -08001346 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001347 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001348 }
1349
David K. Bainbridge794735f2020-02-11 21:01:37 -08001350 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001351 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001352 "previousIntfId": onuDevice.ParentPortNo,
1353 "currentIntfId": ponPort})
1354 }
1355
1356 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001357 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301358 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1359 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301360 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001361 }
1362 if !foundInCache {
1363 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1364
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301365 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 -08001366
1367 }
kesavand7cf3a052020-08-28 12:49:18 +05301368 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001369 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001370 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301371 }
1372 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001373 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001374 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001375 }
1376 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001377}
1378
Neha Sharma96b7bf22020-06-15 10:37:32 +00001379func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001380 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 -07001381 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1382 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1383 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1384 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001385 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001386 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1387 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001388 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001389 onuInd.OperState = "down"
1390 }
1391 }
1392
David K. Bainbridge794735f2020-02-11 21:01:37 -08001393 switch onuInd.OperState {
1394 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001395 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 -07001396 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301397 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001398 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001399 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301400 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001401 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001402 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001403 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001404 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001405 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001406 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001407 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 -04001408 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301409 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001410 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001411 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301412 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001413 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001414 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001415 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001416 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001417 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001418 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001419 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001420 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001421 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001422}
1423
cuilin20187b2a8c32019-03-26 19:52:28 -07001424func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1425 if serialNum != nil {
1426 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001427 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001428 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001429}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001430func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1431 decodedStr, err := hex.DecodeString(serialNum[4:])
1432 if err != nil {
1433 return nil, err
1434 }
1435 return &oop.SerialNumber{
1436 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001437 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001438 }, nil
1439}
cuilin20187b2a8c32019-03-26 19:52:28 -07001440
1441func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001442 if len(vendorSpecific) > 3 {
1443 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1444 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1445 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1446 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1447 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1448 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1449 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1450 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1451 return tmp
1452 }
1453 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001454}
1455
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001456//UpdateFlowsBulk upates the bulk flow
1457func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301458 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001459}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001460
1461//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001462func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1463 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301464 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001465 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301466 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001467 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001468 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001469 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001470 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001471 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001472 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001473 "intf-id": parentPort,
1474 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001475 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001476 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 -08001477 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301478}
1479
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001480// SendPacketInToCore sends packet-in to core
1481// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1482// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001483func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001484 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001485 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001486 "port": logicalPort,
1487 "packet": hex.EncodeToString(packetPayload),
1488 "device-id": dh.device.Id,
1489 })
1490 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001491 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 +05301492 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001493 "source": "adapter",
1494 "destination": "core",
1495 "device-id": dh.device.Id,
1496 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001497 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001498 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001499 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001500 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001501 "packet": hex.EncodeToString(packetPayload),
1502 "device-id": dh.device.Id,
1503 })
1504 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001505 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001506}
1507
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001508// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001509func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001510 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001511
1512 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1513 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001514 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001515 }
1516
Kent Hagermane6ff1012020-07-14 15:07:53 -04001517 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001518 metrics := dh.metrics.GetSubscriberMetrics()
1519 for _, m := range pmConfigs.Metrics {
1520 metrics[m.Name].Enabled = m.Enabled
1521
1522 }
1523 }
1524}
1525
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001526//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301527func (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 +00001528 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 +01001529
Girish Gowdra491a9c62021-01-06 16:43:07 -08001530 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001531 var errorsList []error
1532
Girish Gowdru0c588b22019-04-23 23:24:56 -04001533 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001534 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001535 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001536
Neha Sharma96b7bf22020-06-15 10:37:32 +00001537 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301538 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001539 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301540 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001541 if flow_utils.HasGroup(flow) {
1542 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1543 } else {
1544 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1545 }
Girish Gowdracefae192020-03-19 18:14:10 -07001546 if err != nil {
1547 errorsList = append(errorsList, err)
1548 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001549 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301550
1551 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001552 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001553 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301554 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001555 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301556 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001557 if flow_utils.HasGroup(flow) {
1558 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1559 } else {
1560 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1561 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001562 if err != nil {
1563 errorsList = append(errorsList, err)
1564 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301565 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001566 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001567
Girish Gowdracefae192020-03-19 18:14:10 -07001568 // 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 +00001569 if groups != nil {
1570 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001571 // err = dh.groupMgr.AddGroup(ctx, group)
1572 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001573 if err != nil {
1574 errorsList = append(errorsList, err)
1575 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001576 }
1577 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001578 // err = dh.groupMgr.ModifyGroup(ctx, group)
1579 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
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 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001584 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001585 // err = dh.groupMgr.DeleteGroup(ctx, group)
1586 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001587 if err != nil {
1588 errorsList = append(errorsList, err)
1589 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001590 }
1591 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001592 if len(errorsList) > 0 {
1593 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1594 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001595 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001596 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301597}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001598
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001599//DisableDevice disables the given device
1600//It marks the following for the given device:
1601//Device-Handler Admin-State : down
1602//Device Port-State: UNKNOWN
1603//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001604func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001605 /* On device disable ,admin state update has to be done prior sending request to agent since
1606 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001607 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001608 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001609 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001610 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001611 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001612 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001613 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001614 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001615 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001616 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301617
1618 dh.discOnus = sync.Map{}
1619 dh.onus = sync.Map{}
1620
Thomas Lee S85f37312020-04-03 17:06:12 +05301621 //stopping the stats collector
1622 dh.stopCollector <- true
1623
Neha Sharma96b7bf22020-06-15 10:37:32 +00001624 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001625 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301626 //Update device Admin state
1627 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001628 // 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 +00001629 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 -04001630 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001631 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001632 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001633 return nil
1634}
1635
Neha Sharma96b7bf22020-06-15 10:37:32 +00001636func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001637 // Update onu state as unreachable in onu adapter
1638 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301639 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001640 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001641 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001642 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001643 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 -04001644 }
1645 if onuDevices != nil {
1646 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001647 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001648 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001649 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001650 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001651 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001652 }
1653
1654 }
1655 }
1656
1657}
1658
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001659//ReenableDevice re-enables the olt device after disable
1660//It marks the following for the given device:
1661//Device-Handler Admin-State : up
1662//Device Port-State: ACTIVE
1663//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001664func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001665 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301666 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001667 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301668 }
1669 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001670 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001671
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001672 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001673
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001674 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1675 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001676 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001677 }
1678 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001679 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001680 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001681 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001682 device.OperStatus = voltha.OperStatus_ACTIVE
1683 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001684
Neha Sharma8f4e4322020-08-06 10:51:53 +00001685 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 +05301686 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001687 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001688 "connect-status": device.ConnectStatus,
1689 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001690 }
kesavand39e0aa32020-01-28 20:58:50 -05001691
Neha Sharma96b7bf22020-06-15 10:37:32 +00001692 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001693
1694 return nil
1695}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001696
npujarec5762e2020-01-01 14:08:48 +05301697func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001698 var uniID uint32
1699 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301700 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001701 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001702 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001703 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001704 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001705 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001706 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001707 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001708 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001709 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001710 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001711 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001712 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001713 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001714 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001715 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001716 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001717 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301718 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001719 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1720 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001721 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301722 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001723 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001724 if err = dh.resourceMgr[onu.IntfID].DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001725 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 +00001726 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001727 }
1728 return nil
1729}
1730
Devmalya Paul495b94a2019-08-27 19:42:00 -04001731// 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 +05301732func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001733 logger.Debugw(ctx, "function-entry-delete-device", log.Fields{"device-id": dh.device.Id})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001734 /* Clear the KV store data associated with the all the UNI ports
1735 This clears up flow data and also resource map data for various
1736 other pon resources like alloc_id and gemport_id
1737 */
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001738 dh.cleanupDeviceResources(ctx)
1739 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 -04001740 // Stop the Stats collector
1741 dh.stopCollector <- true
1742 // stop the heartbeat check routine
1743 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301744 dh.lockDevice.RLock()
1745 // Stop the read indication only if it the routine is active
1746 if dh.isReadIndicationRoutineActive {
1747 dh.stopIndications <- true
1748 }
1749 dh.lockDevice.RUnlock()
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001750 dh.removeOnuIndicationChannels(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001751 //Reset the state
1752 if dh.Client != nil {
1753 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301754 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001755 }
1756 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001757 // There is no need to update the core about operation status and connection status of the OLT.
1758 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1759 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1760 // because the device does not exist in DB.
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001761
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001762 return nil
1763}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001764func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001765
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001766 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301767 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001768 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001769 var err error
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001770 onuGemData := dh.flowMgr[ponPort].getOnuGemInfoList(ctx)
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001771 for i, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301772 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001773 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001774 if err = dh.clearUNIData(ctx, &onuGemData[i]); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001775 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301776 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301777 // Clear flowids for gem cache.
1778 for _, gem := range onu.GemPorts {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001779 dh.resourceMgr[ponPort].DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301780 }
1781 onuID[0] = onu.OnuID
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001782 dh.resourceMgr[ponPort].FreeonuID(ctx, ponPort, onuID)
1783 err = dh.resourceMgr[ponPort].DelOnuGemInfo(ctx, ponPort, onu.OnuID)
1784 if err != nil {
1785 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
1786 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301787 }
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001788 if err := dh.resourceMgr[ponPort].Delete(ctx, ponPort); err != nil {
1789 logger.Debug(ctx, err)
1790 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001791 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001792 }
A R Karthick1f85b802019-10-11 05:06:05 +00001793
Devmalya Paul495b94a2019-08-27 19:42:00 -04001794 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301795 dh.onus.Range(func(key interface{}, value interface{}) bool {
1796 dh.onus.Delete(key)
1797 return true
1798 })
1799
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001800 /*Delete discovered ONU map for the device*/
1801 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1802 dh.discOnus.Delete(key)
1803 return true
1804 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001805}
1806
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001807//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001808func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001809 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301810 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001811 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001812 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001813 return nil
1814}
1815
David K. Bainbridge794735f2020-02-11 21:01:37 -08001816func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001817 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001818 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001819 "packet-indication": *packetIn,
1820 "device-id": dh.device.Id,
1821 "packet": hex.EncodeToString(packetIn.Pkt),
1822 })
1823 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001824 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001825 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001826 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001827 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001828 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001829 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001830 "logical-port-num": logicalPortNum,
1831 "device-id": dh.device.Id,
1832 "packet": hex.EncodeToString(packetIn.Pkt),
1833 })
1834 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001835
Neha Sharma8f4e4322020-08-06 10:51:53 +00001836 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 +05301837 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001838 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301839 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001840 "device-id": dh.device.Id,
1841 "packet": hex.EncodeToString(packetIn.Pkt),
1842 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001843 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001844
Matteo Scandolo92186242020-06-12 10:54:18 -07001845 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001846 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001847 "packet": hex.EncodeToString(packetIn.Pkt),
1848 "device-id": dh.device.Id,
1849 })
1850 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001851 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001852}
1853
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001854// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301855func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001856 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001857 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001858 "device-id": dh.device.Id,
1859 "egress-port-no": egressPortNo,
1860 "pkt-length": len(packet.Data),
1861 "packet": hex.EncodeToString(packet.Data),
1862 })
1863 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001864
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001865 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001866 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001867 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1868 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301869 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1870 // Do not packet-out lldp packets on uni port.
1871 // ONOS has no clue about uni/nni ports, it just packets out on all
1872 // available ports on the Logical Switch. It should not be interested
1873 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001874 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001875 "device-id": dh.device.Id,
1876 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301877 return nil
1878 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001879 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1880 if innerEthType == 0x8100 {
1881 // q-in-q 802.1ad or 802.1q double tagged packet.
1882 // slice out the outer tag.
1883 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001884 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001885 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001886 "packet-data": hex.EncodeToString(packet.Data),
1887 "device-id": dh.device.Id,
1888 })
1889 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001890 }
1891 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001892 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1893 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001894 uniID := UniIDFromPortNum(uint32(egressPortNo))
1895
Girish Gowdra9602eb42020-09-09 15:50:39 -07001896 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001897 if err != nil {
1898 // In this case the openolt agent will receive the gemPortID as 0.
1899 // The agent tries to retrieve the gemPortID in this case.
1900 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001901 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001902 "intf-id": intfID,
1903 "onu-id": onuID,
1904 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001905 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301906 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001907 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001908 }
1909
1910 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001911 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001912 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001913 "egress-port-no": egressPortNo,
1914 "intf-id": intfID,
1915 "onu-id": onuID,
1916 "uni-id": uniID,
1917 "gem-port-id": gemPortID,
1918 "packet": hex.EncodeToString(packet.Data),
1919 "device-id": dh.device.Id,
1920 })
1921 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001922
npujarec5762e2020-01-01 14:08:48 +05301923 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301924 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001925 "source": "adapter",
1926 "destination": "onu",
1927 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001928 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001929 "oni-id": onuID,
1930 "uni-id": uniID,
1931 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001932 "packet": hex.EncodeToString(packet.Data),
1933 "device-id": dh.device.Id,
1934 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001935 }
1936 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001937 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001938 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001939 return olterrors.NewErrInvalidValue(log.Fields{
1940 "egress-nni-port": egressPortNo,
1941 "device-id": dh.device.Id,
1942 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001943 }
1944 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001945
Matteo Scandolo92186242020-06-12 10:54:18 -07001946 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001947 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001948 "uplink-pkt": uplinkPkt,
1949 "packet": hex.EncodeToString(packet.Data),
1950 "device-id": dh.device.Id,
1951 })
1952 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001953
npujarec5762e2020-01-01 14:08:48 +05301954 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001955 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1956 "packet": hex.EncodeToString(packet.Data),
1957 "device-id": dh.device.Id,
1958 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001959 }
1960 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001961 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301962 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001963 "egressPortType": egressPortType,
1964 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301965 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001966 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001967 }
1968 return nil
1969}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001970
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001971func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1972 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001973}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301974
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001975func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001976
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301977 // start the heartbeat check towards the OLT.
1978 var timerCheck *time.Timer
1979
1980 for {
1981 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1982 select {
1983 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001984 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001985 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001986 logger.Warnw(ctx, "heartbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301987 if timerCheck == nil {
1988 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001989 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301990 }
1991 } else {
1992 if timerCheck != nil {
1993 if timerCheck.Stop() {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001994 logger.Debugw(ctx, "got-heartbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301995 }
1996 timerCheck = nil
1997 }
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001998 logger.Debugw(ctx, "heartbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301999 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05302000 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302001 }
2002 cancel()
2003 case <-dh.stopHeartbeatCheck:
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002004 logger.Debugw(ctx, "stopping-heartbeat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302005 return
2006 }
2007 }
2008}
2009
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002010func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
2011 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
2012 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002013 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2014 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2015 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2016 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2017 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002018 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002019 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2020 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002021 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302022
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002023 logger.Debugw(ctx, "update-state-unreachable", log.Fields{"device-id": dh.device.Id, "connect-status": device.ConnectStatus,
2024 "admin-state": device.AdminState, "oper-status": device.OperStatus})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002025 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
2026 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002027 _ = 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 -04002028 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002029 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002030 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002031 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002032
2033 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002034 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +00002035 device.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2036 device.OperStatus = voltha.OperStatus_UNKNOWN
2037 go dh.eventMgr.oltCommunicationEvent(ctx, device, raisedTs)
2038
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07002039 dh.cleanupDeviceResources(ctx)
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002040 // Stop the Stats collector
2041 dh.stopCollector <- true
2042 // stop the heartbeat check routine
2043 dh.stopHeartbeatCheck <- true
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002044
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002045 dh.lockDevice.RLock()
2046 // Stop the read indication only if it the routine is active
2047 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2048 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2049 // on next execution of the readIndication routine.
2050 if dh.isReadIndicationRoutineActive {
2051 dh.stopIndications <- true
2052 }
2053 dh.lockDevice.RUnlock()
2054
Gamze Abakac2c32a62021-03-11 11:44:18 +00002055 //reset adapter reconcile flag
2056 dh.adapterPreviouslyConnected = false
2057
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002058 dh.transitionMap.Handle(ctx, DeviceInit)
2059
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302060 }
2061}
kesavand39e0aa32020-01-28 20:58:50 -05002062
2063// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002064func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2065 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2066 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002067}
2068
2069// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002070func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2071 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2072 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002073}
2074
kdarapu1afeceb2020-02-12 01:38:09 -05002075//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 +00002076func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2077 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002078 if port.GetType() == voltha.Port_ETHERNET_NNI {
2079 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002080 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302081 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302082 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002083 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002084 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002085 }
2086 // fetch interfaceid from PortNo
2087 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2088 ponIntf := &oop.Interface{IntfId: ponID}
2089 var operStatus voltha.OperStatus_Types
2090 if enablePort {
2091 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302092 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002093
2094 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302095 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002096 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002097 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002098 }
2099 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002100 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002101 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002102 } else {
2103 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302104 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002105 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302106 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002107 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002108 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002109 }
2110 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002111 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002112 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002113 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302114 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 +05302115 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302116 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002117 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002118 }
2119 return nil
2120}
2121
kdarapu1afeceb2020-02-12 01:38:09 -05002122//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002123func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002124 // Disable the port and update the oper_port_status to core
2125 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002126 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002127 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002128 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302129 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302130 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002131 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002132 }
2133 }
2134 }
2135 return nil
2136}
2137
2138//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002139func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2140 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2141 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002142 if port.Type == voltha.Port_ETHERNET_NNI {
2143 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002144 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002145 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002146 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002147 }
2148 }
2149 if port.Type == voltha.Port_PON_OLT {
2150 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002151 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002152 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002153 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002154 }
2155 }
2156 }
2157}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002158
2159// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002160func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002161 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002162 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2163 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002164
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002165 var sn *oop.SerialNumber
2166 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002167 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302168 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002169 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302170 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002171 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002172 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002173
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002174 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002175 //clear PON resources associated with ONU
2176 onuGem, err := dh.resourceMgr[intfID].GetOnuGemInfo(ctx, intfID, onuID)
2177 if err != nil || onuGem == nil || onuGem.OnuID != onuID {
2178 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
2179 "device-id": dh.device.Id,
2180 "intf-id": intfID,
2181 "onuID": onuID,
2182 "err": err})
2183 } else {
2184 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
2185 if err := dh.clearUNIData(ctx, onuGem); err != nil {
2186 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
2187 "device-id": dh.device.Id,
2188 "onu-device": onu,
2189 "err": err})
2190 }
2191 // Clear flowids for gem cache.
2192 for _, gem := range onuGem.GemPorts {
2193 dh.resourceMgr[intfID].DeleteFlowIDsForGem(ctx, intfID, gem)
2194 }
Girish Gowdra37f13fa2021-08-16 10:59:45 -07002195 if err := dh.flowMgr[intfID].RemoveOnuInfoFromFlowMgrCacheAndKvStore(ctx, intfID, onuID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002196 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
2197 "intf-id": intfID,
2198 "onu-device": onu,
2199 "onu-gem": onuGem,
2200 "err": err})
2201 //Not returning error on cleanup.
2202 }
2203 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGem})
2204 dh.resourceMgr[intfID].FreeonuID(ctx, intfID, []uint32{onuGem.OnuID})
2205 }
2206 dh.onus.Delete(onuKey)
2207 dh.discOnus.Delete(onuSn)
2208
2209 // Now clear the ONU on the OLT
Neha Sharma8f4e4322020-08-06 10:51:53 +00002210 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302211 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302212 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002213 "onu-id": onuID}, err).Log()
2214 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002215
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002216 return nil
2217}
Girish Gowdracefae192020-03-19 18:14:10 -07002218
2219func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002220 for _, field := range flow_utils.GetOfbFields(flow) {
2221 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002222 return field.GetPort()
2223 }
2224 }
2225 return InvalidPort
2226}
2227
2228func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002229 for _, action := range flow_utils.GetActions(flow) {
2230 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002231 if out := action.GetOutput(); out != nil {
2232 return out.GetPort()
2233 }
2234 }
2235 }
2236 return InvalidPort
2237}
2238
Girish Gowdracefae192020-03-19 18:14:10 -07002239func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2240 inPort := getInPortFromFlow(flow)
2241 outPort := getOutPortFromFlow(flow)
2242
2243 if inPort == InvalidPort || outPort == InvalidPort {
2244 return inPort, outPort
2245 }
2246
2247 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2248 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2249 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002250 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002251 return uniPort, outPort
2252 }
2253 }
2254 } else {
2255 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2256 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002257 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002258 return inPort, uniPort
2259 }
2260 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2261 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002262 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002263 return uniPort, outPort
2264 }
2265 }
2266 }
2267
2268 return InvalidPort, InvalidPort
2269}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002270
2271func extractOmciTransactionID(omciPkt []byte) uint16 {
2272 if len(omciPkt) > 3 {
2273 d := omciPkt[0:2]
2274 transid := binary.BigEndian.Uint16(d)
2275 return transid
2276 }
2277 return 0
2278}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002279
2280// StoreOnuDevice stores the onu parameters to the local cache.
2281func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2282 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2283 dh.onus.Store(onuKey, onuDevice)
2284}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002285
Neha Sharma8f4e4322020-08-06 10:51:53 +00002286func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002287 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002288 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002289 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002290 resp := new(voltha.ReturnValues)
2291 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002292 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002293 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002294 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2295 return nil, err
2296 }
2297 ID = device.ProxyAddress.GetOnuId()
2298 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2299 valueparam.Onu = &Onu
2300 valueparam.Value = value
2301
2302 // This API is unsupported until agent patch is added
2303 resp.Unsupported = uint32(value)
2304 _ = ctx
2305
2306 // Uncomment this code once agent changes are complete and tests
2307 /*
2308 resp, err = dh.Client.GetValue(ctx, valueparam)
2309 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002310 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "err": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002311 return nil, err
2312 }
2313 */
2314
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002315 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 -08002316 return resp, nil
2317}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002318
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002319func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002320 // Default to PON0
2321 var intfID uint32
2322 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002323 if inPort != InvalidPort && outPort != InvalidPort {
2324 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2325 }
2326 return intfID
2327}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002328
Mahir Gunyelb0046752021-02-26 13:51:05 -08002329func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2330 dh.perPonOnuIndicationChannelLock.Lock()
2331 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2332 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002333 return ch.indicationChannel
2334 }
2335 channels := onuIndicationChannels{
2336 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002337 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002338 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002339 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002340 stopChannel: make(chan struct{}),
2341 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002342 dh.perPonOnuIndicationChannel[intfID] = channels
2343 dh.perPonOnuIndicationChannelLock.Unlock()
2344 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002345 return channels.indicationChannel
2346
2347}
2348
Mahir Gunyelb0046752021-02-26 13:51:05 -08002349func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2350 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2351 dh.perPonOnuIndicationChannelLock.Lock()
2352 defer dh.perPonOnuIndicationChannelLock.Unlock()
2353 for _, v := range dh.perPonOnuIndicationChannel {
2354 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002355 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002356 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002357}
2358
Mahir Gunyelb0046752021-02-26 13:51:05 -08002359func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2360 ind := onuIndicationMsg{
2361 ctx: ctx,
2362 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002363 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002364 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002365 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002366 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002367}
2368
Mahir Gunyelb0046752021-02-26 13:51:05 -08002369func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002370 for {
2371 select {
2372 // process one indication per onu, before proceeding to the next one
2373 case onuInd := <-onuChannels.indicationChannel:
2374 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002375 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002376 switch onuInd.indication.Data.(type) {
2377 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002378 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002379 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2380 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002381 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002382 }
2383 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002384 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002385 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2386 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002387 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002388 }
2389 }
2390 case <-onuChannels.stopChannel:
2391 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2392 close(onuChannels.indicationChannel)
2393 return
2394 }
2395 }
2396}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002397
2398// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2399// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2400func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2401 // Step1 : Fill McastFlowOrGroupControlBlock
2402 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2403 // Step3 : Wait on response channel for response
2404 // Step4 : Return error value
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002405 startTime := time.Now()
Girish Gowdra491a9c62021-01-06 16:43:07 -08002406 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2407 errChan := make(chan error)
2408 var groupID uint32
2409 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2410 ctx: ctx,
2411 flowOrGroupAction: action,
2412 flow: flow,
2413 group: group,
2414 errChan: &errChan,
2415 }
2416 if flow != nil {
2417 groupID = flow_utils.GetGroup(flow)
2418 } else if group != nil {
2419 groupID = group.Desc.GroupId
2420 } else {
2421 return errors.New("flow-and-group-both-nil")
2422 }
2423 // Derive the appropriate go routine to handle the request by a simple module operation.
2424 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2425 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2426 // Wait for handler to return error value
2427 err := <-errChan
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002428 logger.Debugw(ctx, "process-flow-or-group--received-resp", log.Fields{"err": err, "totalTimeInSeconds": time.Since(startTime).Milliseconds()})
Girish Gowdra491a9c62021-01-06 16:43:07 -08002429 return err
2430}
2431
2432// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
2433func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock) {
2434 for {
2435 // block on the channel to receive an incoming mcast flow/group
2436 // process the flow completely before proceeding to handle the next flow
2437 mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel
2438 if mcastFlowOrGroupCb.flow != nil {
2439 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2440 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2441 log.Fields{"device-id": dh.device.Id,
2442 "flowToAdd": mcastFlowOrGroupCb.flow})
2443 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2444 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2445 // Pass the return value over the return channel
2446 *mcastFlowOrGroupCb.errChan <- err
2447 } else { // flow remove
2448 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2449 log.Fields{"device-id": dh.device.Id,
2450 "flowToRemove": mcastFlowOrGroupCb.flow})
2451 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2452 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2453 // Pass the return value over the return channel
2454 *mcastFlowOrGroupCb.errChan <- err
2455 }
2456 } else { // mcast group
2457 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2458 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2459 log.Fields{"device-id": dh.device.Id,
2460 "groupToAdd": mcastFlowOrGroupCb.group})
2461 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2462 // Pass the return value over the return channel
2463 *mcastFlowOrGroupCb.errChan <- err
2464 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2465 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2466 log.Fields{"device-id": dh.device.Id,
2467 "groupToModify": mcastFlowOrGroupCb.group})
2468 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2469 // Pass the return value over the return channel
2470 *mcastFlowOrGroupCb.errChan <- err
2471 } else { // group remove
2472 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2473 log.Fields{"device-id": dh.device.Id,
2474 "groupToRemove": mcastFlowOrGroupCb.group})
2475 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2476 // Pass the return value over the return channel
2477 *mcastFlowOrGroupCb.errChan <- err
2478 }
2479 }
2480 }
2481}
kesavand62126212021-01-12 04:56:06 -05002482
2483func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2484
2485 singleValResp := extension.SingleGetValueResponse{
2486 Response: &extension.GetValueResponse{
2487 Response: &extension.GetValueResponse_PortCoutners{
2488 PortCoutners: &extension.GetOltPortCountersResponse{},
2489 },
2490 },
2491 }
2492
2493 errResp := func(status extension.GetValueResponse_Status,
2494 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2495 return &extension.SingleGetValueResponse{
2496 Response: &extension.GetValueResponse{
2497 Status: status,
2498 ErrReason: reason,
2499 },
2500 }
2501 }
2502
2503 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2504 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2505 //send error response
2506 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2507 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2508 }
2509 statIndChn := make(chan bool, 1)
2510 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2511 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2512 //request openOlt agent to send the the port statistics indication
2513
2514 go func() {
2515 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2516 if err != nil {
2517 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2518 }
2519 }()
2520 select {
2521 case <-statIndChn:
2522 //indication received for ports stats
2523 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2524 case <-time.After(oltPortInfoTimeout * time.Second):
2525 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2526 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2527 case <-ctx.Done():
2528 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2529 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2530 }
2531 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2532 //get nni stats
2533 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
2534 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2535 cmnni := dh.portStats.collectNNIMetrics(intfID)
2536 if cmnni == nil {
2537 //TODO define the error reason
2538 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2539 }
2540 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2541 return &singleValResp
2542
2543 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2544 // get pon stats
2545 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
2546 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2547 cmpon := dh.portStats.collectPONMetrics(intfID)
2548 if cmpon == nil {
2549 //TODO define the error reason
2550 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2551 }
2552 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2553 return &singleValResp
2554 }
2555 }
2556 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2557}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +05302558
2559func (dh *DeviceHandler) getOnuPonCounters(ctx context.Context, onuPonInfo *extension.GetOnuCountersRequest) *extension.SingleGetValueResponse {
2560
2561 singleValResp := extension.SingleGetValueResponse{
2562 Response: &extension.GetValueResponse{
2563 Response: &extension.GetValueResponse_OnuPonCounters{
2564 OnuPonCounters: &extension.GetOnuCountersResponse{},
2565 },
2566 },
2567 }
2568
2569 errResp := func(status extension.GetValueResponse_Status,
2570 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2571 return &extension.SingleGetValueResponse{
2572 Response: &extension.GetValueResponse{
2573 Status: status,
2574 ErrReason: reason,
2575 },
2576 }
2577 }
2578 intfID := onuPonInfo.IntfId
2579 onuID := onuPonInfo.OnuId
2580 onuKey := dh.formOnuKey(intfID, onuID)
2581
2582 if _, ok := dh.onus.Load(onuKey); !ok {
2583 logger.Errorw(ctx, "get-onui-pon-counters-request-invalid-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2584 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2585 }
2586 logger.Debugw(ctx, "get-onui-pon-counters-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2587 cmnni := dh.portStats.collectOnDemandOnuStats(ctx, intfID, onuID)
2588 if cmnni == nil {
2589 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2590 }
2591 dh.portStats.updateGetOnuPonCountersResponse(ctx, &singleValResp, cmnni)
2592 return &singleValResp
2593
2594}
Gamze Abaka85e9a142021-05-26 13:41:39 +00002595
2596func (dh *DeviceHandler) getRxPower(ctx context.Context, rxPowerRequest *extension.GetRxPowerRequest) *extension.SingleGetValueResponse {
2597
2598 Onu := oop.Onu{IntfId: rxPowerRequest.IntfId, OnuId: rxPowerRequest.OnuId}
2599 rxPower, err := dh.Client.GetPonRxPower(ctx, &Onu)
2600 if err != nil {
2601 logger.Errorw(ctx, "error-while-getting-rx-power", log.Fields{"Onu": Onu, "err": err})
2602 return generateSingleGetValueErrorResponse(err)
2603 }
2604 return &extension.SingleGetValueResponse{
2605 Response: &extension.GetValueResponse{
2606 Status: extension.GetValueResponse_OK,
2607 Response: &extension.GetValueResponse_RxPower{
2608 RxPower: &extension.GetRxPowerResponse{
2609 IntfId: rxPowerRequest.IntfId,
2610 OnuId: rxPowerRequest.OnuId,
2611 Status: rxPower.Status,
2612 FailReason: rxPower.FailReason.String(),
2613 RxPower: rxPower.RxPowerMeanDbm,
2614 },
2615 },
2616 },
2617 }
2618}
2619
2620func generateSingleGetValueErrorResponse(err error) *extension.SingleGetValueResponse {
2621 errResp := func(status extension.GetValueResponse_Status,
2622 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2623 return &extension.SingleGetValueResponse{
2624 Response: &extension.GetValueResponse{
2625 Status: status,
2626 ErrReason: reason,
2627 },
2628 }
2629 }
2630
2631 if err != nil {
2632 if e, ok := status.FromError(err); ok {
2633 switch e.Code() {
2634 case codes.Internal:
2635 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2636 case codes.DeadlineExceeded:
2637 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2638 case codes.Unimplemented:
2639 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_UNSUPPORTED)
2640 case codes.NotFound:
2641 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2642 }
2643 }
2644 }
2645
2646 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_REASON_UNDEFINED)
2647}