blob: e7e530a29487b60378f42f14b2c123ecc0777c5a [file] [log] [blame]
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
Phaneendra Manda4c62c802019-03-06 21:37:49 +053019
20import (
cuilin20187b2a8c32019-03-26 19:52:28 -070021 "context"
Matt Jeanneretceea2e02020-03-27 14:19:57 -040022 "encoding/binary"
Matt Jeanneret1359c732019-08-01 21:40:02 -040023 "encoding/hex"
Girish Gowdra491a9c62021-01-06 16:43:07 -080024 "errors"
cuilin20187b2a8c32019-03-26 19:52:28 -070025 "fmt"
26 "io"
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -040027 "net"
cuilin20187b2a8c32019-03-26 19:52:28 -070028 "strconv"
29 "strings"
30 "sync"
31 "time"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053032
Matteo Scandolo945e4012019-12-12 14:16:11 -080033 "github.com/cenkalti/backoff/v3"
cuilin20187b2a8c32019-03-26 19:52:28 -070034 "github.com/gogo/protobuf/proto"
35 "github.com/golang/protobuf/ptypes"
Girish Kumar93e91742020-07-27 16:43:19 +000036 grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
37 grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
Girish Gowdra4c3d4602021-07-22 16:33:37 -070038 "github.com/opencord/voltha-lib-go/v6/pkg/adapters/adapterif"
39 "github.com/opencord/voltha-lib-go/v6/pkg/config"
40 "github.com/opencord/voltha-lib-go/v6/pkg/events/eventif"
41 flow_utils "github.com/opencord/voltha-lib-go/v6/pkg/flows"
42 "github.com/opencord/voltha-lib-go/v6/pkg/log"
43 "github.com/opencord/voltha-lib-go/v6/pkg/pmmetrics"
Matteo Scandolodfa7a972020-11-06 13:03:40 -080044
Thomas Lee S94109f12020-03-03 16:39:29 +053045 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Scott Bakerdbd960e2020-02-28 08:57:51 -080046 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070047 "github.com/opencord/voltha-protos/v4/go/common"
kesavand62126212021-01-12 04:56:06 -050048 "github.com/opencord/voltha-protos/v4/go/extension"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070049 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
50 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
51 oop "github.com/opencord/voltha-protos/v4/go/openolt"
52 "github.com/opencord/voltha-protos/v4/go/voltha"
cuilin20187b2a8c32019-03-26 19:52:28 -070053 "google.golang.org/grpc"
Devmalya Paula1efa642020-04-20 01:36:43 -040054 "google.golang.org/grpc/codes"
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -040055 "google.golang.org/grpc/status"
Phaneendra Manda4c62c802019-03-06 21:37:49 +053056)
57
salmansiddiqui7ac62132019-08-22 03:58:50 +000058// Constants for number of retries and for timeout
Manikkaraj kb1d51442019-07-23 10:41:02 -040059const (
Girish Gowdra491a9c62021-01-06 16:43:07 -080060 InvalidPort = 0xffffffff
61 MaxNumOfGroupHandlerChannels = 256
62
63 McastFlowOrGroupAdd = "McastFlowOrGroupAdd"
64 McastFlowOrGroupModify = "McastFlowOrGroupModify"
65 McastFlowOrGroupRemove = "McastFlowOrGroupRemove"
kesavand62126212021-01-12 04:56:06 -050066 oltPortInfoTimeout = 3
Manikkaraj kb1d51442019-07-23 10:41:02 -040067)
68
Phaneendra Manda4c62c802019-03-06 21:37:49 +053069//DeviceHandler will interact with the OLT device.
70type DeviceHandler struct {
Matteo Scandolodfa7a972020-11-06 13:03:40 -080071 cm *config.ConfigManager
cuilin20187b2a8c32019-03-26 19:52:28 -070072 device *voltha.Device
kdarapu381c6902019-07-31 18:23:16 +053073 coreProxy adapterif.CoreProxy
74 AdapterProxy adapterif.AdapterProxy
Himani Chawlacd407802020-12-10 12:08:59 +053075 EventProxy eventif.EventProxy
cuilin20187b2a8c32019-03-26 19:52:28 -070076 openOLT *OpenOLT
cuilin20187b2a8c32019-03-26 19:52:28 -070077 exitChannel chan int
78 lockDevice sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +053079 Client oop.OpenoltClient
cuilin20187b2a8c32019-03-26 19:52:28 -070080 transitionMap *TransitionMap
81 clientCon *grpc.ClientConn
Girish Gowdra9602eb42020-09-09 15:50:39 -070082 flowMgr []*OpenOltFlowMgr
83 groupMgr *OpenOltGroupMgr
Devmalya Paulfb990a52019-07-09 10:01:49 -040084 eventMgr *OpenOltEventMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070085 resourceMgr []*rsrcMgr.OpenOltResourceMgr
86
87 deviceInfo *oop.DeviceInfo
Naga Manjunatha8dc9372019-10-31 23:01:18 +053088
Girish Gowdra3ab6d212020-03-24 17:33:15 -070089 discOnus sync.Map
90 onus sync.Map
91 portStats *OpenOltStatisticsMgr
92 metrics *pmmetrics.PmMetrics
93 stopCollector chan bool
94 stopHeartbeatCheck chan bool
95 activePorts sync.Map
96 stopIndications chan bool
97 isReadIndicationRoutineActive bool
Girish Gowdracefae192020-03-19 18:14:10 -070098
Mahir Gunyelb0046752021-02-26 13:51:05 -080099 totalPonPorts uint32
100 perPonOnuIndicationChannel map[uint32]onuIndicationChannels
101 perPonOnuIndicationChannelLock sync.Mutex
Girish Gowdra491a9c62021-01-06 16:43:07 -0800102
103 // Slice of channels. Each channel in slice, index by (mcast-group-id modulo MaxNumOfGroupHandlerChannels)
104 // A go routine per index, waits on a unique channel for incoming mcast flow or group (add/modify/remove).
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
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400219func macifyIP(ip net.IP) string {
220 if len(ip) > 0 {
221 oct1 := strconv.FormatInt(int64(ip[12]), 16)
222 oct2 := strconv.FormatInt(int64(ip[13]), 16)
223 oct3 := strconv.FormatInt(int64(ip[14]), 16)
224 oct4 := strconv.FormatInt(int64(ip[15]), 16)
225 return fmt.Sprintf("00:00:%02v:%02v:%02v:%02v", oct1, oct2, oct3, oct4)
226 }
227 return ""
228}
229
Neha Sharma96b7bf22020-06-15 10:37:32 +0000230func generateMacFromHost(ctx context.Context, host string) (string, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400231 var genmac string
232 var addr net.IP
233 var ips []string
234 var err error
235
Neha Sharma96b7bf22020-06-15 10:37:32 +0000236 logger.Debugw(ctx, "generating-mac-from-host", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400237
238 if addr = net.ParseIP(host); addr == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000239 logger.Debugw(ctx, "looking-up-hostname", log.Fields{"host": host})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400240
241 if ips, err = net.LookupHost(host); err == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000242 logger.Debugw(ctx, "dns-result-ips", log.Fields{"ips": ips})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400243 if addr = net.ParseIP(ips[0]); addr == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000244 return "", olterrors.NewErrInvalidValue(log.Fields{"ip": ips[0]}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400245 }
246 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000247 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530248 log.Fields{"host": ips[0],
249 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400250 return genmac, nil
251 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000252 return "", olterrors.NewErrAdapter("cannot-resolve-hostname-to-ip", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400253 }
254
255 genmac = macifyIP(addr)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000256 logger.Debugw(ctx, "using-ip-as-mac",
Shrey Baid807a2a02020-04-09 12:52:45 +0530257 log.Fields{"host": host,
258 "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400259 return genmac, nil
260}
261
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530262func macAddressToUint32Array(mac string) []uint32 {
cuilin20187b2a8c32019-03-26 19:52:28 -0700263 slist := strings.Split(mac, ":")
264 result := make([]uint32, len(slist))
265 var err error
266 var tmp int64
267 for index, val := range slist {
268 if tmp, err = strconv.ParseInt(val, 16, 32); err != nil {
269 return []uint32{1, 2, 3, 4, 5, 6}
270 }
271 result[index] = uint32(tmp)
272 }
273 return result
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530274}
275
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700276//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 -0800277func GetportLabel(portNum uint32, portType voltha.Port_PortType) (string, error) {
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530278
David K. Bainbridge794735f2020-02-11 21:01:37 -0800279 switch portType {
280 case voltha.Port_ETHERNET_NNI:
281 return fmt.Sprintf("nni-%d", portNum), nil
282 case voltha.Port_PON_OLT:
283 return fmt.Sprintf("pon-%d", portNum), nil
cuilin20187b2a8c32019-03-26 19:52:28 -0700284 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800285
Girish Kumarf26e4882020-03-05 06:49:10 +0000286 return "", olterrors.NewErrInvalidValue(log.Fields{"port-type": portType}, nil)
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530287}
288
Neha Sharma96b7bf22020-06-15 10:37:32 +0000289func (dh *DeviceHandler) addPort(ctx context.Context, intfID uint32, portType voltha.Port_PortType, state string) error {
Esin Karamanccb714b2019-11-29 15:02:06 +0000290 var operStatus common.OperStatus_Types
cuilin20187b2a8c32019-03-26 19:52:28 -0700291 if state == "up" {
292 operStatus = voltha.OperStatus_ACTIVE
kesavand39e0aa32020-01-28 20:58:50 -0500293 //populating the intfStatus map
Chaitrashree G Sef088112020-02-03 21:39:27 -0500294 dh.activePorts.Store(intfID, true)
cuilin20187b2a8c32019-03-26 19:52:28 -0700295 } else {
296 operStatus = voltha.OperStatus_DISCOVERED
Chaitrashree G Sef088112020-02-03 21:39:27 -0500297 dh.activePorts.Store(intfID, false)
cuilin20187b2a8c32019-03-26 19:52:28 -0700298 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700299 portNum := IntfIDToPortNo(intfID, portType)
Chaitrashree G Sc0878ec2020-05-21 04:59:53 -0400300 label, err := GetportLabel(intfID, portType)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800301 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000302 return olterrors.NewErrNotFound("port-label", log.Fields{"port-number": portNum, "port-type": portType}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400303 }
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500304
Neha Sharma8f4e4322020-08-06 10:51:53 +0000305 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 +0000306 logger.Debug(ctx, "port-already-exists-updating-oper-status-of-port")
Neha Sharma8f4e4322020-08-06 10:51:53 +0000307 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 -0400308 return olterrors.NewErrAdapter("failed-to-update-port-state", log.Fields{
309 "device-id": dh.device.Id,
310 "port-type": portType,
311 "port-number": portNum,
312 "oper-status": operStatus}, err).Log()
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500313 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400314 return nil
Chaitrashree G Sded0a832020-01-09 20:21:48 -0500315 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400316 // Now create Port
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700317 capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400318 port := &voltha.Port{
cuilin20187b2a8c32019-03-26 19:52:28 -0700319 PortNo: portNum,
320 Label: label,
321 Type: portType,
322 OperStatus: operStatus,
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700323 OfpPort: &of.OfpPort{
324 HwAddr: macAddressToUint32Array(dh.device.MacAddress),
325 Config: 0,
326 State: uint32(of.OfpPortState_OFPPS_LIVE),
327 Curr: capacity,
328 Advertised: capacity,
329 Peer: capacity,
330 CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
331 MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
332 },
cuilin20187b2a8c32019-03-26 19:52:28 -0700333 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000334 logger.Debugw(ctx, "sending-port-update-to-core", log.Fields{"port": port})
cuilin20187b2a8c32019-03-26 19:52:28 -0700335 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000336 if err := dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, port); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000337 return olterrors.NewErrAdapter("error-creating-port", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800338 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000339 "port-type": portType}, err)
Girish Gowdru1110ef22019-06-24 11:17:59 -0400340 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000341 go dh.updateLocalDevice(ctx)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530342 return nil
343}
344
Kent Hagermane6ff1012020-07-14 15:07:53 -0400345func (dh *DeviceHandler) updateLocalDevice(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +0000346 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530347 if err != nil || device == nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400348 logger.Errorf(ctx, "device-not-found", log.Fields{"device-id": dh.device.Id}, err)
349 return
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530350 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800351 dh.lockDevice.Lock()
352 defer dh.lockDevice.Unlock()
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530353 dh.device = device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530354}
355
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700356// nolint: gocyclo
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530357// readIndications to read the indications from the OLT device
David K. Bainbridge794735f2020-02-11 21:01:37 -0800358func (dh *DeviceHandler) readIndications(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000359 defer logger.Debugw(ctx, "indications-ended", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700360 defer func() {
361 dh.lockDevice.Lock()
362 dh.isReadIndicationRoutineActive = false
363 dh.lockDevice.Unlock()
364 }()
Girish Gowdra3f974912020-03-23 20:35:18 -0700365 indications, err := dh.startOpenOltIndicationStream(ctx)
cuilin20187b2a8c32019-03-26 19:52:28 -0700366 if err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700367 return err
cuilin20187b2a8c32019-03-26 19:52:28 -0700368 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -0400369
David Bainbridgef5879ca2019-12-13 21:17:54 +0000370 // Create an exponential backoff around re-enabling indications. The
371 // maximum elapsed time for the back off is set to 0 so that we will
372 // continue to retry. The max interval defaults to 1m, but is set
373 // here for code clarity
374 indicationBackoff := backoff.NewExponentialBackOff()
375 indicationBackoff.MaxElapsedTime = 0
376 indicationBackoff.MaxInterval = 1 * time.Minute
Girish Gowdra3f974912020-03-23 20:35:18 -0700377
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700378 dh.lockDevice.Lock()
379 dh.isReadIndicationRoutineActive = true
380 dh.lockDevice.Unlock()
381
Girish Gowdra3f974912020-03-23 20:35:18 -0700382Loop:
cuilin20187b2a8c32019-03-26 19:52:28 -0700383 for {
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400384 select {
385 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000386 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700387 break Loop
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400388 default:
389 indication, err := indications.Recv()
390 if err == io.EOF {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000391 logger.Infow(ctx, "eof-for-indications",
Shrey Baid807a2a02020-04-09 12:52:45 +0530392 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530393 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400394 // Use an exponential back off to prevent getting into a tight loop
395 duration := indicationBackoff.NextBackOff()
396 if duration == backoff.Stop {
397 // If we reach a maximum then warn and reset the backoff
398 // timer and keep attempting.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000399 logger.Warnw(ctx, "maximum-indication-backoff-reached--resetting-backoff-timer",
Shrey Baid807a2a02020-04-09 12:52:45 +0530400 log.Fields{"max-indication-backoff": indicationBackoff.MaxElapsedTime,
Thomas Lee S985938d2020-05-04 11:40:41 +0530401 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400402 indicationBackoff.Reset()
403 }
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700404
405 // On failure process a backoff timer while watching for stopIndications
406 // events
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700407 backoffTimer := time.NewTimer(indicationBackoff.NextBackOff())
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700408 select {
409 case <-dh.stopIndications:
divyadesai3af43e12020-08-18 07:10:54 +0000410 logger.Debugw(ctx, "stopping-collecting-indications-for-olt", log.Fields{"device-id": dh.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700411 if !backoffTimer.Stop() {
412 <-backoffTimer.C
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700413 }
414 break Loop
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700415 case <-backoffTimer.C:
416 // backoffTimer expired continue
David Bainbridge95a3fcf2020-06-09 10:49:31 -0700417 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700418 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
419 return err
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400420 }
421 continue
David Bainbridgef5879ca2019-12-13 21:17:54 +0000422 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530423 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000424 logger.Errorw(ctx, "read-indication-error",
Shrey Baid807a2a02020-04-09 12:52:45 +0530425 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530426 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700427 // Close the stream, and re-initialize it
428 if err = indications.CloseSend(); err != nil {
429 // Ok to ignore here, because we landed here due to a problem on the stream
430 // In all probability, the closeSend call may fail
Neha Sharma96b7bf22020-06-15 10:37:32 +0000431 logger.Debugw(ctx, "error-closing-send stream--error-ignored",
Shrey Baid807a2a02020-04-09 12:52:45 +0530432 log.Fields{"err": err,
Thomas Lee S985938d2020-05-04 11:40:41 +0530433 "device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700434 }
Matteo Scandolof16389e2021-05-18 00:47:08 +0000435 if indications, err = dh.startOpenOltIndicationStream(ctx); err != nil {
Girish Gowdra3f974912020-03-23 20:35:18 -0700436 return err
437 }
438 // once we re-initialized the indication stream, continue to read indications
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400439 continue
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530440 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400441 // Reset backoff if we have a successful receive
442 indicationBackoff.Reset()
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400443 // When OLT is admin down, ignore all indications.
Girish Gowdra852ad912021-05-04 00:05:50 -0700444 if dh.device.AdminState == voltha.AdminState_DISABLED && !isIndicationAllowedDuringOltAdminDown(indication) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000445 logger.Debugw(ctx, "olt-is-admin-down, ignore indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530446 log.Fields{"indication": indication,
Thomas Lee S985938d2020-05-04 11:40:41 +0530447 "device-id": dh.device.Id})
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400448 continue
Devmalya Paul495b94a2019-08-27 19:42:00 -0400449 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400450 dh.handleIndication(ctx, indication)
cuilin20187b2a8c32019-03-26 19:52:28 -0700451 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700452 }
Girish Gowdra3f974912020-03-23 20:35:18 -0700453 // Close the send stream
454 _ = indications.CloseSend() // Ok to ignore error, as we stopping the readIndication anyway
Girish Gowdra3ab6d212020-03-24 17:33:15 -0700455
Girish Gowdra3f974912020-03-23 20:35:18 -0700456 return nil
457}
458
459func (dh *DeviceHandler) startOpenOltIndicationStream(ctx context.Context) (oop.Openolt_EnableIndicationClient, error) {
Girish Gowdra852ad912021-05-04 00:05:50 -0700460 logger.Infow(ctx, "enabling read indications", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700461 indications, err := dh.Client.EnableIndication(ctx, new(oop.Empty))
462 if err != nil {
463 return nil, olterrors.NewErrCommunication("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
464 }
465 if indications == nil {
466 return nil, olterrors.NewErrInvalidValue(log.Fields{"indications": nil, "device-id": dh.device.Id}, nil).Log()
467 }
Girish Gowdra852ad912021-05-04 00:05:50 -0700468 logger.Infow(ctx, "read indication started successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdra3f974912020-03-23 20:35:18 -0700469 return indications, nil
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400470}
471
472// isIndicationAllowedDuringOltAdminDown returns true if the indication is allowed during OLT Admin down, else false
473func isIndicationAllowedDuringOltAdminDown(indication *oop.Indication) bool {
474 switch indication.Data.(type) {
475 case *oop.Indication_OltInd, *oop.Indication_IntfInd, *oop.Indication_IntfOperInd:
476 return true
477
478 default:
479 return false
480 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700481}
482
David K. Bainbridge794735f2020-02-11 21:01:37 -0800483func (dh *DeviceHandler) handleOltIndication(ctx context.Context, oltIndication *oop.OltIndication) error {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700484 raisedTs := time.Now().Unix()
Gamze Abakaa1a50522019-10-03 19:28:27 +0000485 if oltIndication.OperState == "up" && dh.transitionMap.currentDeviceState != deviceStateUp {
npujarec5762e2020-01-01 14:08:48 +0530486 dh.transitionMap.Handle(ctx, DeviceUpInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700487 } else if oltIndication.OperState == "down" {
npujarec5762e2020-01-01 14:08:48 +0530488 dh.transitionMap.Handle(ctx, DeviceDownInd)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700489 }
Daniele Rossi051466a2019-07-26 13:39:37 +0000490 // Send or clear Alarm
Neha Sharma96b7bf22020-06-15 10:37:32 +0000491 if err := dh.eventMgr.oltUpDownIndication(ctx, oltIndication, dh.device.Id, raisedTs); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530492 return olterrors.NewErrAdapter("failed-indication", log.Fields{
divyadesai3af43e12020-08-18 07:10:54 +0000493 "device-id": dh.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800494 "indication": oltIndication,
Girish Kumarf26e4882020-03-05 06:49:10 +0000495 "timestamp": raisedTs}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800496 }
497 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700498}
499
David K. Bainbridge794735f2020-02-11 21:01:37 -0800500// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +0530501func (dh *DeviceHandler) handleIndication(ctx context.Context, indication *oop.Indication) {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700502 raisedTs := time.Now().Unix()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700503 switch indication.Data.(type) {
504 case *oop.Indication_OltInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000505 span, ctx := log.CreateChildSpan(ctx, "olt-indication", log.Fields{"device-id": dh.device.Id})
506 defer span.Finish()
Girish Gowdra852ad912021-05-04 00:05:50 -0700507 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 -0800508 if err := dh.handleOltIndication(ctx, indication.GetOltInd()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400509 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "olt", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800510 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700511 case *oop.Indication_IntfInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000512 span, ctx := log.CreateChildSpan(ctx, "interface-indication", log.Fields{"device-id": dh.device.Id})
513 defer span.Finish()
514
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700515 intfInd := indication.GetIntfInd()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800516 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000517 if err := dh.addPort(ctx, intfInd.GetIntfId(), voltha.Port_PON_OLT, intfInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400518 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "interface", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800519 }
520 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000521 logger.Infow(ctx, "received-interface-indication", log.Fields{"InterfaceInd": intfInd, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700522 case *oop.Indication_IntfOperInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000523 span, ctx := log.CreateChildSpan(ctx, "interface-oper-indication", log.Fields{"device-id": dh.device.Id})
524 defer span.Finish()
525
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700526 intfOperInd := indication.GetIntfOperInd()
527 if intfOperInd.GetType() == "nni" {
David K. Bainbridge794735f2020-02-11 21:01:37 -0800528 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000529 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_ETHERNET_NNI, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400530 _ = 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 -0800531 }
532 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700533 } else if intfOperInd.GetType() == "pon" {
534 // TODO: Check what needs to be handled here for When PON PORT down, ONU will be down
535 // Handle pon port update
David K. Bainbridge794735f2020-02-11 21:01:37 -0800536 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000537 if err := dh.addPort(ctx, intfOperInd.GetIntfId(), voltha.Port_PON_OLT, intfOperInd.GetOperState()); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400538 _ = 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 -0800539 }
540 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000541 go dh.eventMgr.oltIntfOperIndication(ctx, indication.GetIntfOperInd(), dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700542 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000543 logger.Infow(ctx, "received-interface-oper-indication",
Shrey Baid807a2a02020-04-09 12:52:45 +0530544 log.Fields{"interfaceOperInd": intfOperInd,
Thomas Lee S985938d2020-05-04 11:40:41 +0530545 "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700546 case *oop.Indication_OnuDiscInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000547 span, ctx := log.CreateChildSpan(ctx, "onu-discovery-indication", log.Fields{"device-id": dh.device.Id})
548 defer span.Finish()
549
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700550 onuDiscInd := indication.GetOnuDiscInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000551 logger.Infow(ctx, "received-onu-discovery-indication", log.Fields{"OnuDiscInd": onuDiscInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800552 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800553 dh.putOnuIndicationToChannel(ctx, indication, onuDiscInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700554 case *oop.Indication_OnuInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000555 span, ctx := log.CreateChildSpan(ctx, "onu-indication", log.Fields{"device-id": dh.device.Id})
556 defer span.Finish()
557
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700558 onuInd := indication.GetOnuInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000559 logger.Infow(ctx, "received-onu-indication", log.Fields{"OnuInd": onuInd, "device-id": dh.device.Id})
Mahir Gunyel2fb81472020-12-16 23:18:34 -0800560 //put message to channel and return immediately
Mahir Gunyelb0046752021-02-26 13:51:05 -0800561 dh.putOnuIndicationToChannel(ctx, indication, onuInd.GetIntfId())
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700562 case *oop.Indication_OmciInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000563 span, ctx := log.CreateChildSpan(ctx, "omci-indication", log.Fields{"device-id": dh.device.Id})
564 defer span.Finish()
565
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700566 omciInd := indication.GetOmciInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000567 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 -0800568 go func() {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000569 if err := dh.omciIndication(ctx, omciInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400570 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "omci", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800571 }
572 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700573 case *oop.Indication_PktInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000574 span, ctx := log.CreateChildSpan(ctx, "packet-indication", log.Fields{"device-id": dh.device.Id})
575 defer span.Finish()
576
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700577 pktInd := indication.GetPktInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000578 logger.Debugw(ctx, "received-packet-indication", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700579 "intf-type": pktInd.IntfId,
580 "intf-id": pktInd.IntfId,
581 "gem-port-id": pktInd.GemportId,
582 "port-no": pktInd.PortNo,
583 "device-id": dh.device.Id,
584 })
585
586 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000587 logger.Debugw(ctx, "received-packet-indication-packet", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700588 "intf-type": pktInd.IntfId,
589 "intf-id": pktInd.IntfId,
590 "gem-port-id": pktInd.GemportId,
591 "port-no": pktInd.PortNo,
592 "packet": hex.EncodeToString(pktInd.Pkt),
593 "device-id": dh.device.Id,
594 })
595 }
596
David K. Bainbridge794735f2020-02-11 21:01:37 -0800597 go func() {
598 if err := dh.handlePacketIndication(ctx, pktInd); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400599 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{"type": "packet", "device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800600 }
601 }()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700602 case *oop.Indication_PortStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000603 span, ctx := log.CreateChildSpan(ctx, "port-statistics-indication", log.Fields{"device-id": dh.device.Id})
604 defer span.Finish()
605
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700606 portStats := indication.GetPortStats()
Girish Gowdra9602eb42020-09-09 15:50:39 -0700607 go dh.portStats.PortStatisticsIndication(ctx, portStats, dh.totalPonPorts)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700608 case *oop.Indication_FlowStats:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000609 span, ctx := log.CreateChildSpan(ctx, "flow-stats-indication", log.Fields{"device-id": dh.device.Id})
610 defer span.Finish()
611
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700612 flowStats := indication.GetFlowStats()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000613 logger.Infow(ctx, "received-flow-stats", log.Fields{"FlowStats": flowStats, "device-id": dh.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700614 case *oop.Indication_AlarmInd:
Neha Sharma8f4e4322020-08-06 10:51:53 +0000615 span, ctx := log.CreateChildSpan(ctx, "alarm-indication", log.Fields{"device-id": dh.device.Id})
616 defer span.Finish()
617
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700618 alarmInd := indication.GetAlarmInd()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000619 logger.Infow(ctx, "received-alarm-indication", log.Fields{"AlarmInd": alarmInd, "device-id": dh.device.Id})
620 go dh.eventMgr.ProcessEvents(ctx, alarmInd, dh.device.Id, raisedTs)
cuilin20187b2a8c32019-03-26 19:52:28 -0700621 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530622}
623
624// doStateUp handle the olt up indication and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530625func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
Thomas Lee S85f37312020-04-03 17:06:12 +0530626 //starting the stat collector
Neha Sharma96b7bf22020-06-15 10:37:32 +0000627 go startCollector(ctx, dh)
Thomas Lee S85f37312020-04-03 17:06:12 +0530628
Girish Gowdru0c588b22019-04-23 23:24:56 -0400629 // Synchronous call to update device state - this method is run in its own go routine
npujarec5762e2020-01-01 14:08:48 +0530630 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400631 voltha.OperStatus_ACTIVE); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000632 return olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400633 }
Gamze Abaka07868a52020-12-17 14:19:28 +0000634
635 //Clear olt communication failure event
636 dh.device.ConnectStatus = voltha.ConnectStatus_REACHABLE
637 dh.device.OperStatus = voltha.OperStatus_ACTIVE
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -0700638 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +0000639 go dh.eventMgr.oltCommunicationEvent(ctx, dh.device, raisedTs)
640
Gamze Abakac2c32a62021-03-11 11:44:18 +0000641 //check adapter and agent reconcile status
642 //reboot olt if needed (olt disconnection case)
643 if dh.adapterPreviouslyConnected != dh.agentPreviouslyConnected {
644 logger.Warnw(ctx, "different-reconcile-status-between-adapter-and-agent-rebooting-device",
645 log.Fields{
646 "device-id": dh.device.Id,
647 "adapter-status": dh.adapterPreviouslyConnected,
648 "agent-status": dh.agentPreviouslyConnected,
649 })
650 _ = dh.RebootDevice(ctx, dh.device)
651 }
652
Girish Gowdru0c588b22019-04-23 23:24:56 -0400653 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530654}
655
656// doStateDown handle the olt down indication
npujarec5762e2020-01-01 14:08:48 +0530657func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000658 logger.Debugw(ctx, "do-state-down-start", log.Fields{"device-id": dh.device.Id})
Girish Gowdrud4245152019-05-10 00:47:31 -0400659
npujarec5762e2020-01-01 14:08:48 +0530660 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
Girish Gowdrud4245152019-05-10 00:47:31 -0400661 if err != nil || device == nil {
662 /*TODO: needs to handle error scenarios */
Girish Kumarf26e4882020-03-05 06:49:10 +0000663 return olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400664 }
665
666 cloned := proto.Clone(device).(*voltha.Device)
Girish Gowdrud4245152019-05-10 00:47:31 -0400667
668 //Update the device oper state and connection status
669 cloned.OperStatus = voltha.OperStatus_UNKNOWN
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800670 dh.lockDevice.Lock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400671 dh.device = cloned
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800672 dh.lockDevice.Unlock()
Girish Gowdrud4245152019-05-10 00:47:31 -0400673
David K. Bainbridge794735f2020-02-11 21:01:37 -0800674 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000675 return olterrors.NewErrAdapter("state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400676 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400677
678 //get the child device for the parent device
npujarec5762e2020-01-01 14:08:48 +0530679 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400680 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000681 return olterrors.NewErrAdapter("child-device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400682 }
683 for _, onuDevice := range onuDevices.Items {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400684 // Update onu state as down in onu adapter
685 onuInd := oop.OnuIndication{}
686 onuInd.OperState = "down"
David K. Bainbridge794735f2020-02-11 21:01:37 -0800687 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +0300688 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
David K. Bainbridge794735f2020-02-11 21:01:37 -0800689 if err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400690 _ = olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +0300691 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800692 "onu-indicator": onuInd,
693 "device-type": onuDevice.Type,
694 "device-id": onuDevice.Id}, err).LogAt(log.ErrorLevel)
serkant.uluderya245caba2019-09-24 23:15:29 -0700695 //Do not return here and continue to process other ONUs
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800696 } else {
697 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 -0700698 }
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -0400699 }
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800700 dh.lockDevice.Lock()
serkant.uluderya245caba2019-09-24 23:15:29 -0700701 /* Discovered ONUs entries need to be cleared , since after OLT
702 is up, it starts sending discovery indications again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +0530703 dh.discOnus = sync.Map{}
Girish Gowdrabe811ff2021-01-26 17:12:12 -0800704 dh.lockDevice.Unlock()
705
Neha Sharma96b7bf22020-06-15 10:37:32 +0000706 logger.Debugw(ctx, "do-state-down-end", log.Fields{"device-id": device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -0700707 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530708}
709
710// doStateInit dial the grpc before going to init state
npujarec5762e2020-01-01 14:08:48 +0530711func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400712 var err error
Gamze Abaka49c40b32021-05-06 09:30:41 +0000713
714 // if the connection is already available, close the previous connection (olt reboot case)
715 if dh.clientCon != nil {
716 if err = dh.clientCon.Close(); err != nil {
717 logger.Errorw(ctx, "failed-to-close-previous-connection", log.Fields{"device-id": dh.device.Id})
718 } else {
719 logger.Debugw(ctx, "previous-grpc-channel-closed-successfully", log.Fields{"device-id": dh.device.Id})
720 }
721 }
722
723 // Use Interceptors to automatically inject and publish Open Tracing Spans by this GRPC client
Girish Kumar93e91742020-07-27 16:43:19 +0000724 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(),
725 grpc.WithInsecure(),
726 grpc.WithBlock(),
727 grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000728 grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000729 )),
730 grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
Girish Kumar935f7af2020-08-18 11:59:42 +0000731 grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(log.ActiveTracerProxy{})),
Girish Kumar93e91742020-07-27 16:43:19 +0000732 )))
733
734 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530735 return olterrors.NewErrCommunication("dial-failure", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +0530736 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +0000737 "host-and-port": dh.device.GetHostAndPort()}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400738 }
739 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530740}
741
742// postInit create olt client instance to invoke RPC on the olt device
npujarec5762e2020-01-01 14:08:48 +0530743func (dh *DeviceHandler) postInit(ctx context.Context) error {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400744 dh.Client = oop.NewOpenoltClient(dh.clientCon)
npujarec5762e2020-01-01 14:08:48 +0530745 dh.transitionMap.Handle(ctx, GrpcConnected)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400746 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530747}
748
749// doStateConnected get the device info and update to voltha core
npujarec5762e2020-01-01 14:08:48 +0530750func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
Thomas Lee S985938d2020-05-04 11:40:41 +0530751 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000752 logger.Debugw(ctx, "olt-device-connected", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400753
754 // Case where OLT is disabled and then rebooted.
Thomas Lee S985938d2020-05-04 11:40:41 +0530755 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
756 if err != nil || device == nil {
757 /*TODO: needs to handle error scenarios */
758 return olterrors.NewErrAdapter("device-fetch-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
759 }
760 if device.AdminState == voltha.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000761 logger.Debugln(ctx, "do-state-connected--device-admin-state-down")
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400762
763 cloned := proto.Clone(device).(*voltha.Device)
764 cloned.ConnectStatus = voltha.ConnectStatus_REACHABLE
765 cloned.OperStatus = voltha.OperStatus_UNKNOWN
766 dh.device = cloned
Thomas Lee S985938d2020-05-04 11:40:41 +0530767 if err = dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); err != nil {
768 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 -0400769 }
770
Chaitrashree G S44124192019-08-07 20:21:36 -0400771 // 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 +0530772 _, err = dh.Client.DisableOlt(ctx, new(oop.Empty))
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400773 if err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530774 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400775 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400776 // We should still go ahead an initialize various device handler modules so that when OLT is re-enabled, we have
777 // all the modules initialized and ready to handle incoming ONUs.
778
Thomas Lee S985938d2020-05-04 11:40:41 +0530779 err = dh.initializeDeviceHandlerModules(ctx)
780 if err != nil {
781 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 -0400782 }
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400783
784 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800785 go func() {
Thomas Lee S985938d2020-05-04 11:40:41 +0530786 if err = dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400787 _ = olterrors.NewErrAdapter("indication-read-failure", log.Fields{"device-id": dh.device.Id}, err).LogAt(log.ErrorLevel)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800788 }
789 }()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700790
791 go startHeartbeatCheck(ctx, dh)
792
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -0400793 return nil
794 }
795
Neha Sharma8f4e4322020-08-06 10:51:53 +0000796 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400797 if err != nil {
Girish Gowdrud4245152019-05-10 00:47:31 -0400798 /*TODO: needs to handle error scenarios */
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400799 return olterrors.NewErrAdapter("fetch-ports-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400800 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400801 dh.populateActivePorts(ctx, ports)
802 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
803 return olterrors.NewErrAdapter("port-status-update-failed", log.Fields{"ports": ports}, err)
Girish Gowdrud4245152019-05-10 00:47:31 -0400804 }
805
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400806 if err := dh.initializeDeviceHandlerModules(ctx); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +0530807 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 -0400808 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530809
cuilin20187b2a8c32019-03-26 19:52:28 -0700810 // Start reading indications
David K. Bainbridge794735f2020-02-11 21:01:37 -0800811 go func() {
812 if err := dh.readIndications(ctx); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -0400813 _ = olterrors.NewErrAdapter("read-indications-failure", log.Fields{"device-id": dh.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -0800814 }
815 }()
Neha Sharma96b7bf22020-06-15 10:37:32 +0000816 go dh.updateLocalDevice(ctx)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000817
818 if device.PmConfigs != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000819 dh.UpdatePmConfig(ctx, device.PmConfigs)
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000820 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700821
822 go startHeartbeatCheck(ctx, dh)
823
cuilin20187b2a8c32019-03-26 19:52:28 -0700824 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530825}
826
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400827func (dh *DeviceHandler) initializeDeviceHandlerModules(ctx context.Context) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700828 var err error
829 dh.deviceInfo, err = dh.populateDeviceInfo(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400830
831 if err != nil {
832 return olterrors.NewErrAdapter("populate-device-info-failed", log.Fields{"device-id": dh.device.Id}, err)
833 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700834 dh.totalPonPorts = dh.deviceInfo.GetPonPorts()
835 dh.agentPreviouslyConnected = dh.deviceInfo.PreviouslyConnected
Girish Gowdra9602eb42020-09-09 15:50:39 -0700836
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700837 dh.resourceMgr = make([]*rsrcMgr.OpenOltResourceMgr, dh.totalPonPorts)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700838 dh.flowMgr = make([]*OpenOltFlowMgr, dh.totalPonPorts)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700839 var i uint32
840 for i = 0; i < dh.totalPonPorts; i++ {
841 // Instantiate resource manager
842 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 -0700843 return olterrors.ErrResourceManagerInstantiating
844 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400845 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700846 // GroupManager instance is per OLT. But it needs a reference to any instance of resourceMgr to interface with
847 // the KV store to manage mcast group data. Provide the first instance (0th index)
848 if dh.groupMgr = NewGroupManager(ctx, dh, dh.resourceMgr[0]); dh.groupMgr == nil {
849 return olterrors.ErrGroupManagerInstantiating
850 }
851 for i = 0; i < dh.totalPonPorts; i++ {
852 // Instantiate flow manager
853 if dh.flowMgr[i] = NewFlowManager(ctx, dh, dh.resourceMgr[i], dh.groupMgr, i); dh.flowMgr[i] == nil {
854 return olterrors.ErrFlowManagerInstantiating
855 }
856 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400857 /* TODO: Instantiate Alarm , stats , BW managers */
858 /* Instantiating Event Manager to handle Alarms and KPIs */
859 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
860
861 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000862 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400863
864 return nil
865
866}
867
Neha Sharma96b7bf22020-06-15 10:37:32 +0000868func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400869 var err error
870 var deviceInfo *oop.DeviceInfo
871
Neha Sharma8f4e4322020-08-06 10:51:53 +0000872 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400873
874 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000875 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400876 }
877 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000878 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400879 }
880
Neha Sharma96b7bf22020-06-15 10:37:32 +0000881 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400882 dh.device.Root = true
883 dh.device.Vendor = deviceInfo.Vendor
884 dh.device.Model = deviceInfo.Model
885 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
886 dh.device.HardwareVersion = deviceInfo.HardwareVersion
887 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
888
889 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000890 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400891 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000892 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400893 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000894 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400895 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000896 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400897 dh.device.MacAddress = genmac
898 } else {
899 dh.device.MacAddress = deviceInfo.DeviceId
900 }
901
902 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000903 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000904 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400905 }
906
907 return deviceInfo, nil
908}
909
Neha Sharma96b7bf22020-06-15 10:37:32 +0000910func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700911 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530912 for {
913 select {
914 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000915 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530916 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000917 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700918
Neha Sharma8f4e4322020-08-06 10:51:53 +0000919 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400920 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700921 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400922 continue
923 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530924 for _, port := range ports {
925 // NNI Stats
926 if port.Type == voltha.Port_ETHERNET_NNI {
927 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
928 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000929 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000930 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000931 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530932 }
933 // PON Stats
934 if port.Type == voltha.Port_PON_OLT {
935 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
936 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
937 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000938 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000939 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530940 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000941 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000942
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700943 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700944 if len(onuGemInfoLst) > 0 {
945 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000946 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500947 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530948 }
949 }
950 }
951}
952
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700953//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530954func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400955 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000956 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530957 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530958
959 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400960 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
961 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530962 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530963}
964
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700965//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530966func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700967 return &ic.SwitchCapability{
968 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530969 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700970 HwDesc: "open_pon",
971 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700972 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700973 },
974 SwitchFeatures: &of.OfpSwitchFeatures{
975 NBuffers: 256,
976 NTables: 2,
977 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
978 of.OfpCapabilities_OFPC_TABLE_STATS |
979 of.OfpCapabilities_OFPC_PORT_STATS |
980 of.OfpCapabilities_OFPC_GROUP_STATS),
981 },
982 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530983}
984
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700985// GetInterAdapterTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
986func (dh *DeviceHandler) GetInterAdapterTechProfileDownloadMessage(ctx context.Context, tpPath string, ponPortNum uint32, onuID uint32, uniID uint32) *ic.InterAdapterTechProfileDownloadMessage {
987 ifID, err := IntfIDFromPonPortNum(ctx, ponPortNum)
988 if err != nil {
989 return nil
990 }
991 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, tpPath, ifID, onuID, uniID)
992}
993
Neha Sharma96b7bf22020-06-15 10:37:32 +0000994func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
995 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 -0700996 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700997 var deviceID string
998 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -0700999
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001000 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001001 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001002 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 -07001003 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1004 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001005
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001006 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301007
1008 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1009
Neha Sharma96b7bf22020-06-15 10:37:32 +00001010 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 -07001011 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001012 kwargs := make(map[string]interface{})
1013 kwargs["onu_id"] = omciInd.OnuId
1014 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -07001015
Neha Sharma8f4e4322020-08-06 10:51:53 +00001016 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001017 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301018 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001019 "intf-id": omciInd.IntfId,
1020 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001021 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001022 deviceType = onuDevice.Type
1023 deviceID = onuDevice.Id
1024 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1025 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301026 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001027 } else {
1028 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001029 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 +05301030 deviceType = onuInCache.(*OnuDevice).deviceType
1031 deviceID = onuInCache.(*OnuDevice).deviceID
1032 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001033 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001034
1035 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001036 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001037 ic.InterAdapterMessageType_OMCI_RESPONSE, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001038 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301039 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001040 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001041 "destination": deviceType,
1042 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001043 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001044 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001045 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301046}
1047
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001048//ProcessInterAdapterMessage sends the proxied messages to the target device
1049// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1050// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001051func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1052 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001053 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001054 return dh.handleInterAdapterOmciMsg(ctx, msg)
1055 }
1056 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1057}
cuilin20187b2a8c32019-03-26 19:52:28 -07001058
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001059func (dh *DeviceHandler) handleInterAdapterOmciMsg(ctx context.Context, msg *ic.InterAdapterMessage) error {
1060 msgID := msg.Header.Id
1061 fromTopic := msg.Header.FromTopic
1062 toTopic := msg.Header.ToTopic
1063 toDeviceID := msg.Header.ToDeviceId
1064 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001065
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001066 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 -07001067
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001068 msgBody := msg.GetBody()
1069
1070 omciMsg := &ic.InterAdapterOmciMessage{}
1071 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
1072 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
1073 }
1074
1075 if omciMsg.GetProxyAddress() == nil {
1076 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
1077 if err != nil {
1078 return olterrors.NewErrNotFound("onu", log.Fields{
1079 "device-id": dh.device.Id,
1080 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001081 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001082 logger.Debugw(ctx, "device-retrieved-from-core", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001083 if err := dh.sendProxiedOmciMessage(ctx, onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001084 return olterrors.NewErrCommunication("send-failed", log.Fields{
1085 "device-id": dh.device.Id,
1086 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001087 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001088 } else {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001089 logger.Debugw(ctx, "proxy-address-found-in-omci-message", log.Fields{"msgID": msgID, "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001090 if err := dh.sendProxiedOmciMessage(ctx, nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001091 return olterrors.NewErrCommunication("send-failed", log.Fields{
1092 "device-id": dh.device.Id,
1093 "onu-device-id": toDeviceID}, err)
1094 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001095 }
1096 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301097}
1098
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001099func (dh *DeviceHandler) sendProxiedOmciMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001100 var intfID uint32
1101 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001102 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001103 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001104 intfID = onuDevice.ProxyAddress.GetChannelId()
1105 onuID = onuDevice.ProxyAddress.GetOnuId()
1106 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001107 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001108 intfID = omciMsg.GetProxyAddress().GetChannelId()
1109 onuID = omciMsg.GetProxyAddress().GetOnuId()
1110 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001111 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001112 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001113 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 -08001114
Thomas Lee S94109f12020-03-03 16:39:29 +05301115 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001116 "intf-id": intfID,
1117 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001118 }
1119
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001120 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1121 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001122 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001123 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1124 hex.Encode(hexPkt, omciMsg.Message)
1125 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1126
1127 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1128 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1129 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001130 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001131 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001132
Neha Sharma8f4e4322020-08-06 10:51:53 +00001133 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001134 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301135 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001136 "intf-id": intfID,
1137 "onu-id": onuID,
1138 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001139 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001140 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001141}
1142
David K. Bainbridge794735f2020-02-11 21:01:37 -08001143func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301144 logger.Debugw(ctx, "activate-onu", log.Fields{"intf-id": intfID, "onu-id": onuID, "serialNum": serialNum, "serialNumber": serialNumber, "device-id": dh.device.Id, "OmccEncryption": dh.openOLT.config.OmccEncryption})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001145 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001146 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001147 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001148 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301149 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301150 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001151 st, _ := status.FromError(err)
1152 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001153 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1154
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001155 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301156 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001157 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001158 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001159 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001160 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001161 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001162}
1163
Mahir Gunyelb0046752021-02-26 13:51:05 -08001164func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001165 channelID := onuDiscInd.GetIntfId()
1166 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001167
Mahir Gunyelb0046752021-02-26 13:51:05 -08001168 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001169 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301170
cuilin20187b2a8c32019-03-26 19:52:28 -07001171 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001172 if sn != "" {
1173 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001174 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001175 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001176 }
1177
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301178 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001179 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001180 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301181
1182 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1183 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1184 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1185 OnuLosRaise event sent for it */
1186 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1187 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1188 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001189 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301190 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1191 "currentIntfId": onuDiscInd.GetIntfId()})
1192 // TODO:: Should we need to ignore raising OnuLosClear event
1193 // when onu connected to different PON?
1194 }
1195 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1196 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1197 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001198 go func() {
1199 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001200 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001201 }
1202 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301203 }
1204 return true
1205 })
1206
Neha Sharma96b7bf22020-06-15 10:37:32 +00001207 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001208 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001209 }
1210
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001211 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001212
1213 // check the ONU is already know to the OLT
1214 // NOTE the second time the ONU is discovered this should return a device
1215 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1216
1217 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001218 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 -08001219 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001220 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 -08001221 switch e.Code() {
1222 case codes.Internal:
1223 // this probably means NOT FOUND, so just create a new device
1224 onuDevice = nil
1225 case codes.DeadlineExceeded:
1226 // if the call times out, cleanup and exit
1227 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001228 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001229 }
1230 }
1231 }
1232
1233 if onuDevice == nil {
1234 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001235 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001236 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001237 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001238 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001239
Neha Sharma96b7bf22020-06-15 10:37:32 +00001240 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001241
1242 if err != nil {
1243 // if we can't create an ID in resource manager,
1244 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001245 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001246 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001247 "pon-intf-id": ponintfid,
1248 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001249 }
1250
Neha Sharma8f4e4322020-08-06 10:51:53 +00001251 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001252 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001253 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001254 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 +05301255 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001256 "pon-intf-id": ponintfid,
1257 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001258 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001259 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 -07001260 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001261 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001262 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301263 log.Fields{"onuDevice": onuDevice,
1264 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001265 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301266 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001267 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001268
1269 // we can now use the existing ONU Id
1270 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001271 //Insert the ONU into cache to use in OnuIndication.
1272 //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 +00001273 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001274 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301275 "intfId": onuDiscInd.GetIntfId(),
1276 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001277 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001278
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301279 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301280 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001281 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301282 log.Fields{"onu": onuDev,
1283 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001284
Kent Hagermane6ff1012020-07-14 15:07:53 -04001285 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301286 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001287 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001288 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001289 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001290 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001291 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301292 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001293 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001294 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001295 }
1296 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001297}
1298
Mahir Gunyelb0046752021-02-26 13:51:05 -08001299func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001300
1301 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001302 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001303 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001304 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001305 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001306 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301307 log.Fields{"onuId": onuInd.OnuId,
1308 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301309 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001310 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001311 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301312
David K. Bainbridge794735f2020-02-11 21:01:37 -08001313 errFields := log.Fields{"device-id": dh.device.Id}
1314
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301315 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1316
Mahir Gunyele77977b2019-06-27 05:36:22 -07001317 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1318 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001319 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001320 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001321 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001322 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1323 if serialNumber != "" {
1324 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001325 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001326 } else {
1327 kwargs["onu_id"] = onuInd.OnuId
1328 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001329 errFields["onu-id"] = onuInd.OnuId
1330 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001331 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001332 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001333 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001334
David K. Bainbridge794735f2020-02-11 21:01:37 -08001335 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001336 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001337 }
1338
David K. Bainbridge794735f2020-02-11 21:01:37 -08001339 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001340 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001341 "previousIntfId": onuDevice.ParentPortNo,
1342 "currentIntfId": ponPort})
1343 }
1344
1345 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001346 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301347 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1348 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301349 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001350 }
1351 if !foundInCache {
1352 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1353
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301354 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 -08001355
1356 }
kesavand7cf3a052020-08-28 12:49:18 +05301357 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001358 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001359 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301360 }
1361 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001362 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001363 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001364 }
1365 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001366}
1367
Neha Sharma96b7bf22020-06-15 10:37:32 +00001368func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001369 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 -07001370 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1371 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1372 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1373 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001374 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001375 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1376 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001377 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001378 onuInd.OperState = "down"
1379 }
1380 }
1381
David K. Bainbridge794735f2020-02-11 21:01:37 -08001382 switch onuInd.OperState {
1383 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001384 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 -07001385 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301386 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001387 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001388 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301389 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001390 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001391 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001392 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001393 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001394 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001395 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001396 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 -04001397 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301398 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001399 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001400 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301401 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001402 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001403 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001404 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001405 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001406 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001407 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001408 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001409 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001410 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001411}
1412
cuilin20187b2a8c32019-03-26 19:52:28 -07001413func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1414 if serialNum != nil {
1415 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001416 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001417 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001418}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001419func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1420 decodedStr, err := hex.DecodeString(serialNum[4:])
1421 if err != nil {
1422 return nil, err
1423 }
1424 return &oop.SerialNumber{
1425 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001426 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001427 }, nil
1428}
cuilin20187b2a8c32019-03-26 19:52:28 -07001429
1430func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001431 if len(vendorSpecific) > 3 {
1432 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1433 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1434 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1435 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1436 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1437 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1438 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1439 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1440 return tmp
1441 }
1442 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001443}
1444
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001445//UpdateFlowsBulk upates the bulk flow
1446func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301447 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001448}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001449
1450//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001451func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1452 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301453 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001454 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301455 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001456 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001457 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001458 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001459 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001460 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001461 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001462 "intf-id": parentPort,
1463 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001464 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001465 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 -08001466 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301467}
1468
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001469// SendPacketInToCore sends packet-in to core
1470// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1471// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001472func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001473 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001474 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001475 "port": logicalPort,
1476 "packet": hex.EncodeToString(packetPayload),
1477 "device-id": dh.device.Id,
1478 })
1479 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001480 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 +05301481 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001482 "source": "adapter",
1483 "destination": "core",
1484 "device-id": dh.device.Id,
1485 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001486 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001487 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001488 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001489 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001490 "packet": hex.EncodeToString(packetPayload),
1491 "device-id": dh.device.Id,
1492 })
1493 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001494 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001495}
1496
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001497// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001498func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001499 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001500
1501 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1502 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001503 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001504 }
1505
Kent Hagermane6ff1012020-07-14 15:07:53 -04001506 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001507 metrics := dh.metrics.GetSubscriberMetrics()
1508 for _, m := range pmConfigs.Metrics {
1509 metrics[m.Name].Enabled = m.Enabled
1510
1511 }
1512 }
1513}
1514
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001515//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301516func (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 +00001517 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 +01001518
Girish Gowdra491a9c62021-01-06 16:43:07 -08001519 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001520 var errorsList []error
1521
Girish Gowdru0c588b22019-04-23 23:24:56 -04001522 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001523 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001524 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001525
Neha Sharma96b7bf22020-06-15 10:37:32 +00001526 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301527 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001528 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301529 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001530 if flow_utils.HasGroup(flow) {
1531 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1532 } else {
1533 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1534 }
Girish Gowdracefae192020-03-19 18:14:10 -07001535 if err != nil {
1536 errorsList = append(errorsList, err)
1537 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001538 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301539
1540 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001541 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001542 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301543 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001544 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301545 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001546 if flow_utils.HasGroup(flow) {
1547 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1548 } else {
1549 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1550 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001551 if err != nil {
1552 errorsList = append(errorsList, err)
1553 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301554 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001555 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001556
Girish Gowdracefae192020-03-19 18:14:10 -07001557 // 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 +00001558 if groups != nil {
1559 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001560 // err = dh.groupMgr.AddGroup(ctx, group)
1561 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001562 if err != nil {
1563 errorsList = append(errorsList, err)
1564 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001565 }
1566 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001567 // err = dh.groupMgr.ModifyGroup(ctx, group)
1568 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001569 if err != nil {
1570 errorsList = append(errorsList, err)
1571 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001572 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001573 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001574 // err = dh.groupMgr.DeleteGroup(ctx, group)
1575 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001576 if err != nil {
1577 errorsList = append(errorsList, err)
1578 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001579 }
1580 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001581 if len(errorsList) > 0 {
1582 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1583 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001584 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001585 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301586}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001587
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001588//DisableDevice disables the given device
1589//It marks the following for the given device:
1590//Device-Handler Admin-State : down
1591//Device Port-State: UNKNOWN
1592//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001593func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001594 /* On device disable ,admin state update has to be done prior sending request to agent since
1595 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001596 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001597 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001598 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001599 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001600 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001601 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001602 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001603 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001604 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001605 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301606
1607 dh.discOnus = sync.Map{}
1608 dh.onus = sync.Map{}
1609
Thomas Lee S85f37312020-04-03 17:06:12 +05301610 //stopping the stats collector
1611 dh.stopCollector <- true
1612
Neha Sharma96b7bf22020-06-15 10:37:32 +00001613 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001614 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301615 //Update device Admin state
1616 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001617 // 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 +00001618 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 -04001619 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001620 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001621 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001622 return nil
1623}
1624
Neha Sharma96b7bf22020-06-15 10:37:32 +00001625func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001626 // Update onu state as unreachable in onu adapter
1627 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301628 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001629 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001630 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001631 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001632 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 -04001633 }
1634 if onuDevices != nil {
1635 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001636 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001637 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001638 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001639 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001640 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001641 }
1642
1643 }
1644 }
1645
1646}
1647
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001648//ReenableDevice re-enables the olt device after disable
1649//It marks the following for the given device:
1650//Device-Handler Admin-State : up
1651//Device Port-State: ACTIVE
1652//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001653func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001654 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301655 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001656 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301657 }
1658 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001659 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001660
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001661 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001662
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001663 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1664 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001665 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001666 }
1667 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001668 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001669 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001670 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001671 device.OperStatus = voltha.OperStatus_ACTIVE
1672 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001673
Neha Sharma8f4e4322020-08-06 10:51:53 +00001674 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 +05301675 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001676 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001677 "connect-status": device.ConnectStatus,
1678 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001679 }
kesavand39e0aa32020-01-28 20:58:50 -05001680
Neha Sharma96b7bf22020-06-15 10:37:32 +00001681 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001682
1683 return nil
1684}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001685
npujarec5762e2020-01-01 14:08:48 +05301686func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001687 var uniID uint32
1688 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301689 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001690 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001691 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001692 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001693 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001694 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001695 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001696 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001697 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001698 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001699 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001700 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001701 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001702 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001703 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001704 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001705 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001706 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301707 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001708 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1709 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001710 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301711 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001712 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001713 if err = dh.resourceMgr[onu.IntfID].DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001714 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 +00001715 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001716 }
1717 return nil
1718}
1719
Devmalya Paul495b94a2019-08-27 19:42:00 -04001720// 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 +05301721func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001722 logger.Debugw(ctx, "function-entry-delete-device", log.Fields{"device-id": dh.device.Id})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001723 /* Clear the KV store data associated with the all the UNI ports
1724 This clears up flow data and also resource map data for various
1725 other pon resources like alloc_id and gemport_id
1726 */
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001727 dh.cleanupDeviceResources(ctx)
1728 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 -04001729 // Stop the Stats collector
1730 dh.stopCollector <- true
1731 // stop the heartbeat check routine
1732 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301733 dh.lockDevice.RLock()
1734 // Stop the read indication only if it the routine is active
1735 if dh.isReadIndicationRoutineActive {
1736 dh.stopIndications <- true
1737 }
1738 dh.lockDevice.RUnlock()
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001739 dh.removeOnuIndicationChannels(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001740 //Reset the state
1741 if dh.Client != nil {
1742 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301743 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001744 }
1745 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001746 // There is no need to update the core about operation status and connection status of the OLT.
1747 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1748 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1749 // because the device does not exist in DB.
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001750
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001751 return nil
1752}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001753func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001754
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001755 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301756 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001757 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001758 var err error
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001759 onuGemData := dh.flowMgr[ponPort].getOnuGemInfoList(ctx)
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001760 for i, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301761 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001762 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001763 if err = dh.clearUNIData(ctx, &onuGemData[i]); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001764 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301765 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301766 // Clear flowids for gem cache.
1767 for _, gem := range onu.GemPorts {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001768 dh.resourceMgr[ponPort].DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301769 }
1770 onuID[0] = onu.OnuID
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001771 dh.resourceMgr[ponPort].FreeonuID(ctx, ponPort, onuID)
1772 err = dh.resourceMgr[ponPort].DelOnuGemInfo(ctx, ponPort, onu.OnuID)
1773 if err != nil {
1774 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
1775 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301776 }
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001777 if err := dh.resourceMgr[ponPort].Delete(ctx, ponPort); err != nil {
1778 logger.Debug(ctx, err)
1779 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001780 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001781 }
A R Karthick1f85b802019-10-11 05:06:05 +00001782
Devmalya Paul495b94a2019-08-27 19:42:00 -04001783 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301784 dh.onus.Range(func(key interface{}, value interface{}) bool {
1785 dh.onus.Delete(key)
1786 return true
1787 })
1788
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001789 /*Delete discovered ONU map for the device*/
1790 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1791 dh.discOnus.Delete(key)
1792 return true
1793 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001794}
1795
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001796//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001797func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001798 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301799 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001800 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001801 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001802 return nil
1803}
1804
David K. Bainbridge794735f2020-02-11 21:01:37 -08001805func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001806 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001807 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001808 "packet-indication": *packetIn,
1809 "device-id": dh.device.Id,
1810 "packet": hex.EncodeToString(packetIn.Pkt),
1811 })
1812 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001813 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001814 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001815 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001816 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001817 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001818 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001819 "logical-port-num": logicalPortNum,
1820 "device-id": dh.device.Id,
1821 "packet": hex.EncodeToString(packetIn.Pkt),
1822 })
1823 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001824
Neha Sharma8f4e4322020-08-06 10:51:53 +00001825 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 +05301826 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001827 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301828 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001829 "device-id": dh.device.Id,
1830 "packet": hex.EncodeToString(packetIn.Pkt),
1831 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001832 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001833
Matteo Scandolo92186242020-06-12 10:54:18 -07001834 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001835 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001836 "packet": hex.EncodeToString(packetIn.Pkt),
1837 "device-id": dh.device.Id,
1838 })
1839 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001840 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001841}
1842
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001843// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301844func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001845 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001846 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001847 "device-id": dh.device.Id,
1848 "egress-port-no": egressPortNo,
1849 "pkt-length": len(packet.Data),
1850 "packet": hex.EncodeToString(packet.Data),
1851 })
1852 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001853
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001854 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001855 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001856 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1857 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301858 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1859 // Do not packet-out lldp packets on uni port.
1860 // ONOS has no clue about uni/nni ports, it just packets out on all
1861 // available ports on the Logical Switch. It should not be interested
1862 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001863 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001864 "device-id": dh.device.Id,
1865 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301866 return nil
1867 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001868 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1869 if innerEthType == 0x8100 {
1870 // q-in-q 802.1ad or 802.1q double tagged packet.
1871 // slice out the outer tag.
1872 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001873 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001874 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001875 "packet-data": hex.EncodeToString(packet.Data),
1876 "device-id": dh.device.Id,
1877 })
1878 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001879 }
1880 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001881 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1882 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001883 uniID := UniIDFromPortNum(uint32(egressPortNo))
1884
Girish Gowdra9602eb42020-09-09 15:50:39 -07001885 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001886 if err != nil {
1887 // In this case the openolt agent will receive the gemPortID as 0.
1888 // The agent tries to retrieve the gemPortID in this case.
1889 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001890 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001891 "intf-id": intfID,
1892 "onu-id": onuID,
1893 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001894 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301895 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001896 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001897 }
1898
1899 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001900 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001901 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001902 "egress-port-no": egressPortNo,
1903 "intf-id": intfID,
1904 "onu-id": onuID,
1905 "uni-id": uniID,
1906 "gem-port-id": gemPortID,
1907 "packet": hex.EncodeToString(packet.Data),
1908 "device-id": dh.device.Id,
1909 })
1910 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001911
npujarec5762e2020-01-01 14:08:48 +05301912 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301913 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001914 "source": "adapter",
1915 "destination": "onu",
1916 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001917 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001918 "oni-id": onuID,
1919 "uni-id": uniID,
1920 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001921 "packet": hex.EncodeToString(packet.Data),
1922 "device-id": dh.device.Id,
1923 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001924 }
1925 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001926 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001927 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001928 return olterrors.NewErrInvalidValue(log.Fields{
1929 "egress-nni-port": egressPortNo,
1930 "device-id": dh.device.Id,
1931 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001932 }
1933 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001934
Matteo Scandolo92186242020-06-12 10:54:18 -07001935 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001936 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001937 "uplink-pkt": uplinkPkt,
1938 "packet": hex.EncodeToString(packet.Data),
1939 "device-id": dh.device.Id,
1940 })
1941 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001942
npujarec5762e2020-01-01 14:08:48 +05301943 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001944 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1945 "packet": hex.EncodeToString(packet.Data),
1946 "device-id": dh.device.Id,
1947 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001948 }
1949 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001950 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301951 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001952 "egressPortType": egressPortType,
1953 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301954 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001955 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001956 }
1957 return nil
1958}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001959
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001960func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1961 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001962}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301963
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001964func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001965
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301966 // start the heartbeat check towards the OLT.
1967 var timerCheck *time.Timer
1968
1969 for {
1970 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1971 select {
1972 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001973 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001974 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001975 logger.Warnw(ctx, "heartbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301976 if timerCheck == nil {
1977 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001978 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301979 }
1980 } else {
1981 if timerCheck != nil {
1982 if timerCheck.Stop() {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001983 logger.Debugw(ctx, "got-heartbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301984 }
1985 timerCheck = nil
1986 }
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001987 logger.Debugw(ctx, "heartbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301988 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301989 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301990 }
1991 cancel()
1992 case <-dh.stopHeartbeatCheck:
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001993 logger.Debugw(ctx, "stopping-heartbeat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301994 return
1995 }
1996 }
1997}
1998
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001999func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
2000 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
2001 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002002 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2003 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2004 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2005 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2006 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002007 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002008 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2009 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002010 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302011
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002012 logger.Debugw(ctx, "update-state-unreachable", log.Fields{"device-id": dh.device.Id, "connect-status": device.ConnectStatus,
2013 "admin-state": device.AdminState, "oper-status": device.OperStatus})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002014 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
2015 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002016 _ = 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 -04002017 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002018 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002019 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002020 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002021
2022 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002023 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +00002024 device.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2025 device.OperStatus = voltha.OperStatus_UNKNOWN
2026 go dh.eventMgr.oltCommunicationEvent(ctx, device, raisedTs)
2027
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07002028 dh.cleanupDeviceResources(ctx)
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002029 // Stop the Stats collector
2030 dh.stopCollector <- true
2031 // stop the heartbeat check routine
2032 dh.stopHeartbeatCheck <- true
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002033
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002034 dh.lockDevice.RLock()
2035 // Stop the read indication only if it the routine is active
2036 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2037 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2038 // on next execution of the readIndication routine.
2039 if dh.isReadIndicationRoutineActive {
2040 dh.stopIndications <- true
2041 }
2042 dh.lockDevice.RUnlock()
2043
Gamze Abakac2c32a62021-03-11 11:44:18 +00002044 //reset adapter reconcile flag
2045 dh.adapterPreviouslyConnected = false
2046
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002047 dh.transitionMap.Handle(ctx, DeviceInit)
2048
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302049 }
2050}
kesavand39e0aa32020-01-28 20:58:50 -05002051
2052// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002053func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2054 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2055 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002056}
2057
2058// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002059func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2060 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2061 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002062}
2063
kdarapu1afeceb2020-02-12 01:38:09 -05002064//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 +00002065func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2066 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002067 if port.GetType() == voltha.Port_ETHERNET_NNI {
2068 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002069 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302070 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302071 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002072 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002073 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002074 }
2075 // fetch interfaceid from PortNo
2076 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2077 ponIntf := &oop.Interface{IntfId: ponID}
2078 var operStatus voltha.OperStatus_Types
2079 if enablePort {
2080 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302081 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002082
2083 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302084 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002085 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002086 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002087 }
2088 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002089 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002090 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002091 } else {
2092 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302093 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002094 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302095 return olterrors.NewErrAdapter("pon-port-disable-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, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002101 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002102 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302103 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 +05302104 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302105 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002106 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002107 }
2108 return nil
2109}
2110
kdarapu1afeceb2020-02-12 01:38:09 -05002111//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002112func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002113 // Disable the port and update the oper_port_status to core
2114 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002115 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002116 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002117 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302118 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302119 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002120 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002121 }
2122 }
2123 }
2124 return nil
2125}
2126
2127//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002128func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2129 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2130 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002131 if port.Type == voltha.Port_ETHERNET_NNI {
2132 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002133 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002134 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002135 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002136 }
2137 }
2138 if port.Type == voltha.Port_PON_OLT {
2139 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002140 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002141 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002142 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002143 }
2144 }
2145 }
2146}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002147
2148// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002149func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002150 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002151 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2152 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002153
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002154 var sn *oop.SerialNumber
2155 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002156 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302157 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002158 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302159 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002160 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002161 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002162
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002163 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002164 //clear PON resources associated with ONU
2165 onuGem, err := dh.resourceMgr[intfID].GetOnuGemInfo(ctx, intfID, onuID)
2166 if err != nil || onuGem == nil || onuGem.OnuID != onuID {
2167 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
2168 "device-id": dh.device.Id,
2169 "intf-id": intfID,
2170 "onuID": onuID,
2171 "err": err})
2172 } else {
2173 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
2174 if err := dh.clearUNIData(ctx, onuGem); err != nil {
2175 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
2176 "device-id": dh.device.Id,
2177 "onu-device": onu,
2178 "err": err})
2179 }
2180 // Clear flowids for gem cache.
2181 for _, gem := range onuGem.GemPorts {
2182 dh.resourceMgr[intfID].DeleteFlowIDsForGem(ctx, intfID, gem)
2183 }
2184 err := dh.resourceMgr[intfID].DelOnuGemInfo(ctx, intfID, onuID)
2185 if err != nil {
2186 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
2187 "intf-id": intfID,
2188 "onu-device": onu,
2189 "onu-gem": onuGem,
2190 "err": err})
2191 //Not returning error on cleanup.
2192 }
2193 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGem})
2194 dh.resourceMgr[intfID].FreeonuID(ctx, intfID, []uint32{onuGem.OnuID})
2195 }
2196 dh.onus.Delete(onuKey)
2197 dh.discOnus.Delete(onuSn)
2198
2199 // Now clear the ONU on the OLT
Neha Sharma8f4e4322020-08-06 10:51:53 +00002200 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302201 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302202 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002203 "onu-id": onuID}, err).Log()
2204 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002205
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002206 return nil
2207}
Girish Gowdracefae192020-03-19 18:14:10 -07002208
2209func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002210 for _, field := range flow_utils.GetOfbFields(flow) {
2211 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002212 return field.GetPort()
2213 }
2214 }
2215 return InvalidPort
2216}
2217
2218func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002219 for _, action := range flow_utils.GetActions(flow) {
2220 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002221 if out := action.GetOutput(); out != nil {
2222 return out.GetPort()
2223 }
2224 }
2225 }
2226 return InvalidPort
2227}
2228
Girish Gowdracefae192020-03-19 18:14:10 -07002229func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2230 inPort := getInPortFromFlow(flow)
2231 outPort := getOutPortFromFlow(flow)
2232
2233 if inPort == InvalidPort || outPort == InvalidPort {
2234 return inPort, outPort
2235 }
2236
2237 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2238 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2239 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002240 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002241 return uniPort, outPort
2242 }
2243 }
2244 } else {
2245 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2246 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002247 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002248 return inPort, uniPort
2249 }
2250 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2251 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002252 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002253 return uniPort, outPort
2254 }
2255 }
2256 }
2257
2258 return InvalidPort, InvalidPort
2259}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002260
2261func extractOmciTransactionID(omciPkt []byte) uint16 {
2262 if len(omciPkt) > 3 {
2263 d := omciPkt[0:2]
2264 transid := binary.BigEndian.Uint16(d)
2265 return transid
2266 }
2267 return 0
2268}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002269
2270// StoreOnuDevice stores the onu parameters to the local cache.
2271func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2272 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2273 dh.onus.Store(onuKey, onuDevice)
2274}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002275
Neha Sharma8f4e4322020-08-06 10:51:53 +00002276func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002277 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002278 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002279 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002280 resp := new(voltha.ReturnValues)
2281 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002282 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002283 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002284 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2285 return nil, err
2286 }
2287 ID = device.ProxyAddress.GetOnuId()
2288 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2289 valueparam.Onu = &Onu
2290 valueparam.Value = value
2291
2292 // This API is unsupported until agent patch is added
2293 resp.Unsupported = uint32(value)
2294 _ = ctx
2295
2296 // Uncomment this code once agent changes are complete and tests
2297 /*
2298 resp, err = dh.Client.GetValue(ctx, valueparam)
2299 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002300 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "err": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002301 return nil, err
2302 }
2303 */
2304
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002305 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 -08002306 return resp, nil
2307}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002308
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002309func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002310 // Default to PON0
2311 var intfID uint32
2312 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002313 if inPort != InvalidPort && outPort != InvalidPort {
2314 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2315 }
2316 return intfID
2317}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002318
Mahir Gunyelb0046752021-02-26 13:51:05 -08002319func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2320 dh.perPonOnuIndicationChannelLock.Lock()
2321 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2322 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002323 return ch.indicationChannel
2324 }
2325 channels := onuIndicationChannels{
2326 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002327 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002328 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002329 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002330 stopChannel: make(chan struct{}),
2331 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002332 dh.perPonOnuIndicationChannel[intfID] = channels
2333 dh.perPonOnuIndicationChannelLock.Unlock()
2334 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002335 return channels.indicationChannel
2336
2337}
2338
Mahir Gunyelb0046752021-02-26 13:51:05 -08002339func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2340 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2341 dh.perPonOnuIndicationChannelLock.Lock()
2342 defer dh.perPonOnuIndicationChannelLock.Unlock()
2343 for _, v := range dh.perPonOnuIndicationChannel {
2344 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002345 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002346 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002347}
2348
Mahir Gunyelb0046752021-02-26 13:51:05 -08002349func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2350 ind := onuIndicationMsg{
2351 ctx: ctx,
2352 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002353 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002354 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002355 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002356 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002357}
2358
Mahir Gunyelb0046752021-02-26 13:51:05 -08002359func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002360 for {
2361 select {
2362 // process one indication per onu, before proceeding to the next one
2363 case onuInd := <-onuChannels.indicationChannel:
2364 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002365 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002366 switch onuInd.indication.Data.(type) {
2367 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002368 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002369 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2370 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002371 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002372 }
2373 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002374 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002375 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2376 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002377 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002378 }
2379 }
2380 case <-onuChannels.stopChannel:
2381 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2382 close(onuChannels.indicationChannel)
2383 return
2384 }
2385 }
2386}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002387
2388// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2389// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2390func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2391 // Step1 : Fill McastFlowOrGroupControlBlock
2392 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2393 // Step3 : Wait on response channel for response
2394 // Step4 : Return error value
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002395 startTime := time.Now()
Girish Gowdra491a9c62021-01-06 16:43:07 -08002396 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2397 errChan := make(chan error)
2398 var groupID uint32
2399 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2400 ctx: ctx,
2401 flowOrGroupAction: action,
2402 flow: flow,
2403 group: group,
2404 errChan: &errChan,
2405 }
2406 if flow != nil {
2407 groupID = flow_utils.GetGroup(flow)
2408 } else if group != nil {
2409 groupID = group.Desc.GroupId
2410 } else {
2411 return errors.New("flow-and-group-both-nil")
2412 }
2413 // Derive the appropriate go routine to handle the request by a simple module operation.
2414 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2415 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2416 // Wait for handler to return error value
2417 err := <-errChan
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002418 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 -08002419 return err
2420}
2421
2422// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
2423func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock) {
2424 for {
2425 // block on the channel to receive an incoming mcast flow/group
2426 // process the flow completely before proceeding to handle the next flow
2427 mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel
2428 if mcastFlowOrGroupCb.flow != nil {
2429 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2430 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2431 log.Fields{"device-id": dh.device.Id,
2432 "flowToAdd": mcastFlowOrGroupCb.flow})
2433 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2434 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2435 // Pass the return value over the return channel
2436 *mcastFlowOrGroupCb.errChan <- err
2437 } else { // flow remove
2438 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2439 log.Fields{"device-id": dh.device.Id,
2440 "flowToRemove": mcastFlowOrGroupCb.flow})
2441 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2442 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2443 // Pass the return value over the return channel
2444 *mcastFlowOrGroupCb.errChan <- err
2445 }
2446 } else { // mcast group
2447 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2448 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2449 log.Fields{"device-id": dh.device.Id,
2450 "groupToAdd": mcastFlowOrGroupCb.group})
2451 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2452 // Pass the return value over the return channel
2453 *mcastFlowOrGroupCb.errChan <- err
2454 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2455 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2456 log.Fields{"device-id": dh.device.Id,
2457 "groupToModify": mcastFlowOrGroupCb.group})
2458 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2459 // Pass the return value over the return channel
2460 *mcastFlowOrGroupCb.errChan <- err
2461 } else { // group remove
2462 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2463 log.Fields{"device-id": dh.device.Id,
2464 "groupToRemove": mcastFlowOrGroupCb.group})
2465 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2466 // Pass the return value over the return channel
2467 *mcastFlowOrGroupCb.errChan <- err
2468 }
2469 }
2470 }
2471}
kesavand62126212021-01-12 04:56:06 -05002472
2473func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2474
2475 singleValResp := extension.SingleGetValueResponse{
2476 Response: &extension.GetValueResponse{
2477 Response: &extension.GetValueResponse_PortCoutners{
2478 PortCoutners: &extension.GetOltPortCountersResponse{},
2479 },
2480 },
2481 }
2482
2483 errResp := func(status extension.GetValueResponse_Status,
2484 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2485 return &extension.SingleGetValueResponse{
2486 Response: &extension.GetValueResponse{
2487 Status: status,
2488 ErrReason: reason,
2489 },
2490 }
2491 }
2492
2493 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2494 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2495 //send error response
2496 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2497 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2498 }
2499 statIndChn := make(chan bool, 1)
2500 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2501 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2502 //request openOlt agent to send the the port statistics indication
2503
2504 go func() {
2505 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2506 if err != nil {
2507 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2508 }
2509 }()
2510 select {
2511 case <-statIndChn:
2512 //indication received for ports stats
2513 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2514 case <-time.After(oltPortInfoTimeout * time.Second):
2515 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2516 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2517 case <-ctx.Done():
2518 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2519 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2520 }
2521 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2522 //get nni stats
2523 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
2524 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2525 cmnni := dh.portStats.collectNNIMetrics(intfID)
2526 if cmnni == nil {
2527 //TODO define the error reason
2528 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2529 }
2530 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2531 return &singleValResp
2532
2533 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2534 // get pon stats
2535 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
2536 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2537 cmpon := dh.portStats.collectPONMetrics(intfID)
2538 if cmpon == nil {
2539 //TODO define the error reason
2540 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2541 }
2542 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2543 return &singleValResp
2544 }
2545 }
2546 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2547}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +05302548
2549func (dh *DeviceHandler) getOnuPonCounters(ctx context.Context, onuPonInfo *extension.GetOnuCountersRequest) *extension.SingleGetValueResponse {
2550
2551 singleValResp := extension.SingleGetValueResponse{
2552 Response: &extension.GetValueResponse{
2553 Response: &extension.GetValueResponse_OnuPonCounters{
2554 OnuPonCounters: &extension.GetOnuCountersResponse{},
2555 },
2556 },
2557 }
2558
2559 errResp := func(status extension.GetValueResponse_Status,
2560 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2561 return &extension.SingleGetValueResponse{
2562 Response: &extension.GetValueResponse{
2563 Status: status,
2564 ErrReason: reason,
2565 },
2566 }
2567 }
2568 intfID := onuPonInfo.IntfId
2569 onuID := onuPonInfo.OnuId
2570 onuKey := dh.formOnuKey(intfID, onuID)
2571
2572 if _, ok := dh.onus.Load(onuKey); !ok {
2573 logger.Errorw(ctx, "get-onui-pon-counters-request-invalid-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2574 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2575 }
2576 logger.Debugw(ctx, "get-onui-pon-counters-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2577 cmnni := dh.portStats.collectOnDemandOnuStats(ctx, intfID, onuID)
2578 if cmnni == nil {
2579 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2580 }
2581 dh.portStats.updateGetOnuPonCountersResponse(ctx, &singleValResp, cmnni)
2582 return &singleValResp
2583
2584}
Gamze Abaka85e9a142021-05-26 13:41:39 +00002585
2586func (dh *DeviceHandler) getRxPower(ctx context.Context, rxPowerRequest *extension.GetRxPowerRequest) *extension.SingleGetValueResponse {
2587
2588 Onu := oop.Onu{IntfId: rxPowerRequest.IntfId, OnuId: rxPowerRequest.OnuId}
2589 rxPower, err := dh.Client.GetPonRxPower(ctx, &Onu)
2590 if err != nil {
2591 logger.Errorw(ctx, "error-while-getting-rx-power", log.Fields{"Onu": Onu, "err": err})
2592 return generateSingleGetValueErrorResponse(err)
2593 }
2594 return &extension.SingleGetValueResponse{
2595 Response: &extension.GetValueResponse{
2596 Status: extension.GetValueResponse_OK,
2597 Response: &extension.GetValueResponse_RxPower{
2598 RxPower: &extension.GetRxPowerResponse{
2599 IntfId: rxPowerRequest.IntfId,
2600 OnuId: rxPowerRequest.OnuId,
2601 Status: rxPower.Status,
2602 FailReason: rxPower.FailReason.String(),
2603 RxPower: rxPower.RxPowerMeanDbm,
2604 },
2605 },
2606 },
2607 }
2608}
2609
2610func generateSingleGetValueErrorResponse(err error) *extension.SingleGetValueResponse {
2611 errResp := func(status extension.GetValueResponse_Status,
2612 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2613 return &extension.SingleGetValueResponse{
2614 Response: &extension.GetValueResponse{
2615 Status: status,
2616 ErrReason: reason,
2617 },
2618 }
2619 }
2620
2621 if err != nil {
2622 if e, ok := status.FromError(err); ok {
2623 switch e.Code() {
2624 case codes.Internal:
2625 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2626 case codes.DeadlineExceeded:
2627 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2628 case codes.Unimplemented:
2629 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_UNSUPPORTED)
2630 case codes.NotFound:
2631 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2632 }
2633 }
2634 }
2635
2636 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_REASON_UNDEFINED)
2637}