blob: 60bd3bd555f9d83e33b4a601e1f3f8b9b30af163 [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 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700856 dh.resourceMgr[i].TechprofileRef = dh.flowMgr[i].techprofile
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700857 }
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400858 /* TODO: Instantiate Alarm , stats , BW managers */
859 /* Instantiating Event Manager to handle Alarms and KPIs */
860 dh.eventMgr = NewEventMgr(dh.EventProxy, dh)
861
862 // Stats config for new device
Neha Sharma96b7bf22020-06-15 10:37:32 +0000863 dh.portStats = NewOpenOltStatsMgr(ctx, dh)
Chaitrashree G Sa4649252020-03-11 21:24:11 -0400864
865 return nil
866
867}
868
Neha Sharma96b7bf22020-06-15 10:37:32 +0000869func (dh *DeviceHandler) populateDeviceInfo(ctx context.Context) (*oop.DeviceInfo, error) {
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400870 var err error
871 var deviceInfo *oop.DeviceInfo
872
Neha Sharma8f4e4322020-08-06 10:51:53 +0000873 deviceInfo, err = dh.Client.GetDeviceInfo(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty))
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400874
875 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000876 return nil, olterrors.NewErrPersistence("get", "device", 0, nil, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400877 }
878 if deviceInfo == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000879 return nil, olterrors.NewErrInvalidValue(log.Fields{"device": nil}, nil)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400880 }
881
Neha Sharma96b7bf22020-06-15 10:37:32 +0000882 logger.Debugw(ctx, "fetched-device-info", log.Fields{"deviceInfo": deviceInfo, "device-id": dh.device.Id})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400883 dh.device.Root = true
884 dh.device.Vendor = deviceInfo.Vendor
885 dh.device.Model = deviceInfo.Model
886 dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
887 dh.device.HardwareVersion = deviceInfo.HardwareVersion
888 dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
889
890 if deviceInfo.DeviceId == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000891 logger.Warnw(ctx, "no-device-id-provided-using-host", log.Fields{"hostport": dh.device.GetHostAndPort()})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400892 host := strings.Split(dh.device.GetHostAndPort(), ":")[0]
Neha Sharma96b7bf22020-06-15 10:37:32 +0000893 genmac, err := generateMacFromHost(ctx, host)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400894 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000895 return nil, olterrors.NewErrAdapter("failed-to-generate-mac-host", log.Fields{"host": host}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400896 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000897 logger.Debugw(ctx, "using-host-for-mac-address", log.Fields{"host": host, "mac": genmac})
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400898 dh.device.MacAddress = genmac
899 } else {
900 dh.device.MacAddress = deviceInfo.DeviceId
901 }
902
903 // Synchronous call to update device - this method is run in its own go routine
Neha Sharma8f4e4322020-08-06 10:51:53 +0000904 if err := dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000905 return nil, olterrors.NewErrAdapter("device-update-failed", log.Fields{"device-id": dh.device.Id}, err)
Matt Jeanneretf4fdcd72019-07-19 20:03:23 -0400906 }
907
908 return deviceInfo, nil
909}
910
Neha Sharma96b7bf22020-06-15 10:37:32 +0000911func startCollector(ctx context.Context, dh *DeviceHandler) {
Matteo Scandolo861e06e2021-05-26 11:51:46 -0700912 logger.Debugw(ctx, "starting-collector", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530913 for {
914 select {
915 case <-dh.stopCollector:
divyadesai3af43e12020-08-18 07:10:54 +0000916 logger.Debugw(ctx, "stopping-collector-for-olt", log.Fields{"device-id": dh.device.Id})
Naga Manjunath7615e552019-10-11 22:35:47 +0530917 return
Rohan Agrawalda5e0b22020-05-20 11:10:26 +0000918 case <-time.After(time.Duration(dh.metrics.ToPmConfigs().DefaultFreq) * time.Second):
Girish Gowdra34815db2020-05-11 17:18:04 -0700919
Neha Sharma8f4e4322020-08-06 10:51:53 +0000920 ports, err := dh.coreProxy.ListDevicePorts(log.WithSpanFromContext(context.Background(), ctx), dh.device.Id)
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400921 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700922 logger.Warnw(ctx, "failed-to-list-ports", log.Fields{"device-id": dh.device.Id, "err": err})
Kent Hagermanf1db18b2020-07-08 13:38:15 -0400923 continue
924 }
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530925 for _, port := range ports {
926 // NNI Stats
927 if port.Type == voltha.Port_ETHERNET_NNI {
928 intfID := PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI)
929 cmnni := dh.portStats.collectNNIMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000930 logger.Debugw(ctx, "collect-nni-metrics", log.Fields{"metrics": cmnni})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000931 go dh.portStats.publishMetrics(ctx, NNIStats, cmnni, port, dh.device.Id, dh.device.Type)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000932 logger.Debugw(ctx, "publish-nni-metrics", log.Fields{"nni-port": port.Label})
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530933 }
934 // PON Stats
935 if port.Type == voltha.Port_PON_OLT {
936 intfID := PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT)
937 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
938 cmpon := dh.portStats.collectPONMetrics(intfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000939 logger.Debugw(ctx, "collect-pon-metrics", log.Fields{"metrics": cmpon})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000940 go dh.portStats.publishMetrics(ctx, PONStats, cmpon, port, dh.device.Id, dh.device.Type)
Kishore Darapuaaf9c102020-05-04 13:06:57 +0530941 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000942 logger.Debugw(ctx, "publish-pon-metrics", log.Fields{"pon-port": port.Label})
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000943
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700944 onuGemInfoLst := dh.flowMgr[intfID].getOnuGemInfoList(ctx)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700945 if len(onuGemInfoLst) > 0 {
946 go dh.portStats.collectOnuAndGemStats(ctx, onuGemInfoLst)
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000947 }
Chaitrashree G Sef088112020-02-03 21:39:27 -0500948 }
Naga Manjunath7615e552019-10-11 22:35:47 +0530949 }
950 }
951 }
952}
953
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700954//AdoptDevice adopts the OLT device
npujarec5762e2020-01-01 14:08:48 +0530955func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400956 dh.transitionMap = NewTransitionMap(dh)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000957 logger.Infow(ctx, "adopt-device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
npujarec5762e2020-01-01 14:08:48 +0530958 dh.transitionMap.Handle(ctx, DeviceInit)
Naga Manjunath7615e552019-10-11 22:35:47 +0530959
960 // Now, set the initial PM configuration for that device
Kent Hagermane6ff1012020-07-14 15:07:53 -0400961 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.metrics.ToPmConfigs()); err != nil {
962 _ = olterrors.NewErrAdapter("error-updating-performance-metrics", log.Fields{"device-id": device.Id}, err).LogAt(log.ErrorLevel)
Naga Manjunath7615e552019-10-11 22:35:47 +0530963 }
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530964}
965
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700966//GetOfpDeviceInfo Gets the Ofp information of the given device
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530967func (dh *DeviceHandler) GetOfpDeviceInfo(device *voltha.Device) (*ic.SwitchCapability, error) {
cuilin20187b2a8c32019-03-26 19:52:28 -0700968 return &ic.SwitchCapability{
969 Desc: &of.OfpDesc{
Devmalya Paul70dd4972019-06-10 15:19:17 +0530970 MfrDesc: "VOLTHA Project",
cuilin20187b2a8c32019-03-26 19:52:28 -0700971 HwDesc: "open_pon",
972 SwDesc: "open_pon",
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700973 SerialNum: device.SerialNumber,
cuilin20187b2a8c32019-03-26 19:52:28 -0700974 },
975 SwitchFeatures: &of.OfpSwitchFeatures{
976 NBuffers: 256,
977 NTables: 2,
978 Capabilities: uint32(of.OfpCapabilities_OFPC_FLOW_STATS |
979 of.OfpCapabilities_OFPC_TABLE_STATS |
980 of.OfpCapabilities_OFPC_PORT_STATS |
981 of.OfpCapabilities_OFPC_GROUP_STATS),
982 },
983 }, nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +0530984}
985
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700986// GetInterAdapterTechProfileDownloadMessage fetches the TechProfileDownloadMessage for the caller.
987func (dh *DeviceHandler) GetInterAdapterTechProfileDownloadMessage(ctx context.Context, tpPath string, ponPortNum uint32, onuID uint32, uniID uint32) *ic.InterAdapterTechProfileDownloadMessage {
988 ifID, err := IntfIDFromPonPortNum(ctx, ponPortNum)
989 if err != nil {
990 return nil
991 }
992 return dh.flowMgr[ifID].getTechProfileDownloadMessage(ctx, tpPath, ifID, onuID, uniID)
993}
994
Neha Sharma96b7bf22020-06-15 10:37:32 +0000995func (dh *DeviceHandler) omciIndication(ctx context.Context, omciInd *oop.OmciIndication) error {
996 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 -0700997 var deviceType string
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700998 var deviceID string
999 var proxyDeviceID string
cuilin20187b2a8c32019-03-26 19:52:28 -07001000
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001001 transid := extractOmciTransactionID(omciInd.Pkt)
Matteo Scandolo92186242020-06-12 10:54:18 -07001002 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001003 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 -07001004 "omci-transaction-id": transid, "omci-msg": hex.EncodeToString(omciInd.Pkt)})
1005 }
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001006
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001007 onuKey := dh.formOnuKey(omciInd.IntfId, omciInd.OnuId)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301008
1009 if onuInCache, ok := dh.onus.Load(onuKey); !ok {
1010
Neha Sharma96b7bf22020-06-15 10:37:32 +00001011 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 -07001012 ponPort := IntfIDToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001013 kwargs := make(map[string]interface{})
1014 kwargs["onu_id"] = omciInd.OnuId
1015 kwargs["parent_port_no"] = ponPort
cuilin20187b2a8c32019-03-26 19:52:28 -07001016
Neha Sharma8f4e4322020-08-06 10:51:53 +00001017 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001018 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301019 return olterrors.NewErrNotFound("onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001020 "intf-id": omciInd.IntfId,
1021 "onu-id": omciInd.OnuId}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001022 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001023 deviceType = onuDevice.Type
1024 deviceID = onuDevice.Id
1025 proxyDeviceID = onuDevice.ProxyAddress.DeviceId
1026 //if not exist in cache, then add to cache.
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301027 dh.onus.Store(onuKey, NewOnuDevice(deviceID, deviceType, onuDevice.SerialNumber, omciInd.OnuId, omciInd.IntfId, proxyDeviceID, false))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001028 } else {
1029 //found in cache
Neha Sharma96b7bf22020-06-15 10:37:32 +00001030 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 +05301031 deviceType = onuInCache.(*OnuDevice).deviceType
1032 deviceID = onuInCache.(*OnuDevice).deviceID
1033 proxyDeviceID = onuInCache.(*OnuDevice).proxyDeviceID
cuilin20187b2a8c32019-03-26 19:52:28 -07001034 }
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001035
1036 omciMsg := &ic.InterAdapterOmciMessage{Message: omciInd.Pkt}
Neha Sharma8f4e4322020-08-06 10:51:53 +00001037 if err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx), omciMsg,
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001038 ic.InterAdapterMessageType_OMCI_RESPONSE, dh.openOLT.config.Topic, deviceType,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001039 deviceID, proxyDeviceID, ""); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301040 return olterrors.NewErrCommunication("omci-request", log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001041 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001042 "destination": deviceType,
1043 "onu-id": deviceID,
Girish Kumarf26e4882020-03-05 06:49:10 +00001044 "proxy-device-id": proxyDeviceID}, err)
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001045 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001046 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301047}
1048
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001049//ProcessInterAdapterMessage sends the proxied messages to the target device
1050// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
1051// is meant, and then send the unmarshalled omci message to this onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001052func (dh *DeviceHandler) ProcessInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
1053 logger.Debugw(ctx, "process-inter-adapter-message", log.Fields{"msgID": msg.Header.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001054 if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001055 return dh.handleInterAdapterOmciMsg(ctx, msg)
1056 }
1057 return olterrors.NewErrInvalidValue(log.Fields{"inter-adapter-message-type": msg.Header.Type}, nil)
1058}
cuilin20187b2a8c32019-03-26 19:52:28 -07001059
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001060func (dh *DeviceHandler) handleInterAdapterOmciMsg(ctx context.Context, msg *ic.InterAdapterMessage) error {
1061 msgID := msg.Header.Id
1062 fromTopic := msg.Header.FromTopic
1063 toTopic := msg.Header.ToTopic
1064 toDeviceID := msg.Header.ToDeviceId
1065 proxyDeviceID := msg.Header.ProxyDeviceId
cuilin20187b2a8c32019-03-26 19:52:28 -07001066
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001067 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 -07001068
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001069 msgBody := msg.GetBody()
1070
1071 omciMsg := &ic.InterAdapterOmciMessage{}
1072 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
1073 return olterrors.NewErrAdapter("cannot-unmarshal-omci-msg-body", log.Fields{"msgbody": msgBody}, err)
1074 }
1075
1076 if omciMsg.GetProxyAddress() == nil {
1077 onuDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, toDeviceID)
1078 if err != nil {
1079 return olterrors.NewErrNotFound("onu", log.Fields{
1080 "device-id": dh.device.Id,
1081 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001082 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001083 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 -07001084 if err := dh.sendProxiedOmciMessage(ctx, onuDevice, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001085 return olterrors.NewErrCommunication("send-failed", log.Fields{
1086 "device-id": dh.device.Id,
1087 "onu-device-id": toDeviceID}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001088 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001089 } else {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001090 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 -07001091 if err := dh.sendProxiedOmciMessage(ctx, nil, omciMsg); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001092 return olterrors.NewErrCommunication("send-failed", log.Fields{
1093 "device-id": dh.device.Id,
1094 "onu-device-id": toDeviceID}, err)
1095 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001096 }
1097 return nil
Phaneendra Manda4c62c802019-03-06 21:37:49 +05301098}
1099
Girish Gowdra7de58ac2021-07-20 15:09:25 -07001100func (dh *DeviceHandler) sendProxiedOmciMessage(ctx context.Context, onuDevice *voltha.Device, omciMsg *ic.InterAdapterOmciMessage) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001101 var intfID uint32
1102 var onuID uint32
Esin Karamanccb714b2019-11-29 15:02:06 +00001103 var connectStatus common.ConnectStatus_Types
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001104 if onuDevice != nil {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001105 intfID = onuDevice.ProxyAddress.GetChannelId()
1106 onuID = onuDevice.ProxyAddress.GetOnuId()
1107 connectStatus = onuDevice.ConnectStatus
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001108 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001109 intfID = omciMsg.GetProxyAddress().GetChannelId()
1110 onuID = omciMsg.GetProxyAddress().GetOnuId()
1111 connectStatus = omciMsg.GetConnectStatus()
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001112 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001113 if connectStatus != voltha.ConnectStatus_REACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001114 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 -08001115
Thomas Lee S94109f12020-03-03 16:39:29 +05301116 return olterrors.NewErrCommunication("unreachable", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001117 "intf-id": intfID,
1118 "onu-id": onuID}, nil)
cuilin20187b2a8c32019-03-26 19:52:28 -07001119 }
1120
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001121 // TODO: OpenOLT Agent oop.OmciMsg expects a hex encoded string for OMCI packets rather than the actual bytes.
1122 // Fix this in the agent and then we can pass byte array as Pkt: omciMsg.Message.
lcuie24ef182019-04-29 22:58:36 -07001123 var omciMessage *oop.OmciMsg
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001124 hexPkt := make([]byte, hex.EncodedLen(len(omciMsg.Message)))
1125 hex.Encode(hexPkt, omciMsg.Message)
1126 omciMessage = &oop.OmciMsg{IntfId: intfID, OnuId: onuID, Pkt: hexPkt}
1127
1128 // TODO: Below logging illustrates the "stringify" of the omci Pkt.
1129 // once above is fixed this log line can change to just use hex.EncodeToString(omciMessage.Pkt)
1130 transid := extractOmciTransactionID(omciMsg.Message)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001131 logger.Debugw(ctx, "sent-omci-msg", log.Fields{"intf-id": intfID, "onu-id": onuID,
Matt Jeanneretceea2e02020-03-27 14:19:57 -04001132 "omciTransactionID": transid, "omciMsg": string(omciMessage.Pkt)})
cuilin20187b2a8c32019-03-26 19:52:28 -07001133
Neha Sharma8f4e4322020-08-06 10:51:53 +00001134 _, err := dh.Client.OmciMsgOut(log.WithSpanFromContext(context.Background(), ctx), omciMessage)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001135 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301136 return olterrors.NewErrCommunication("omci-send-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001137 "intf-id": intfID,
1138 "onu-id": onuID,
1139 "message": omciMessage}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001140 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001141 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001142}
1143
David K. Bainbridge794735f2020-02-11 21:01:37 -08001144func (dh *DeviceHandler) activateONU(ctx context.Context, intfID uint32, onuID int64, serialNum *oop.SerialNumber, serialNumber string) error {
kesavand494c2082020-08-31 11:16:12 +05301145 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 -07001146 if err := dh.flowMgr[intfID].UpdateOnuInfo(ctx, intfID, uint32(onuID), serialNumber); err != nil {
Matteo Scandolo92186242020-06-12 10:54:18 -07001147 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": onuID, "intf-id": intfID}, err)
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001148 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001149 var pir uint32 = 1000000
kesavand494c2082020-08-31 11:16:12 +05301150 Onu := oop.Onu{IntfId: intfID, OnuId: uint32(onuID), SerialNumber: serialNum, Pir: pir, OmccEncryption: dh.openOLT.config.OmccEncryption}
npujarec5762e2020-01-01 14:08:48 +05301151 if _, err := dh.Client.ActivateOnu(ctx, &Onu); err != nil {
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001152 st, _ := status.FromError(err)
1153 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001154 logger.Debugw(ctx, "onu-activation-in-progress", log.Fields{"SerialNumber": serialNumber, "onu-id": onuID, "device-id": dh.device.Id})
1155
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001156 } else {
Thomas Lee S985938d2020-05-04 11:40:41 +05301157 return olterrors.NewErrAdapter("onu-activate-failed", log.Fields{"onu": Onu, "device-id": dh.device.Id}, err)
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001158 }
cuilin20187b2a8c32019-03-26 19:52:28 -07001159 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001160 logger.Infow(ctx, "activated-onu", log.Fields{"SerialNumber": serialNumber, "device-id": dh.device.Id})
cuilin20187b2a8c32019-03-26 19:52:28 -07001161 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001162 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001163}
1164
Mahir Gunyelb0046752021-02-26 13:51:05 -08001165func (dh *DeviceHandler) onuDiscIndication(ctx context.Context, onuDiscInd *oop.OnuDiscIndication) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001166 channelID := onuDiscInd.GetIntfId()
1167 parentPortNo := IntfIDToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
Matt Jeanneret53539512019-07-20 14:47:02 -04001168
Mahir Gunyelb0046752021-02-26 13:51:05 -08001169 sn := dh.stringifySerialNumber(onuDiscInd.SerialNumber)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001170 logger.Infow(ctx, "new-discovery-indication", log.Fields{"sn": sn})
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301171
cuilin20187b2a8c32019-03-26 19:52:28 -07001172 kwargs := make(map[string]interface{})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001173 if sn != "" {
1174 kwargs["serial_number"] = sn
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001175 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001176 return olterrors.NewErrInvalidValue(log.Fields{"serial-number": sn}, nil)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001177 }
1178
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301179 var alarmInd oop.OnuAlarmIndication
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001180 raisedTs := time.Now().Unix()
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001181 if _, loaded := dh.discOnus.LoadOrStore(sn, true); loaded {
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301182
1183 /* When PON cable disconnected and connected back from OLT, it was expected OnuAlarmIndication
1184 with "los_status: off" should be raised but BAL does not raise this Alarm hence manually sending
1185 OnuLosClear event on receiving OnuDiscoveryIndication for the Onu after checking whether
1186 OnuLosRaise event sent for it */
1187 dh.onus.Range(func(Onukey interface{}, onuInCache interface{}) bool {
1188 if onuInCache.(*OnuDevice).serialNumber == sn && onuInCache.(*OnuDevice).losRaised {
1189 if onuDiscInd.GetIntfId() != onuInCache.(*OnuDevice).intfID {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001190 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301191 "previousIntfId": onuInCache.(*OnuDevice).intfID,
1192 "currentIntfId": onuDiscInd.GetIntfId()})
1193 // TODO:: Should we need to ignore raising OnuLosClear event
1194 // when onu connected to different PON?
1195 }
1196 alarmInd.IntfId = onuInCache.(*OnuDevice).intfID
1197 alarmInd.OnuId = onuInCache.(*OnuDevice).onuID
1198 alarmInd.LosStatus = statusCheckOff
Kent Hagermane6ff1012020-07-14 15:07:53 -04001199 go func() {
1200 if err := dh.eventMgr.onuAlarmIndication(ctx, &alarmInd, onuInCache.(*OnuDevice).deviceID, raisedTs); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001201 logger.Debugw(ctx, "indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001202 }
1203 }()
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301204 }
1205 return true
1206 })
1207
Neha Sharma96b7bf22020-06-15 10:37:32 +00001208 logger.Warnw(ctx, "onu-sn-is-already-being-processed", log.Fields{"sn": sn})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001209 return nil
Amit Ghoshe5c6a852020-02-10 15:09:46 +00001210 }
1211
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001212 var onuID uint32
Matteo Scandolo945e4012019-12-12 14:16:11 -08001213
1214 // check the ONU is already know to the OLT
1215 // NOTE the second time the ONU is discovered this should return a device
1216 onuDevice, err := dh.coreProxy.GetChildDevice(ctx, dh.device.Id, kwargs)
1217
1218 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001219 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 -08001220 if e, ok := status.FromError(err); ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001221 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 -08001222 switch e.Code() {
1223 case codes.Internal:
1224 // this probably means NOT FOUND, so just create a new device
1225 onuDevice = nil
1226 case codes.DeadlineExceeded:
1227 // if the call times out, cleanup and exit
1228 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001229 return olterrors.NewErrTimeout("get-child-device", log.Fields{"device-id": dh.device.Id}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001230 }
1231 }
1232 }
1233
1234 if onuDevice == nil {
1235 // NOTE this should happen a single time, and only if GetChildDevice returns NotFound
Neha Sharma96b7bf22020-06-15 10:37:32 +00001236 logger.Debugw(ctx, "creating-new-onu", log.Fields{"sn": sn})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001237 // we need to create a new ChildDevice
Matt Jeanneret53539512019-07-20 14:47:02 -04001238 ponintfid := onuDiscInd.GetIntfId()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001239 onuID, err = dh.resourceMgr[ponintfid].GetONUID(ctx, ponintfid)
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001240
Neha Sharma96b7bf22020-06-15 10:37:32 +00001241 logger.Infow(ctx, "creating-new-onu-got-onu-id", log.Fields{"sn": sn, "onuId": onuID})
Matteo Scandolo945e4012019-12-12 14:16:11 -08001242
1243 if err != nil {
1244 // if we can't create an ID in resource manager,
1245 // cleanup and exit
Matteo Scandolo945e4012019-12-12 14:16:11 -08001246 dh.discOnus.Delete(sn)
Girish Kumarf26e4882020-03-05 06:49:10 +00001247 return olterrors.NewErrAdapter("resource-manager-get-onu-id-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001248 "pon-intf-id": ponintfid,
1249 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001250 }
1251
Neha Sharma8f4e4322020-08-06 10:51:53 +00001252 if onuDevice, err = dh.coreProxy.ChildDeviceDetected(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, int(parentPortNo),
Matteo Scandolo945e4012019-12-12 14:16:11 -08001253 "", int(channelID), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuID)); err != nil {
Matteo Scandolo945e4012019-12-12 14:16:11 -08001254 dh.discOnus.Delete(sn)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001255 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 +05301256 return olterrors.NewErrAdapter("core-proxy-child-device-detected-failed", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001257 "pon-intf-id": ponintfid,
1258 "serial-number": sn}, err)
Matteo Scandolo945e4012019-12-12 14:16:11 -08001259 }
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001260 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 -07001261 logger.Warnw(ctx, "discovery-indication-failed", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001262 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001263 logger.Infow(ctx, "onu-child-device-added",
Shrey Baid807a2a02020-04-09 12:52:45 +05301264 log.Fields{"onuDevice": onuDevice,
1265 "sn": sn,
Matteo Scandolo92186242020-06-12 10:54:18 -07001266 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301267 "device-id": dh.device.Id})
Chaitrashree G Sbe6ab942019-05-24 06:42:49 -04001268 }
Matteo Scandolo945e4012019-12-12 14:16:11 -08001269
1270 // we can now use the existing ONU Id
1271 onuID = onuDevice.ProxyAddress.OnuId
Mahir Gunyele77977b2019-06-27 05:36:22 -07001272 //Insert the ONU into cache to use in OnuIndication.
1273 //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 +00001274 logger.Debugw(ctx, "onu-discovery-indication-key-create",
Matteo Scandolo92186242020-06-12 10:54:18 -07001275 log.Fields{"onu-id": onuID,
Shrey Baid807a2a02020-04-09 12:52:45 +05301276 "intfId": onuDiscInd.GetIntfId(),
1277 "sn": sn})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001278 onuKey := dh.formOnuKey(onuDiscInd.GetIntfId(), onuID)
Matt Jeanneret53539512019-07-20 14:47:02 -04001279
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301280 onuDev := NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuID, onuDiscInd.GetIntfId(), onuDevice.ProxyAddress.DeviceId, false)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301281 dh.onus.Store(onuKey, onuDev)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001282 logger.Debugw(ctx, "new-onu-device-discovered",
Shrey Baid807a2a02020-04-09 12:52:45 +05301283 log.Fields{"onu": onuDev,
1284 "sn": sn})
Chaitrashree G S35b5d802019-07-08 23:12:03 -04001285
Kent Hagermane6ff1012020-07-14 15:07:53 -04001286 if err := dh.coreProxy.DeviceStateUpdate(ctx, onuDevice.Id, common.ConnectStatus_REACHABLE, common.OperStatus_DISCOVERED); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301287 return olterrors.NewErrAdapter("failed-to-update-device-state", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001288 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001289 "serial-number": sn}, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001290 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001291 logger.Infow(ctx, "onu-discovered-reachable", log.Fields{"device-id": onuDevice.Id, "sn": sn})
Kent Hagermane6ff1012020-07-14 15:07:53 -04001292 if err := dh.activateONU(ctx, onuDiscInd.IntfId, int64(onuID), onuDiscInd.SerialNumber, sn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301293 return olterrors.NewErrAdapter("onu-activation-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001294 "device-id": onuDevice.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00001295 "serial-number": sn}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001296 }
1297 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001298}
1299
Mahir Gunyelb0046752021-02-26 13:51:05 -08001300func (dh *DeviceHandler) onuIndication(ctx context.Context, onuInd *oop.OnuIndication) error {
cuilin20187b2a8c32019-03-26 19:52:28 -07001301
1302 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001303 ponPort := IntfIDToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
Mahir Gunyele77977b2019-06-27 05:36:22 -07001304 var onuDevice *voltha.Device
David K. Bainbridge794735f2020-02-11 21:01:37 -08001305 var err error
Mahir Gunyele77977b2019-06-27 05:36:22 -07001306 foundInCache := false
Neha Sharma96b7bf22020-06-15 10:37:32 +00001307 logger.Debugw(ctx, "onu-indication-key-create",
Shrey Baid807a2a02020-04-09 12:52:45 +05301308 log.Fields{"onuId": onuInd.OnuId,
1309 "intfId": onuInd.GetIntfId(),
Thomas Lee S985938d2020-05-04 11:40:41 +05301310 "device-id": dh.device.Id})
Mahir Gunyele77977b2019-06-27 05:36:22 -07001311 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.OnuId)
Mahir Gunyelb0046752021-02-26 13:51:05 -08001312 serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301313
David K. Bainbridge794735f2020-02-11 21:01:37 -08001314 errFields := log.Fields{"device-id": dh.device.Id}
1315
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301316 if onuInCache, ok := dh.onus.Load(onuKey); ok {
1317
Mahir Gunyele77977b2019-06-27 05:36:22 -07001318 //If ONU id is discovered before then use GetDevice to get onuDevice because it is cheaper.
1319 foundInCache = true
David K. Bainbridge794735f2020-02-11 21:01:37 -08001320 errFields["onu-id"] = onuInCache.(*OnuDevice).deviceID
Kent Hagermane6ff1012020-07-14 15:07:53 -04001321 onuDevice, err = dh.coreProxy.GetDevice(ctx, dh.device.Id, onuInCache.(*OnuDevice).deviceID)
cuilin20187b2a8c32019-03-26 19:52:28 -07001322 } else {
Mahir Gunyele77977b2019-06-27 05:36:22 -07001323 //If ONU not found in adapter cache then we have to use GetChildDevice to get onuDevice
1324 if serialNumber != "" {
1325 kwargs["serial_number"] = serialNumber
David K. Bainbridge794735f2020-02-11 21:01:37 -08001326 errFields["serial-number"] = serialNumber
Mahir Gunyele77977b2019-06-27 05:36:22 -07001327 } else {
1328 kwargs["onu_id"] = onuInd.OnuId
1329 kwargs["parent_port_no"] = ponPort
David K. Bainbridge794735f2020-02-11 21:01:37 -08001330 errFields["onu-id"] = onuInd.OnuId
1331 errFields["parent-port-no"] = ponPort
Mahir Gunyele77977b2019-06-27 05:36:22 -07001332 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001333 onuDevice, err = dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
cuilin20187b2a8c32019-03-26 19:52:28 -07001334 }
Mahir Gunyele77977b2019-06-27 05:36:22 -07001335
David K. Bainbridge794735f2020-02-11 21:01:37 -08001336 if err != nil || onuDevice == nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001337 return olterrors.NewErrNotFound("onu-device", errFields, err)
cuilin20187b2a8c32019-03-26 19:52:28 -07001338 }
1339
David K. Bainbridge794735f2020-02-11 21:01:37 -08001340 if onuDevice.ParentPortNo != ponPort {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001341 logger.Warnw(ctx, "onu-is-on-a-different-intf-id-now", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001342 "previousIntfId": onuDevice.ParentPortNo,
1343 "currentIntfId": ponPort})
1344 }
1345
1346 if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001347 logger.Warnw(ctx, "onu-id-mismatch-possible-if-voltha-and-olt-rebooted", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301348 "expected-onu-id": onuDevice.ProxyAddress.OnuId,
1349 "received-onu-id": onuInd.OnuId,
Thomas Lee S985938d2020-05-04 11:40:41 +05301350 "device-id": dh.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001351 }
1352 if !foundInCache {
1353 onuKey := dh.formOnuKey(onuInd.GetIntfId(), onuInd.GetOnuId())
1354
Thiyagarajan Subramani34a00282020-03-10 20:19:31 +05301355 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 -08001356
1357 }
kesavand7cf3a052020-08-28 12:49:18 +05301358 if onuInd.OperState == "down" && onuInd.FailReason != oop.OnuIndication_ONU_ACTIVATION_FAIL_REASON_NONE {
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07001359 if err := dh.eventMgr.onuActivationIndication(ctx, onuActivationFailEvent, onuInd, dh.device.Id, time.Now().Unix()); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001360 logger.Warnw(ctx, "onu-activation-indication-reporting-failed", log.Fields{"err": err})
kesavand7cf3a052020-08-28 12:49:18 +05301361 }
1362 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001363 if err := dh.updateOnuStates(ctx, onuDevice, onuInd); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001364 return olterrors.NewErrCommunication("state-update-failed", errFields, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001365 }
1366 return nil
cuilin20187b2a8c32019-03-26 19:52:28 -07001367}
1368
Neha Sharma96b7bf22020-06-15 10:37:32 +00001369func (dh *DeviceHandler) updateOnuStates(ctx context.Context, onuDevice *voltha.Device, onuInd *oop.OnuIndication) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001370 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 -07001371 if onuInd.AdminState == "down" || onuInd.OperState == "down" {
1372 // The ONU has gone admin_state "down" or oper_state "down" - we expect the ONU to send discovery again
1373 // The ONU admin_state is "up" while "oper_state" is down in cases where ONU activation fails. In this case
1374 // the ONU sends Discovery again.
Girish Gowdra429f9502020-05-04 13:22:16 -07001375 dh.discOnus.Delete(onuDevice.SerialNumber)
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001376 // Tests have shown that we sometimes get OperState as NOT down even if AdminState is down, forcing it
1377 if onuInd.OperState != "down" {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001378 logger.Warnw(ctx, "onu-admin-state-down", log.Fields{"operState": onuInd.OperState})
Amit Ghosh9bbc5652020-02-17 13:37:32 +00001379 onuInd.OperState = "down"
1380 }
1381 }
1382
David K. Bainbridge794735f2020-02-11 21:01:37 -08001383 switch onuInd.OperState {
1384 case "down":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001385 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 -07001386 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301387 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001388 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001389 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301390 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001391 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001392 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001393 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001394 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001395 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001396 case "up":
Neha Sharma96b7bf22020-06-15 10:37:32 +00001397 logger.Debugw(ctx, "sending-interadapter-onu-indication", log.Fields{"onuIndication": onuInd, "device-id": onuDevice.Id, "operStatus": onuDevice.OperStatus, "adminStatus": onuDevice.AdminState})
Matt Jeanneret53539512019-07-20 14:47:02 -04001398 // TODO NEW CORE do not hardcode adapter name. Handler needs Adapter reference
npujarec5762e2020-01-01 14:08:48 +05301399 err := dh.AdapterProxy.SendInterAdapterMessage(ctx, onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001400 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001401 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301402 return olterrors.NewErrCommunication("inter-adapter-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001403 "onu-indicator": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001404 "source": dh.openOLT.config.Topic,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001405 "device-type": onuDevice.Type,
Girish Kumarf26e4882020-03-05 06:49:10 +00001406 "device-id": onuDevice.Id}, err)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001407 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001408 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001409 return olterrors.NewErrInvalidValue(log.Fields{"oper-state": onuInd.OperState}, nil)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001410 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001411 return nil
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001412}
1413
cuilin20187b2a8c32019-03-26 19:52:28 -07001414func (dh *DeviceHandler) stringifySerialNumber(serialNum *oop.SerialNumber) string {
1415 if serialNum != nil {
1416 return string(serialNum.VendorId) + dh.stringifyVendorSpecific(serialNum.VendorSpecific)
cuilin20187b2a8c32019-03-26 19:52:28 -07001417 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001418 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001419}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001420func (dh *DeviceHandler) deStringifySerialNumber(serialNum string) (*oop.SerialNumber, error) {
1421 decodedStr, err := hex.DecodeString(serialNum[4:])
1422 if err != nil {
1423 return nil, err
1424 }
1425 return &oop.SerialNumber{
1426 VendorId: []byte(serialNum[:4]),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001427 VendorSpecific: decodedStr,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001428 }, nil
1429}
cuilin20187b2a8c32019-03-26 19:52:28 -07001430
1431func (dh *DeviceHandler) stringifyVendorSpecific(vendorSpecific []byte) string {
Mahir Gunyelb0046752021-02-26 13:51:05 -08001432 if len(vendorSpecific) > 3 {
1433 tmp := fmt.Sprintf("%x", (uint32(vendorSpecific[0])>>4)&0x0f) +
1434 fmt.Sprintf("%x", uint32(vendorSpecific[0]&0x0f)) +
1435 fmt.Sprintf("%x", (uint32(vendorSpecific[1])>>4)&0x0f) +
1436 fmt.Sprintf("%x", (uint32(vendorSpecific[1]))&0x0f) +
1437 fmt.Sprintf("%x", (uint32(vendorSpecific[2])>>4)&0x0f) +
1438 fmt.Sprintf("%x", (uint32(vendorSpecific[2]))&0x0f) +
1439 fmt.Sprintf("%x", (uint32(vendorSpecific[3])>>4)&0x0f) +
1440 fmt.Sprintf("%x", (uint32(vendorSpecific[3]))&0x0f)
1441 return tmp
1442 }
1443 return ""
cuilin20187b2a8c32019-03-26 19:52:28 -07001444}
1445
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001446//UpdateFlowsBulk upates the bulk flow
1447func (dh *DeviceHandler) UpdateFlowsBulk() error {
Thomas Lee S94109f12020-03-03 16:39:29 +05301448 return olterrors.ErrNotImplemented
cuilin20187b2a8c32019-03-26 19:52:28 -07001449}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001450
1451//GetChildDevice returns the child device for given parent port and onu id
Neha Sharma96b7bf22020-06-15 10:37:32 +00001452func (dh *DeviceHandler) GetChildDevice(ctx context.Context, parentPort, onuID uint32) (*voltha.Device, error) {
1453 logger.Debugw(ctx, "getchilddevice",
Shrey Baid807a2a02020-04-09 12:52:45 +05301454 log.Fields{"pon-port": parentPort,
Matteo Scandolo92186242020-06-12 10:54:18 -07001455 "onu-id": onuID,
Thomas Lee S985938d2020-05-04 11:40:41 +05301456 "device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001457 kwargs := make(map[string]interface{})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001458 kwargs["onu_id"] = onuID
Girish Gowdru0c588b22019-04-23 23:24:56 -04001459 kwargs["parent_port_no"] = parentPort
Neha Sharma8f4e4322020-08-06 10:51:53 +00001460 onuDevice, err := dh.coreProxy.GetChildDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, kwargs)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001461 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001462 return nil, olterrors.NewErrNotFound("onu-device", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001463 "intf-id": parentPort,
1464 "onu-id": onuID}, err)
Girish Gowdru0c588b22019-04-23 23:24:56 -04001465 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001466 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 -08001467 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301468}
1469
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001470// SendPacketInToCore sends packet-in to core
1471// For this, it calls SendPacketIn of the core-proxy which uses a device specific topic to send the request.
1472// The adapter handling the device creates a device specific topic
Neha Sharma96b7bf22020-06-15 10:37:32 +00001473func (dh *DeviceHandler) SendPacketInToCore(ctx context.Context, logicalPort uint32, packetPayload []byte) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001474 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001475 logger.Debugw(ctx, "send-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001476 "port": logicalPort,
1477 "packet": hex.EncodeToString(packetPayload),
1478 "device-id": dh.device.Id,
1479 })
1480 }
Neha Sharma8f4e4322020-08-06 10:51:53 +00001481 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 +05301482 return olterrors.NewErrCommunication("packet-send-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001483 "source": "adapter",
1484 "destination": "core",
1485 "device-id": dh.device.Id,
1486 "logical-port": logicalPort,
Girish Kumarf26e4882020-03-05 06:49:10 +00001487 "packet": hex.EncodeToString(packetPayload)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001488 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001489 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001490 logger.Debugw(ctx, "sent-packet-in-to-core-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001491 "packet": hex.EncodeToString(packetPayload),
1492 "device-id": dh.device.Id,
1493 })
1494 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001495 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001496}
1497
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001498// UpdatePmConfig updates the pm metrics.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001499func (dh *DeviceHandler) UpdatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001500 logger.Infow(ctx, "update-pm-configs", log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs})
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001501
1502 if pmConfigs.DefaultFreq != dh.metrics.ToPmConfigs().DefaultFreq {
1503 dh.metrics.UpdateFrequency(pmConfigs.DefaultFreq)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001504 logger.Debugf(ctx, "frequency-updated")
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001505 }
1506
Kent Hagermane6ff1012020-07-14 15:07:53 -04001507 if !pmConfigs.Grouped {
Rohan Agrawalda5e0b22020-05-20 11:10:26 +00001508 metrics := dh.metrics.GetSubscriberMetrics()
1509 for _, m := range pmConfigs.Metrics {
1510 metrics[m.Name].Enabled = m.Enabled
1511
1512 }
1513 }
1514}
1515
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001516//UpdateFlowsIncrementally updates the device flow
npujarec5762e2020-01-01 14:08:48 +05301517func (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 +00001518 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 +01001519
Girish Gowdra491a9c62021-01-06 16:43:07 -08001520 var err error
Andrea Campanellac63bba92020-03-10 17:01:04 +01001521 var errorsList []error
1522
Girish Gowdru0c588b22019-04-23 23:24:56 -04001523 if flows != nil {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001524 for _, flow := range flows.ToRemove.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001525 ponIf := dh.getPonIfFromFlow(flow)
Girish Gowdracefae192020-03-19 18:14:10 -07001526
Neha Sharma96b7bf22020-06-15 10:37:32 +00001527 logger.Debugw(ctx, "removing-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301528 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001529 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301530 "flowToRemove": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001531 if flow_utils.HasGroup(flow) {
1532 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupRemove)
1533 } else {
1534 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, false, nil)
1535 }
Girish Gowdracefae192020-03-19 18:14:10 -07001536 if err != nil {
1537 errorsList = append(errorsList, err)
1538 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001539 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301540
1541 for _, flow := range flows.ToAdd.Items {
Girish Gowdrafb3d6102020-10-16 16:32:36 -07001542 ponIf := dh.getPonIfFromFlow(flow)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001543 logger.Debugw(ctx, "adding-flow",
Shrey Baid807a2a02020-04-09 12:52:45 +05301544 log.Fields{"device-id": device.Id,
Girish Gowdra9602eb42020-09-09 15:50:39 -07001545 "ponIf": ponIf,
Shrey Baid807a2a02020-04-09 12:52:45 +05301546 "flowToAdd": flow})
Girish Gowdra491a9c62021-01-06 16:43:07 -08001547 if flow_utils.HasGroup(flow) {
1548 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, flow, nil, McastFlowOrGroupAdd)
1549 } else {
1550 err = dh.flowMgr[ponIf].RouteFlowToOnuChannel(ctx, flow, true, flowMetadata)
1551 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001552 if err != nil {
1553 errorsList = append(errorsList, err)
1554 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301555 }
Girish Gowdru0c588b22019-04-23 23:24:56 -04001556 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001557
Girish Gowdracefae192020-03-19 18:14:10 -07001558 // 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 +00001559 if groups != nil {
1560 for _, group := range groups.ToAdd.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001561 // err = dh.groupMgr.AddGroup(ctx, group)
1562 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupAdd)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001563 if err != nil {
1564 errorsList = append(errorsList, err)
1565 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001566 }
1567 for _, group := range groups.ToUpdate.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001568 // err = dh.groupMgr.ModifyGroup(ctx, group)
1569 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupModify)
Andrea Campanellac63bba92020-03-10 17:01:04 +01001570 if err != nil {
1571 errorsList = append(errorsList, err)
1572 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001573 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001574 for _, group := range groups.ToRemove.Items {
Girish Gowdra491a9c62021-01-06 16:43:07 -08001575 // err = dh.groupMgr.DeleteGroup(ctx, group)
1576 err = dh.RouteMcastFlowOrGroupMsgToChannel(ctx, nil, group, McastFlowOrGroupRemove)
Esin Karamand519bbf2020-07-01 11:16:03 +00001577 if err != nil {
1578 errorsList = append(errorsList, err)
1579 }
Esin Karamanccb714b2019-11-29 15:02:06 +00001580 }
1581 }
Andrea Campanellac63bba92020-03-10 17:01:04 +01001582 if len(errorsList) > 0 {
1583 return fmt.Errorf("errors-installing-flows-groups, errors:%v", errorsList)
1584 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001585 logger.Debugw(ctx, "updated-flows-incrementally-successfully", log.Fields{"device-id": dh.device.Id})
Girish Gowdru0c588b22019-04-23 23:24:56 -04001586 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301587}
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001588
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001589//DisableDevice disables the given device
1590//It marks the following for the given device:
1591//Device-Handler Admin-State : down
1592//Device Port-State: UNKNOWN
1593//Device Oper-State: UNKNOWN
Neha Sharma96b7bf22020-06-15 10:37:32 +00001594func (dh *DeviceHandler) DisableDevice(ctx context.Context, device *voltha.Device) error {
Chaitrashree G S44124192019-08-07 20:21:36 -04001595 /* On device disable ,admin state update has to be done prior sending request to agent since
1596 the indication thread may processes invalid indications of ONU and OLT*/
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001597 if dh.Client != nil {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001598 if _, err := dh.Client.DisableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001599 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001600 return olterrors.NewErrAdapter("olt-disable-failed", log.Fields{"device-id": device.Id}, err)
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001601 }
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001602 }
Chaitrashree G S44124192019-08-07 20:21:36 -04001603 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001604 logger.Debugw(ctx, "olt-disabled", log.Fields{"device-id": device.Id})
Chaitrashree G S44124192019-08-07 20:21:36 -04001605 /* Discovered ONUs entries need to be cleared , since on device disable the child devices goes to
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001606 UNREACHABLE state which needs to be configured again*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301607
1608 dh.discOnus = sync.Map{}
1609 dh.onus = sync.Map{}
1610
Thomas Lee S85f37312020-04-03 17:06:12 +05301611 //stopping the stats collector
1612 dh.stopCollector <- true
1613
Neha Sharma96b7bf22020-06-15 10:37:32 +00001614 go dh.notifyChildDevices(ctx, "unreachable")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001615 cloned := proto.Clone(device).(*voltha.Device)
Thomas Lee S985938d2020-05-04 11:40:41 +05301616 //Update device Admin state
1617 dh.device = cloned
kdarapu1afeceb2020-02-12 01:38:09 -05001618 // 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 +00001619 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 -04001620 return olterrors.NewErrAdapter("ports-state-update-failed", log.Fields{"device-id": device.Id}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001621 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001622 logger.Debugw(ctx, "disable-device-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001623 return nil
1624}
1625
Neha Sharma96b7bf22020-06-15 10:37:32 +00001626func (dh *DeviceHandler) notifyChildDevices(ctx context.Context, state string) {
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001627 // Update onu state as unreachable in onu adapter
1628 onuInd := oop.OnuIndication{}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301629 onuInd.OperState = state
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001630 //get the child device for the parent device
Neha Sharma8f4e4322020-08-06 10:51:53 +00001631 onuDevices, err := dh.coreProxy.GetChildDevices(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id)
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001632 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001633 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 -04001634 }
1635 if onuDevices != nil {
1636 for _, onuDevice := range onuDevices.Items {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001637 err := dh.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.TODO(), ctx), &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001638 dh.openOLT.config.Topic, onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001639 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001640 logger.Errorw(ctx, "failed-to-send-inter-adapter-message", log.Fields{"OnuInd": onuInd,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001641 "From Adapter": dh.openOLT.config.Topic, "DeviceType": onuDevice.Type, "device-id": onuDevice.Id})
Chaitrashree G S3b4c0352019-09-09 20:59:29 -04001642 }
1643
1644 }
1645 }
1646
1647}
1648
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001649//ReenableDevice re-enables the olt device after disable
1650//It marks the following for the given device:
1651//Device-Handler Admin-State : up
1652//Device Port-State: ACTIVE
1653//Device Oper-State: ACTIVE
Neha Sharma96b7bf22020-06-15 10:37:32 +00001654func (dh *DeviceHandler) ReenableDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001655 if _, err := dh.Client.ReenableOlt(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301656 if e, ok := status.FromError(err); ok && e.Code() == codes.Internal {
Girish Kumarf26e4882020-03-05 06:49:10 +00001657 return olterrors.NewErrAdapter("olt-reenable-failed", log.Fields{"device-id": dh.device.Id}, err)
Abhilash Laxmeshwar5b302e12020-01-09 15:15:14 +05301658 }
1659 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001660 logger.Debug(ctx, "olt-reenabled")
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001661
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001662 // Update the all ports state on that device to enable
kesavand39e0aa32020-01-28 20:58:50 -05001663
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001664 ports, err := dh.coreProxy.ListDevicePorts(ctx, device.Id)
1665 if err != nil {
divyadesai3af43e12020-08-18 07:10:54 +00001666 return olterrors.NewErrAdapter("list-ports-failed", log.Fields{"device-id": device.Id}, err)
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001667 }
1668 if err := dh.disableAdminDownPorts(ctx, ports); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001669 return olterrors.NewErrAdapter("port-status-update-failed-after-olt-reenable", log.Fields{"device": device}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001670 }
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001671 //Update the device oper status as ACTIVE
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001672 device.OperStatus = voltha.OperStatus_ACTIVE
1673 dh.device = device
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001674
Neha Sharma8f4e4322020-08-06 10:51:53 +00001675 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 +05301676 return olterrors.NewErrAdapter("state-update-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001677 "device-id": device.Id,
Kent Hagermanf1db18b2020-07-08 13:38:15 -04001678 "connect-status": device.ConnectStatus,
1679 "oper-status": device.OperStatus}, err)
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001680 }
kesavand39e0aa32020-01-28 20:58:50 -05001681
Neha Sharma96b7bf22020-06-15 10:37:32 +00001682 logger.Debugw(ctx, "reenabledevice-end", log.Fields{"device-id": device.Id})
Girish Gowdru5ba46c92019-04-25 05:00:05 -04001683
1684 return nil
1685}
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001686
npujarec5762e2020-01-01 14:08:48 +05301687func (dh *DeviceHandler) clearUNIData(ctx context.Context, onu *rsrcMgr.OnuGemInfo) error {
Devmalya Paul495b94a2019-08-27 19:42:00 -04001688 var uniID uint32
1689 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301690 for _, port := range onu.UniPorts {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001691 uniID = UniIDFromPortNum(port)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001692 logger.Debugw(ctx, "clearing-resource-data-for-uni-port", log.Fields{"port": port, "uni-id": uniID})
A R Karthick1f85b802019-10-11 05:06:05 +00001693 /* Delete tech-profile instance from the KV store */
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001694 if err = dh.flowMgr[onu.IntfID].DeleteTechProfileInstances(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001695 logger.Debugw(ctx, "failed-to-remove-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001696 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001697 logger.Debugw(ctx, "deleted-tech-profile-instance-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001698 tpIDList := dh.resourceMgr[onu.IntfID].GetTechProfileIDForOnu(ctx, onu.IntfID, onu.OnuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +00001699 for _, tpID := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001700 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "upstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001701 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001702 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001703 logger.Debugw(ctx, "removed-meter-id-for-onu-upstream", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001704 if err = dh.resourceMgr[onu.IntfID].RemoveMeterInfoForOnu(ctx, "downstream", onu.IntfID, onu.OnuID, uniID, tpID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001705 logger.Debugw(ctx, "failed-to-remove-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Gamze Abakafee36392019-10-03 11:17:24 +00001706 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001707 logger.Debugw(ctx, "removed-meter-id-for-onu-downstream", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301708 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001709 dh.resourceMgr[onu.IntfID].FreePONResourcesForONU(ctx, onu.IntfID, onu.OnuID, uniID)
1710 if err = dh.resourceMgr[onu.IntfID].RemoveTechProfileIDsForOnu(ctx, onu.IntfID, onu.OnuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001711 logger.Debugw(ctx, "failed-to-remove-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301712 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001713 logger.Debugw(ctx, "removed-tech-profile-id-for-onu", log.Fields{"onu-id": onu.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001714 if err = dh.resourceMgr[onu.IntfID].DeletePacketInGemPortForOnu(ctx, onu.IntfID, onu.OnuID, port); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001715 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 +00001716 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001717 }
1718 return nil
1719}
1720
Devmalya Paul495b94a2019-08-27 19:42:00 -04001721// 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 +05301722func (dh *DeviceHandler) DeleteDevice(ctx context.Context, device *voltha.Device) error {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001723 logger.Debugw(ctx, "function-entry-delete-device", log.Fields{"device-id": dh.device.Id})
Devmalya Paul495b94a2019-08-27 19:42:00 -04001724 /* Clear the KV store data associated with the all the UNI ports
1725 This clears up flow data and also resource map data for various
1726 other pon resources like alloc_id and gemport_id
1727 */
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001728 dh.cleanupDeviceResources(ctx)
1729 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 -04001730 // Stop the Stats collector
1731 dh.stopCollector <- true
1732 // stop the heartbeat check routine
1733 dh.stopHeartbeatCheck <- true
Himani Chawla49a5d562020-11-25 11:53:44 +05301734 dh.lockDevice.RLock()
1735 // Stop the read indication only if it the routine is active
1736 if dh.isReadIndicationRoutineActive {
1737 dh.stopIndications <- true
1738 }
1739 dh.lockDevice.RUnlock()
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001740 dh.removeOnuIndicationChannels(ctx)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001741 //Reset the state
1742 if dh.Client != nil {
1743 if _, err := dh.Client.Reboot(ctx, new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301744 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001745 }
1746 }
Girish Gowdrab1caa442020-10-19 12:24:39 -07001747 // There is no need to update the core about operation status and connection status of the OLT.
1748 // The OLT is getting deleted anyway and the core might have already cleared the OLT device from its DB.
1749 // So any attempt to update the operation status and connection status of the OLT will result in core throwing an error back,
1750 // because the device does not exist in DB.
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001751
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001752 return nil
1753}
Kent Hagermane6ff1012020-07-14 15:07:53 -04001754func (dh *DeviceHandler) cleanupDeviceResources(ctx context.Context) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001755
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001756 if dh.resourceMgr != nil {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301757 var ponPort uint32
Girish Gowdra9602eb42020-09-09 15:50:39 -07001758 for ponPort = 0; ponPort < dh.totalPonPorts; ponPort++ {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001759 var err error
Girish Gowdrabcf98af2021-07-01 08:24:42 -07001760 onuGemData := dh.flowMgr[ponPort].getOnuGemInfoList(ctx)
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001761 for i, onu := range onuGemData {
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301762 onuID := make([]uint32, 1)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001763 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
Andrey Pozolotin32b36562021-06-02 10:23:26 +03001764 if err = dh.clearUNIData(ctx, &onuGemData[i]); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001765 logger.Errorw(ctx, "failed-to-clear-data-for-onu", log.Fields{"onu-device": onu})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301766 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301767 // Clear flowids for gem cache.
1768 for _, gem := range onu.GemPorts {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001769 dh.resourceMgr[ponPort].DeleteFlowIDsForGem(ctx, ponPort, gem)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301770 }
1771 onuID[0] = onu.OnuID
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001772 dh.resourceMgr[ponPort].FreeonuID(ctx, ponPort, onuID)
1773 err = dh.resourceMgr[ponPort].DelOnuGemInfo(ctx, ponPort, onu.OnuID)
1774 if err != nil {
1775 logger.Errorw(ctx, "failed-to-update-onugem-info", log.Fields{"intfid": ponPort, "onugeminfo": onuGemData})
1776 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301777 }
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07001778 if err := dh.resourceMgr[ponPort].Delete(ctx, ponPort); err != nil {
1779 logger.Debug(ctx, err)
1780 }
Devmalya Paul495b94a2019-08-27 19:42:00 -04001781 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -07001782 }
A R Karthick1f85b802019-10-11 05:06:05 +00001783
Devmalya Paul495b94a2019-08-27 19:42:00 -04001784 /*Delete ONU map for the device*/
Naga Manjunatha8dc9372019-10-31 23:01:18 +05301785 dh.onus.Range(func(key interface{}, value interface{}) bool {
1786 dh.onus.Delete(key)
1787 return true
1788 })
1789
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001790 /*Delete discovered ONU map for the device*/
1791 dh.discOnus.Range(func(key interface{}, value interface{}) bool {
1792 dh.discOnus.Delete(key)
1793 return true
1794 })
Devmalya Paul495b94a2019-08-27 19:42:00 -04001795}
1796
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001797//RebootDevice reboots the given device
Neha Sharma96b7bf22020-06-15 10:37:32 +00001798func (dh *DeviceHandler) RebootDevice(ctx context.Context, device *voltha.Device) error {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001799 if _, err := dh.Client.Reboot(log.WithSpanFromContext(context.Background(), ctx), new(oop.Empty)); err != nil {
Thomas Lee S985938d2020-05-04 11:40:41 +05301800 return olterrors.NewErrAdapter("olt-reboot-failed", log.Fields{"device-id": dh.device.Id}, err)
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001801 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001802 logger.Debugw(ctx, "rebooted-device-successfully", log.Fields{"device-id": device.Id})
Girish Gowdru0fe5f7e2019-05-28 05:12:27 -04001803 return nil
1804}
1805
David K. Bainbridge794735f2020-02-11 21:01:37 -08001806func (dh *DeviceHandler) handlePacketIndication(ctx context.Context, packetIn *oop.PacketIndication) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001807 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001808 logger.Debugw(ctx, "received-packet-in", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001809 "packet-indication": *packetIn,
1810 "device-id": dh.device.Id,
1811 "packet": hex.EncodeToString(packetIn.Pkt),
1812 })
1813 }
Girish Gowdra9602eb42020-09-09 15:50:39 -07001814 logicalPortNum, err := dh.flowMgr[packetIn.IntfId].GetLogicalPortFromPacketIn(ctx, packetIn)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001815 if err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +00001816 return olterrors.NewErrNotFound("logical-port", log.Fields{"packet": hex.EncodeToString(packetIn.Pkt)}, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001817 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001818 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001819 logger.Debugw(ctx, "sending-packet-in-to-core", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001820 "logical-port-num": logicalPortNum,
1821 "device-id": dh.device.Id,
1822 "packet": hex.EncodeToString(packetIn.Pkt),
1823 })
1824 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001825
Neha Sharma8f4e4322020-08-06 10:51:53 +00001826 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 +05301827 return olterrors.NewErrCommunication("send-packet-in", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001828 "destination": "core",
Thomas Lee S985938d2020-05-04 11:40:41 +05301829 "source": dh.device.Type,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001830 "device-id": dh.device.Id,
1831 "packet": hex.EncodeToString(packetIn.Pkt),
1832 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001833 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001834
Matteo Scandolo92186242020-06-12 10:54:18 -07001835 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001836 logger.Debugw(ctx, "success-sending-packet-in-to-core!", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001837 "packet": hex.EncodeToString(packetIn.Pkt),
1838 "device-id": dh.device.Id,
1839 })
1840 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001841 return nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001842}
1843
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001844// PacketOut sends packet-out from VOLTHA to OLT on the egress port provided
npujarec5762e2020-01-01 14:08:48 +05301845func (dh *DeviceHandler) PacketOut(ctx context.Context, egressPortNo int, packet *of.OfpPacketOut) error {
Matteo Scandolo92186242020-06-12 10:54:18 -07001846 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001847 logger.Debugw(ctx, "incoming-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001848 "device-id": dh.device.Id,
1849 "egress-port-no": egressPortNo,
1850 "pkt-length": len(packet.Data),
1851 "packet": hex.EncodeToString(packet.Data),
1852 })
1853 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001854
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001855 egressPortType := IntfIDToPortTypeName(uint32(egressPortNo))
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001856 if egressPortType == voltha.Port_ETHERNET_UNI {
Matt Jeanneret1359c732019-08-01 21:40:02 -04001857 outerEthType := (uint16(packet.Data[12]) << 8) | uint16(packet.Data[13])
1858 innerEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301859 if outerEthType == 0x8942 || outerEthType == 0x88cc {
1860 // Do not packet-out lldp packets on uni port.
1861 // ONOS has no clue about uni/nni ports, it just packets out on all
1862 // available ports on the Logical Switch. It should not be interested
1863 // in the UNI links.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001864 logger.Debugw(ctx, "dropping-lldp-packet-out-on-uni", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001865 "device-id": dh.device.Id,
1866 })
Girish Gowdra6e1534a2019-11-15 19:24:04 +05301867 return nil
1868 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001869 if outerEthType == 0x88a8 || outerEthType == 0x8100 {
1870 if innerEthType == 0x8100 {
1871 // q-in-q 802.1ad or 802.1q double tagged packet.
1872 // slice out the outer tag.
1873 packet.Data = append(packet.Data[:12], packet.Data[16:]...)
Matteo Scandolo92186242020-06-12 10:54:18 -07001874 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001875 logger.Debugw(ctx, "packet-now-single-tagged", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001876 "packet-data": hex.EncodeToString(packet.Data),
1877 "device-id": dh.device.Id,
1878 })
1879 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001880 }
1881 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001882 intfID := IntfIDFromUniPortNum(uint32(egressPortNo))
1883 onuID := OnuIDFromPortNum(uint32(egressPortNo))
Manikkaraj kb1d51442019-07-23 10:41:02 -04001884 uniID := UniIDFromPortNum(uint32(egressPortNo))
1885
Girish Gowdra9602eb42020-09-09 15:50:39 -07001886 gemPortID, err := dh.flowMgr[intfID].GetPacketOutGemPortID(ctx, intfID, onuID, uint32(egressPortNo), packet.Data)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001887 if err != nil {
1888 // In this case the openolt agent will receive the gemPortID as 0.
1889 // The agent tries to retrieve the gemPortID in this case.
1890 // This may not always succeed at the agent and packetOut may fail.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001891 logger.Errorw(ctx, "failed-to-retrieve-gemport-id-for-packet-out", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001892 "intf-id": intfID,
1893 "onu-id": onuID,
1894 "uni-id": uniID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001895 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301896 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001897 })
Manikkaraj kb1d51442019-07-23 10:41:02 -04001898 }
1899
1900 onuPkt := oop.OnuPacket{IntfId: intfID, OnuId: onuID, PortNo: uint32(egressPortNo), GemportId: gemPortID, Pkt: packet.Data}
Matteo Scandolo92186242020-06-12 10:54:18 -07001901 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001902 logger.Debugw(ctx, "sending-packet-to-onu", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001903 "egress-port-no": egressPortNo,
1904 "intf-id": intfID,
1905 "onu-id": onuID,
1906 "uni-id": uniID,
1907 "gem-port-id": gemPortID,
1908 "packet": hex.EncodeToString(packet.Data),
1909 "device-id": dh.device.Id,
1910 })
1911 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001912
npujarec5762e2020-01-01 14:08:48 +05301913 if _, err := dh.Client.OnuPacketOut(ctx, &onuPkt); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301914 return olterrors.NewErrCommunication("packet-out-send", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001915 "source": "adapter",
1916 "destination": "onu",
1917 "egress-port-number": egressPortNo,
Matteo Scandolo92186242020-06-12 10:54:18 -07001918 "intf-id": intfID,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001919 "oni-id": onuID,
1920 "uni-id": uniID,
1921 "gem-port-id": gemPortID,
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001922 "packet": hex.EncodeToString(packet.Data),
1923 "device-id": dh.device.Id,
1924 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001925 }
1926 } else if egressPortType == voltha.Port_ETHERNET_NNI {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001927 nniIntfID, err := IntfIDFromNniPortNum(ctx, uint32(egressPortNo))
David K. Bainbridge794735f2020-02-11 21:01:37 -08001928 if err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001929 return olterrors.NewErrInvalidValue(log.Fields{
1930 "egress-nni-port": egressPortNo,
1931 "device-id": dh.device.Id,
1932 }, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001933 }
1934 uplinkPkt := oop.UplinkPacket{IntfId: nniIntfID, Pkt: packet.Data}
Matt Jeanneret1359c732019-08-01 21:40:02 -04001935
Matteo Scandolo92186242020-06-12 10:54:18 -07001936 if logger.V(log.DebugLevel) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001937 logger.Debugw(ctx, "sending-packet-to-nni", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001938 "uplink-pkt": uplinkPkt,
1939 "packet": hex.EncodeToString(packet.Data),
1940 "device-id": dh.device.Id,
1941 })
1942 }
Matt Jeanneret1359c732019-08-01 21:40:02 -04001943
npujarec5762e2020-01-01 14:08:48 +05301944 if _, err := dh.Client.UplinkPacketOut(ctx, &uplinkPkt); err != nil {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001945 return olterrors.NewErrCommunication("packet-out-to-nni", log.Fields{
1946 "packet": hex.EncodeToString(packet.Data),
1947 "device-id": dh.device.Id,
1948 }, err)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001949 }
1950 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001951 logger.Warnw(ctx, "packet-out-to-this-interface-type-not-implemented", log.Fields{
Shrey Baid807a2a02020-04-09 12:52:45 +05301952 "egress-port-no": egressPortNo,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001953 "egressPortType": egressPortType,
1954 "packet": hex.EncodeToString(packet.Data),
Thomas Lee S985938d2020-05-04 11:40:41 +05301955 "device-id": dh.device.Id,
Matteo Scandolo6056e822019-11-13 14:05:29 -08001956 })
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001957 }
1958 return nil
1959}
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001960
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001961func (dh *DeviceHandler) formOnuKey(intfID, onuID uint32) string {
1962 return "" + strconv.Itoa(int(intfID)) + "." + strconv.Itoa(int(onuID))
Mahir Gunyela3f9add2019-06-06 15:13:19 -07001963}
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301964
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001965func startHeartbeatCheck(ctx context.Context, dh *DeviceHandler) {
Neha Sharma8f4e4322020-08-06 10:51:53 +00001966
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301967 // start the heartbeat check towards the OLT.
1968 var timerCheck *time.Timer
1969
1970 for {
1971 heartbeatTimer := time.NewTimer(dh.openOLT.HeartbeatCheckInterval)
1972 select {
1973 case <-heartbeatTimer.C:
Neha Sharma8f4e4322020-08-06 10:51:53 +00001974 ctxWithTimeout, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.openOLT.GrpcTimeoutInterval)
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001975 if heartBeat, err := dh.Client.HeartbeatCheck(ctxWithTimeout, new(oop.Empty)); err != nil {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001976 logger.Warnw(ctx, "heartbeat-failed", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301977 if timerCheck == nil {
1978 // start a after func, when expired will update the state to the core
Chaitrashree G Sa4649252020-03-11 21:24:11 -04001979 timerCheck = time.AfterFunc(dh.openOLT.HeartbeatFailReportInterval, func() { dh.updateStateUnreachable(ctx) })
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301980 }
1981 } else {
1982 if timerCheck != nil {
1983 if timerCheck.Stop() {
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001984 logger.Debugw(ctx, "got-heartbeat-within-timeout", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301985 }
1986 timerCheck = nil
1987 }
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001988 logger.Debugw(ctx, "heartbeat",
Shrey Baid807a2a02020-04-09 12:52:45 +05301989 log.Fields{"signature": heartBeat,
Thomas Lee S985938d2020-05-04 11:40:41 +05301990 "device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301991 }
1992 cancel()
1993 case <-dh.stopHeartbeatCheck:
Matteo Scandolo861e06e2021-05-26 11:51:46 -07001994 logger.Debugw(ctx, "stopping-heartbeat-check", log.Fields{"device-id": dh.device.Id})
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05301995 return
1996 }
1997 }
1998}
1999
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002000func (dh *DeviceHandler) updateStateUnreachable(ctx context.Context) {
2001 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
2002 if err != nil || device == nil {
Girish Gowdrab1caa442020-10-19 12:24:39 -07002003 // One case where we have seen core returning an error for GetDevice call is after OLT device delete.
2004 // After OLT delete, the adapter asks for OLT to reboot. When OLT is rebooted, shortly we loose heartbeat.
2005 // The 'startHeartbeatCheck' then asks the device to be marked unreachable towards the core, but the core
2006 // has already deleted the device and returns error. In this particular scenario, it is Ok because any necessary
2007 // cleanup in the adapter was already done during DeleteDevice API handler routine.
Kent Hagermane6ff1012020-07-14 15:07:53 -04002008 _ = olterrors.NewErrNotFound("device", log.Fields{"device-id": dh.device.Id}, err).Log()
Girish Gowdrab1caa442020-10-19 12:24:39 -07002009 // Immediately return, otherwise accessing a null 'device' struct would cause panic
2010 return
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002011 }
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302012
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002013 logger.Debugw(ctx, "update-state-unreachable", log.Fields{"device-id": dh.device.Id, "connect-status": device.ConnectStatus,
2014 "admin-state": device.AdminState, "oper-status": device.OperStatus})
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002015 if device.ConnectStatus == voltha.ConnectStatus_REACHABLE {
2016 if err = dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002017 _ = 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 -04002018 }
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002019 if err = dh.coreProxy.PortsStateUpdate(ctx, dh.device.Id, 0, voltha.OperStatus_UNKNOWN); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04002020 _ = olterrors.NewErrAdapter("port-update-failed", log.Fields{"device-id": dh.device.Id}, err).Log()
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002021 }
Gamze Abaka07868a52020-12-17 14:19:28 +00002022
2023 //raise olt communication failure event
Girish Gowdrac1b9d5e2021-04-22 12:47:44 -07002024 raisedTs := time.Now().Unix()
Gamze Abaka07868a52020-12-17 14:19:28 +00002025 device.ConnectStatus = voltha.ConnectStatus_UNREACHABLE
2026 device.OperStatus = voltha.OperStatus_UNKNOWN
2027 go dh.eventMgr.oltCommunicationEvent(ctx, device, raisedTs)
2028
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -07002029 dh.cleanupDeviceResources(ctx)
Matteo Scandolo861e06e2021-05-26 11:51:46 -07002030 // Stop the Stats collector
2031 dh.stopCollector <- true
2032 // stop the heartbeat check routine
2033 dh.stopHeartbeatCheck <- true
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002034
Girish Gowdra3ab6d212020-03-24 17:33:15 -07002035 dh.lockDevice.RLock()
2036 // Stop the read indication only if it the routine is active
2037 // The read indication would have already stopped due to failure on the gRPC stream following OLT going unreachable
2038 // Sending message on the 'stopIndication' channel again will cause the readIndication routine to immediately stop
2039 // on next execution of the readIndication routine.
2040 if dh.isReadIndicationRoutineActive {
2041 dh.stopIndications <- true
2042 }
2043 dh.lockDevice.RUnlock()
2044
Gamze Abakac2c32a62021-03-11 11:44:18 +00002045 //reset adapter reconcile flag
2046 dh.adapterPreviouslyConnected = false
2047
Chaitrashree G Sa4649252020-03-11 21:24:11 -04002048 dh.transitionMap.Handle(ctx, DeviceInit)
2049
Abhilash Laxmeshwarf9942e92020-01-07 15:32:44 +05302050 }
2051}
kesavand39e0aa32020-01-28 20:58:50 -05002052
2053// EnablePort to enable Pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002054func (dh *DeviceHandler) EnablePort(ctx context.Context, port *voltha.Port) error {
2055 logger.Debugw(ctx, "enable-port", log.Fields{"Device": dh.device, "port": port})
2056 return dh.modifyPhyPort(ctx, port, true)
kesavand39e0aa32020-01-28 20:58:50 -05002057}
2058
2059// DisablePort to disable pon interface
Neha Sharma96b7bf22020-06-15 10:37:32 +00002060func (dh *DeviceHandler) DisablePort(ctx context.Context, port *voltha.Port) error {
2061 logger.Debugw(ctx, "disable-port", log.Fields{"Device": dh.device, "port": port})
2062 return dh.modifyPhyPort(ctx, port, false)
kesavand39e0aa32020-01-28 20:58:50 -05002063}
2064
kdarapu1afeceb2020-02-12 01:38:09 -05002065//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 +00002066func (dh *DeviceHandler) modifyPhyPort(ctx context.Context, port *voltha.Port, enablePort bool) error {
2067 logger.Infow(ctx, "modifyPhyPort", log.Fields{"port": port, "Enable": enablePort, "device-id": dh.device.Id})
kesavand39e0aa32020-01-28 20:58:50 -05002068 if port.GetType() == voltha.Port_ETHERNET_NNI {
2069 // Bug is opened for VOL-2505 to support NNI disable feature.
Neha Sharma96b7bf22020-06-15 10:37:32 +00002070 logger.Infow(ctx, "voltha-supports-single-nni-hence-disable-of-nni-not-allowed",
Shrey Baid807a2a02020-04-09 12:52:45 +05302071 log.Fields{"device": dh.device, "port": port})
Thomas Lee S94109f12020-03-03 16:39:29 +05302072 return olterrors.NewErrAdapter("illegal-port-request", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002073 "port-type": port.GetType,
Girish Kumarf26e4882020-03-05 06:49:10 +00002074 "enable-state": enablePort}, nil)
kesavand39e0aa32020-01-28 20:58:50 -05002075 }
2076 // fetch interfaceid from PortNo
2077 ponID := PortNoToIntfID(port.GetPortNo(), voltha.Port_PON_OLT)
2078 ponIntf := &oop.Interface{IntfId: ponID}
2079 var operStatus voltha.OperStatus_Types
2080 if enablePort {
2081 operStatus = voltha.OperStatus_ACTIVE
npujarec5762e2020-01-01 14:08:48 +05302082 out, err := dh.Client.EnablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002083
2084 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302085 return olterrors.NewErrAdapter("pon-port-enable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002086 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002087 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002088 }
2089 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002090 dh.activePorts.Store(ponID, true)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002091 logger.Infow(ctx, "enabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002092 } else {
2093 operStatus = voltha.OperStatus_UNKNOWN
npujarec5762e2020-01-01 14:08:48 +05302094 out, err := dh.Client.DisablePonIf(ctx, ponIntf)
kesavand39e0aa32020-01-28 20:58:50 -05002095 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302096 return olterrors.NewErrAdapter("pon-port-disable-failed", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08002097 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002098 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002099 }
2100 // updating interface local cache for collecting stats
Chaitrashree G Sef088112020-02-03 21:39:27 -05002101 dh.activePorts.Store(ponID, false)
Neha Sharma96b7bf22020-06-15 10:37:32 +00002102 logger.Infow(ctx, "disabled-pon-port", log.Fields{"out": out, "device-id": dh.device, "Port": port})
kesavand39e0aa32020-01-28 20:58:50 -05002103 }
Thomas Lee S985938d2020-05-04 11:40:41 +05302104 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 +05302105 return olterrors.NewErrAdapter("port-state-update-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302106 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002107 "port": port.PortNo}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002108 }
2109 return nil
2110}
2111
kdarapu1afeceb2020-02-12 01:38:09 -05002112//disableAdminDownPorts disables the ports, if the corresponding port Adminstate is disabled on reboot and Renable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002113func (dh *DeviceHandler) disableAdminDownPorts(ctx context.Context, ports []*voltha.Port) error {
kesavand39e0aa32020-01-28 20:58:50 -05002114 // Disable the port and update the oper_port_status to core
2115 // if the Admin state of the port is disabled on reboot and re-enable device.
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002116 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002117 if port.AdminState == common.AdminState_DISABLED {
Neha Sharma96b7bf22020-06-15 10:37:32 +00002118 if err := dh.DisablePort(ctx, port); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302119 return olterrors.NewErrAdapter("port-disable-failed", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302120 "device-id": dh.device.Id,
Girish Kumarf26e4882020-03-05 06:49:10 +00002121 "port": port}, err)
kesavand39e0aa32020-01-28 20:58:50 -05002122 }
2123 }
2124 }
2125 return nil
2126}
2127
2128//populateActivePorts to populate activePorts map
Kent Hagermanf1db18b2020-07-08 13:38:15 -04002129func (dh *DeviceHandler) populateActivePorts(ctx context.Context, ports []*voltha.Port) {
2130 logger.Infow(ctx, "populateActivePorts", log.Fields{"device-id": dh.device.Id})
2131 for _, port := range ports {
kesavand39e0aa32020-01-28 20:58:50 -05002132 if port.Type == voltha.Port_ETHERNET_NNI {
2133 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002134 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), true)
kesavand39e0aa32020-01-28 20:58:50 -05002135 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002136 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_ETHERNET_NNI), false)
kesavand39e0aa32020-01-28 20:58:50 -05002137 }
2138 }
2139 if port.Type == voltha.Port_PON_OLT {
2140 if port.OperStatus == voltha.OperStatus_ACTIVE {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002141 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), true)
kesavand39e0aa32020-01-28 20:58:50 -05002142 } else {
Chaitrashree G Sef088112020-02-03 21:39:27 -05002143 dh.activePorts.Store(PortNoToIntfID(port.PortNo, voltha.Port_PON_OLT), false)
kesavand39e0aa32020-01-28 20:58:50 -05002144 }
2145 }
2146 }
2147}
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002148
2149// ChildDeviceLost deletes ONU and clears pon resources related to it.
Girish Gowdraa0870562021-03-11 14:30:14 -08002150func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
divyadesai3af43e12020-08-18 07:10:54 +00002151 logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002152 intfID := PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
2153 onuKey := dh.formOnuKey(intfID, onuID)
Girish Gowdraa0870562021-03-11 14:30:14 -08002154
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002155 var sn *oop.SerialNumber
2156 var err error
Girish Gowdraa0870562021-03-11 14:30:14 -08002157 if sn, err = dh.deStringifySerialNumber(onuSn); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302158 return olterrors.NewErrAdapter("failed-to-destringify-serial-number",
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002159 log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302160 "devicer-id": dh.device.Id,
Girish Gowdraa0870562021-03-11 14:30:14 -08002161 "serial-number": onuSn}, err).Log()
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002162 }
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002163
Girish Gowdra89ae6d82020-05-28 23:40:53 -07002164 onu := &oop.Onu{IntfId: intfID, OnuId: onuID, SerialNumber: sn}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002165 //clear PON resources associated with ONU
2166 onuGem, err := dh.resourceMgr[intfID].GetOnuGemInfo(ctx, intfID, onuID)
2167 if err != nil || onuGem == nil || onuGem.OnuID != onuID {
2168 logger.Warnw(ctx, "failed-to-get-onu-info-for-pon-port", log.Fields{
2169 "device-id": dh.device.Id,
2170 "intf-id": intfID,
2171 "onuID": onuID,
2172 "err": err})
2173 } else {
2174 logger.Debugw(ctx, "onu-data", log.Fields{"onu": onu})
2175 if err := dh.clearUNIData(ctx, onuGem); err != nil {
2176 logger.Warnw(ctx, "failed-to-clear-uni-data-for-onu", log.Fields{
2177 "device-id": dh.device.Id,
2178 "onu-device": onu,
2179 "err": err})
2180 }
2181 // Clear flowids for gem cache.
2182 for _, gem := range onuGem.GemPorts {
2183 dh.resourceMgr[intfID].DeleteFlowIDsForGem(ctx, intfID, gem)
2184 }
2185 err := dh.resourceMgr[intfID].DelOnuGemInfo(ctx, intfID, onuID)
2186 if err != nil {
2187 logger.Warnw(ctx, "persistence-update-onu-gem-info-failed", log.Fields{
2188 "intf-id": intfID,
2189 "onu-device": onu,
2190 "onu-gem": onuGem,
2191 "err": err})
2192 //Not returning error on cleanup.
2193 }
2194 logger.Debugw(ctx, "removed-onu-gem-info", log.Fields{"intf": intfID, "onu-device": onu, "onugem": onuGem})
2195 dh.resourceMgr[intfID].FreeonuID(ctx, intfID, []uint32{onuGem.OnuID})
2196 }
2197 dh.onus.Delete(onuKey)
2198 dh.discOnus.Delete(onuSn)
2199
2200 // Now clear the ONU on the OLT
Neha Sharma8f4e4322020-08-06 10:51:53 +00002201 if _, err := dh.Client.DeleteOnu(log.WithSpanFromContext(context.Background(), ctx), onu); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05302202 return olterrors.NewErrAdapter("failed-to-delete-onu", log.Fields{
Thomas Lee S985938d2020-05-04 11:40:41 +05302203 "device-id": dh.device.Id,
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002204 "onu-id": onuID}, err).Log()
2205 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002206
Chaitrashree G S1a55b882020-02-04 17:35:35 -05002207 return nil
2208}
Girish Gowdracefae192020-03-19 18:14:10 -07002209
2210func getInPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002211 for _, field := range flow_utils.GetOfbFields(flow) {
2212 if field.Type == flow_utils.IN_PORT {
Girish Gowdracefae192020-03-19 18:14:10 -07002213 return field.GetPort()
2214 }
2215 }
2216 return InvalidPort
2217}
2218
2219func getOutPortFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002220 for _, action := range flow_utils.GetActions(flow) {
2221 if action.Type == flow_utils.OUTPUT {
Girish Gowdracefae192020-03-19 18:14:10 -07002222 if out := action.GetOutput(); out != nil {
2223 return out.GetPort()
2224 }
2225 }
2226 }
2227 return InvalidPort
2228}
2229
Girish Gowdracefae192020-03-19 18:14:10 -07002230func getPorts(flow *of.OfpFlowStats) (uint32, uint32) {
2231 inPort := getInPortFromFlow(flow)
2232 outPort := getOutPortFromFlow(flow)
2233
2234 if inPort == InvalidPort || outPort == InvalidPort {
2235 return inPort, outPort
2236 }
2237
2238 if isControllerFlow := IsControllerBoundFlow(outPort); isControllerFlow {
2239 /* Get UNI port/ IN Port from tunnel ID field for upstream controller bound flows */
2240 if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002241 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002242 return uniPort, outPort
2243 }
2244 }
2245 } else {
2246 // Downstream flow from NNI to PON port , Use tunnel ID as new OUT port / UNI port
2247 if portType := IntfIDToPortTypeName(outPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002248 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002249 return inPort, uniPort
2250 }
2251 // Upstream flow from PON to NNI port , Use tunnel ID as new IN port / UNI port
2252 } else if portType := IntfIDToPortTypeName(inPort); portType == voltha.Port_PON_OLT {
Girish Gowdra491a9c62021-01-06 16:43:07 -08002253 if uniPort := flow_utils.GetChildPortFromTunnelId(flow); uniPort != 0 {
Girish Gowdracefae192020-03-19 18:14:10 -07002254 return uniPort, outPort
2255 }
2256 }
2257 }
2258
2259 return InvalidPort, InvalidPort
2260}
Matt Jeanneretceea2e02020-03-27 14:19:57 -04002261
2262func extractOmciTransactionID(omciPkt []byte) uint16 {
2263 if len(omciPkt) > 3 {
2264 d := omciPkt[0:2]
2265 transid := binary.BigEndian.Uint16(d)
2266 return transid
2267 }
2268 return 0
2269}
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07002270
2271// StoreOnuDevice stores the onu parameters to the local cache.
2272func (dh *DeviceHandler) StoreOnuDevice(onuDevice *OnuDevice) {
2273 onuKey := dh.formOnuKey(onuDevice.intfID, onuDevice.onuID)
2274 dh.onus.Store(onuKey, onuDevice)
2275}
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002276
Neha Sharma8f4e4322020-08-06 10:51:53 +00002277func (dh *DeviceHandler) getExtValue(ctx context.Context, device *voltha.Device, value voltha.ValueType_Type) (*voltha.ReturnValues, error) {
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002278 var err error
Andrea Campanella9931ad62020-04-28 15:11:06 +02002279 var sn *oop.SerialNumber
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00002280 var ID uint32
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002281 resp := new(voltha.ReturnValues)
2282 valueparam := new(oop.ValueParam)
Neha Sharma8f4e4322020-08-06 10:51:53 +00002283 ctx = log.WithSpanFromContext(context.Background(), ctx)
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002284 logger.Infow(ctx, "getExtValue", log.Fields{"onu-id": device.Id, "pon-intf": device.ParentPortNo})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002285 if sn, err = dh.deStringifySerialNumber(device.SerialNumber); err != nil {
2286 return nil, err
2287 }
2288 ID = device.ProxyAddress.GetOnuId()
2289 Onu := oop.Onu{IntfId: device.ParentPortNo, OnuId: ID, SerialNumber: sn}
2290 valueparam.Onu = &Onu
2291 valueparam.Value = value
2292
2293 // This API is unsupported until agent patch is added
2294 resp.Unsupported = uint32(value)
2295 _ = ctx
2296
2297 // Uncomment this code once agent changes are complete and tests
2298 /*
2299 resp, err = dh.Client.GetValue(ctx, valueparam)
2300 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002301 logger.Errorw("error-while-getValue", log.Fields{"DeviceID": dh.device, "onu-id": onuid, "err": err})
Dinesh Belwalkardb587af2020-02-27 15:37:16 -08002302 return nil, err
2303 }
2304 */
2305
Girish Kumara1ea2aa2020-08-19 18:14:22 +00002306 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 -08002307 return resp, nil
2308}
Girish Gowdra9602eb42020-09-09 15:50:39 -07002309
Girish Gowdrafb3d6102020-10-16 16:32:36 -07002310func (dh *DeviceHandler) getPonIfFromFlow(flow *of.OfpFlowStats) uint32 {
Girish Gowdra9602eb42020-09-09 15:50:39 -07002311 // Default to PON0
2312 var intfID uint32
2313 inPort, outPort := getPorts(flow)
Girish Gowdra9602eb42020-09-09 15:50:39 -07002314 if inPort != InvalidPort && outPort != InvalidPort {
2315 _, intfID, _, _ = ExtractAccessFromFlow(inPort, outPort)
2316 }
2317 return intfID
2318}
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002319
Mahir Gunyelb0046752021-02-26 13:51:05 -08002320func (dh *DeviceHandler) getOnuIndicationChannel(ctx context.Context, intfID uint32) chan onuIndicationMsg {
2321 dh.perPonOnuIndicationChannelLock.Lock()
2322 if ch, ok := dh.perPonOnuIndicationChannel[intfID]; ok {
2323 dh.perPonOnuIndicationChannelLock.Unlock()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002324 return ch.indicationChannel
2325 }
2326 channels := onuIndicationChannels{
2327 //We create a buffered channel here to avoid calling function to be blocked
Mahir Gunyelb0046752021-02-26 13:51:05 -08002328 //in case of multiple indications from the ONUs,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002329 //especially in the case where indications are buffered in OLT.
Mahir Gunyelb0046752021-02-26 13:51:05 -08002330 indicationChannel: make(chan onuIndicationMsg, 500),
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002331 stopChannel: make(chan struct{}),
2332 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002333 dh.perPonOnuIndicationChannel[intfID] = channels
2334 dh.perPonOnuIndicationChannelLock.Unlock()
2335 go dh.onuIndicationsRoutine(&channels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002336 return channels.indicationChannel
2337
2338}
2339
Mahir Gunyelb0046752021-02-26 13:51:05 -08002340func (dh *DeviceHandler) removeOnuIndicationChannels(ctx context.Context) {
2341 logger.Debug(ctx, "remove-onu-indication-channels", log.Fields{"device-id": dh.device.Id})
2342 dh.perPonOnuIndicationChannelLock.Lock()
2343 defer dh.perPonOnuIndicationChannelLock.Unlock()
2344 for _, v := range dh.perPonOnuIndicationChannel {
2345 close(v.stopChannel)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002346 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002347 dh.perPonOnuIndicationChannel = make(map[uint32]onuIndicationChannels)
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002348}
2349
Mahir Gunyelb0046752021-02-26 13:51:05 -08002350func (dh *DeviceHandler) putOnuIndicationToChannel(ctx context.Context, indication *oop.Indication, intfID uint32) {
2351 ind := onuIndicationMsg{
2352 ctx: ctx,
2353 indication: indication,
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002354 }
Mahir Gunyelb0046752021-02-26 13:51:05 -08002355 logger.Debugw(ctx, "put-onu-indication-to-channel", log.Fields{"indication": indication, "intfID": intfID})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002356 // Send the onuIndication on the ONU channel
Mahir Gunyelb0046752021-02-26 13:51:05 -08002357 dh.getOnuIndicationChannel(ctx, intfID) <- ind
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002358}
2359
Mahir Gunyelb0046752021-02-26 13:51:05 -08002360func (dh *DeviceHandler) onuIndicationsRoutine(onuChannels *onuIndicationChannels) {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002361 for {
2362 select {
2363 // process one indication per onu, before proceeding to the next one
2364 case onuInd := <-onuChannels.indicationChannel:
2365 logger.Debugw(onuInd.ctx, "calling-indication", log.Fields{"device-id": dh.device.Id,
Mahir Gunyelb0046752021-02-26 13:51:05 -08002366 "ind": onuInd.indication})
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002367 switch onuInd.indication.Data.(type) {
2368 case *oop.Indication_OnuInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002369 if err := dh.onuIndication(onuInd.ctx, onuInd.indication.GetOnuInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002370 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2371 "type": "onu-indication",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002372 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002373 }
2374 case *oop.Indication_OnuDiscInd:
Mahir Gunyelb0046752021-02-26 13:51:05 -08002375 if err := dh.onuDiscIndication(onuInd.ctx, onuInd.indication.GetOnuDiscInd()); err != nil {
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002376 _ = olterrors.NewErrAdapter("handle-indication-error", log.Fields{
2377 "type": "onu-discovery",
Mahir Gunyelb0046752021-02-26 13:51:05 -08002378 "device-id": dh.device.Id}, err).Log()
Mahir Gunyel2fb81472020-12-16 23:18:34 -08002379 }
2380 }
2381 case <-onuChannels.stopChannel:
2382 logger.Debugw(context.Background(), "stop-signal-received-for-onu-channel", log.Fields{"device-id": dh.device.Id})
2383 close(onuChannels.indicationChannel)
2384 return
2385 }
2386 }
2387}
Girish Gowdra491a9c62021-01-06 16:43:07 -08002388
2389// RouteMcastFlowOrGroupMsgToChannel routes incoming mcast flow or group to a channel to be handled by the a specific
2390// instance of mcastFlowOrGroupChannelHandlerRoutine meant to handle messages for that group.
2391func (dh *DeviceHandler) RouteMcastFlowOrGroupMsgToChannel(ctx context.Context, flow *voltha.OfpFlowStats, group *voltha.OfpGroupEntry, action string) error {
2392 // Step1 : Fill McastFlowOrGroupControlBlock
2393 // Step2 : Push the McastFlowOrGroupControlBlock to appropriate channel
2394 // Step3 : Wait on response channel for response
2395 // Step4 : Return error value
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002396 startTime := time.Now()
Girish Gowdra491a9c62021-01-06 16:43:07 -08002397 logger.Debugw(ctx, "process-flow-or-group", log.Fields{"flow": flow, "group": group, "action": action})
2398 errChan := make(chan error)
2399 var groupID uint32
2400 mcastFlowOrGroupCb := McastFlowOrGroupControlBlock{
2401 ctx: ctx,
2402 flowOrGroupAction: action,
2403 flow: flow,
2404 group: group,
2405 errChan: &errChan,
2406 }
2407 if flow != nil {
2408 groupID = flow_utils.GetGroup(flow)
2409 } else if group != nil {
2410 groupID = group.Desc.GroupId
2411 } else {
2412 return errors.New("flow-and-group-both-nil")
2413 }
2414 // Derive the appropriate go routine to handle the request by a simple module operation.
2415 // There are only MaxNumOfGroupHandlerChannels number of channels to handle the mcast flow or group
2416 dh.incomingMcastFlowOrGroup[groupID%MaxNumOfGroupHandlerChannels] <- mcastFlowOrGroupCb
2417 // Wait for handler to return error value
2418 err := <-errChan
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07002419 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 -08002420 return err
2421}
2422
2423// mcastFlowOrGroupChannelHandlerRoutine routine to handle incoming mcast flow/group message
2424func (dh *DeviceHandler) mcastFlowOrGroupChannelHandlerRoutine(mcastFlowOrGroupChannel chan McastFlowOrGroupControlBlock) {
2425 for {
2426 // block on the channel to receive an incoming mcast flow/group
2427 // process the flow completely before proceeding to handle the next flow
2428 mcastFlowOrGroupCb := <-mcastFlowOrGroupChannel
2429 if mcastFlowOrGroupCb.flow != nil {
2430 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2431 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-flow",
2432 log.Fields{"device-id": dh.device.Id,
2433 "flowToAdd": mcastFlowOrGroupCb.flow})
2434 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2435 err := dh.flowMgr[0].AddFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow, nil)
2436 // Pass the return value over the return channel
2437 *mcastFlowOrGroupCb.errChan <- err
2438 } else { // flow remove
2439 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-flow",
2440 log.Fields{"device-id": dh.device.Id,
2441 "flowToRemove": mcastFlowOrGroupCb.flow})
2442 // The mcast flow is not unique to any particular PON port, so it is OK to default to PON0
2443 err := dh.flowMgr[0].RemoveFlow(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.flow)
2444 // Pass the return value over the return channel
2445 *mcastFlowOrGroupCb.errChan <- err
2446 }
2447 } else { // mcast group
2448 if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupAdd {
2449 logger.Debugw(mcastFlowOrGroupCb.ctx, "adding-mcast-group",
2450 log.Fields{"device-id": dh.device.Id,
2451 "groupToAdd": mcastFlowOrGroupCb.group})
2452 err := dh.groupMgr.AddGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2453 // Pass the return value over the return channel
2454 *mcastFlowOrGroupCb.errChan <- err
2455 } else if mcastFlowOrGroupCb.flowOrGroupAction == McastFlowOrGroupModify { // group modify
2456 logger.Debugw(mcastFlowOrGroupCb.ctx, "modifying-mcast-group",
2457 log.Fields{"device-id": dh.device.Id,
2458 "groupToModify": mcastFlowOrGroupCb.group})
2459 err := dh.groupMgr.ModifyGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2460 // Pass the return value over the return channel
2461 *mcastFlowOrGroupCb.errChan <- err
2462 } else { // group remove
2463 logger.Debugw(mcastFlowOrGroupCb.ctx, "removing-mcast-group",
2464 log.Fields{"device-id": dh.device.Id,
2465 "groupToRemove": mcastFlowOrGroupCb.group})
2466 err := dh.groupMgr.DeleteGroup(mcastFlowOrGroupCb.ctx, mcastFlowOrGroupCb.group)
2467 // Pass the return value over the return channel
2468 *mcastFlowOrGroupCb.errChan <- err
2469 }
2470 }
2471 }
2472}
kesavand62126212021-01-12 04:56:06 -05002473
2474func (dh *DeviceHandler) getOltPortCounters(ctx context.Context, oltPortInfo *extension.GetOltPortCounters) *extension.SingleGetValueResponse {
2475
2476 singleValResp := extension.SingleGetValueResponse{
2477 Response: &extension.GetValueResponse{
2478 Response: &extension.GetValueResponse_PortCoutners{
2479 PortCoutners: &extension.GetOltPortCountersResponse{},
2480 },
2481 },
2482 }
2483
2484 errResp := func(status extension.GetValueResponse_Status,
2485 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2486 return &extension.SingleGetValueResponse{
2487 Response: &extension.GetValueResponse{
2488 Status: status,
2489 ErrReason: reason,
2490 },
2491 }
2492 }
2493
2494 if oltPortInfo.PortType != extension.GetOltPortCounters_Port_ETHERNET_NNI &&
2495 oltPortInfo.PortType != extension.GetOltPortCounters_Port_PON_OLT {
2496 //send error response
2497 logger.Debugw(ctx, "getOltPortCounters invalid portType", log.Fields{"oltPortInfo": oltPortInfo.PortType})
2498 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_PORT_TYPE)
2499 }
2500 statIndChn := make(chan bool, 1)
2501 dh.portStats.RegisterForStatIndication(ctx, portStatsType, statIndChn, oltPortInfo.PortNo, oltPortInfo.PortType)
2502 defer dh.portStats.DeRegisterFromStatIndication(ctx, portStatsType, statIndChn)
2503 //request openOlt agent to send the the port statistics indication
2504
2505 go func() {
2506 _, err := dh.Client.CollectStatistics(ctx, new(oop.Empty))
2507 if err != nil {
2508 logger.Errorw(ctx, "getOltPortCounters CollectStatistics failed ", log.Fields{"err": err})
2509 }
2510 }()
2511 select {
2512 case <-statIndChn:
2513 //indication received for ports stats
2514 logger.Debugw(ctx, "getOltPortCounters recvd statIndChn", log.Fields{"oltPortInfo": oltPortInfo})
2515 case <-time.After(oltPortInfoTimeout * time.Second):
2516 logger.Debugw(ctx, "getOltPortCounters timeout happened", log.Fields{"oltPortInfo": oltPortInfo})
2517 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2518 case <-ctx.Done():
2519 logger.Debugw(ctx, "getOltPortCounters ctx Done ", log.Fields{"oltPortInfo": oltPortInfo})
2520 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2521 }
2522 if oltPortInfo.PortType == extension.GetOltPortCounters_Port_ETHERNET_NNI {
2523 //get nni stats
2524 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_ETHERNET_NNI)
2525 logger.Debugw(ctx, "getOltPortCounters intfID ", log.Fields{"intfID": intfID})
2526 cmnni := dh.portStats.collectNNIMetrics(intfID)
2527 if cmnni == nil {
2528 //TODO define the error reason
2529 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2530 }
2531 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmnni)
2532 return &singleValResp
2533
2534 } else if oltPortInfo.PortType == extension.GetOltPortCounters_Port_PON_OLT {
2535 // get pon stats
2536 intfID := PortNoToIntfID(oltPortInfo.PortNo, voltha.Port_PON_OLT)
2537 if val, ok := dh.activePorts.Load(intfID); ok && val == true {
2538 cmpon := dh.portStats.collectPONMetrics(intfID)
2539 if cmpon == nil {
2540 //TODO define the error reason
2541 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2542 }
2543 dh.portStats.updateGetOltPortCountersResponse(ctx, &singleValResp, cmpon)
2544 return &singleValResp
2545 }
2546 }
2547 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2548}
Himani Chawla2c8ae0f2021-05-18 23:27:00 +05302549
2550func (dh *DeviceHandler) getOnuPonCounters(ctx context.Context, onuPonInfo *extension.GetOnuCountersRequest) *extension.SingleGetValueResponse {
2551
2552 singleValResp := extension.SingleGetValueResponse{
2553 Response: &extension.GetValueResponse{
2554 Response: &extension.GetValueResponse_OnuPonCounters{
2555 OnuPonCounters: &extension.GetOnuCountersResponse{},
2556 },
2557 },
2558 }
2559
2560 errResp := func(status extension.GetValueResponse_Status,
2561 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2562 return &extension.SingleGetValueResponse{
2563 Response: &extension.GetValueResponse{
2564 Status: status,
2565 ErrReason: reason,
2566 },
2567 }
2568 }
2569 intfID := onuPonInfo.IntfId
2570 onuID := onuPonInfo.OnuId
2571 onuKey := dh.formOnuKey(intfID, onuID)
2572
2573 if _, ok := dh.onus.Load(onuKey); !ok {
2574 logger.Errorw(ctx, "get-onui-pon-counters-request-invalid-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2575 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2576 }
2577 logger.Debugw(ctx, "get-onui-pon-counters-request-received", log.Fields{"intfID": intfID, "onuID": onuID})
2578 cmnni := dh.portStats.collectOnDemandOnuStats(ctx, intfID, onuID)
2579 if cmnni == nil {
2580 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2581 }
2582 dh.portStats.updateGetOnuPonCountersResponse(ctx, &singleValResp, cmnni)
2583 return &singleValResp
2584
2585}
Gamze Abaka85e9a142021-05-26 13:41:39 +00002586
2587func (dh *DeviceHandler) getRxPower(ctx context.Context, rxPowerRequest *extension.GetRxPowerRequest) *extension.SingleGetValueResponse {
2588
2589 Onu := oop.Onu{IntfId: rxPowerRequest.IntfId, OnuId: rxPowerRequest.OnuId}
2590 rxPower, err := dh.Client.GetPonRxPower(ctx, &Onu)
2591 if err != nil {
2592 logger.Errorw(ctx, "error-while-getting-rx-power", log.Fields{"Onu": Onu, "err": err})
2593 return generateSingleGetValueErrorResponse(err)
2594 }
2595 return &extension.SingleGetValueResponse{
2596 Response: &extension.GetValueResponse{
2597 Status: extension.GetValueResponse_OK,
2598 Response: &extension.GetValueResponse_RxPower{
2599 RxPower: &extension.GetRxPowerResponse{
2600 IntfId: rxPowerRequest.IntfId,
2601 OnuId: rxPowerRequest.OnuId,
2602 Status: rxPower.Status,
2603 FailReason: rxPower.FailReason.String(),
2604 RxPower: rxPower.RxPowerMeanDbm,
2605 },
2606 },
2607 },
2608 }
2609}
2610
2611func generateSingleGetValueErrorResponse(err error) *extension.SingleGetValueResponse {
2612 errResp := func(status extension.GetValueResponse_Status,
2613 reason extension.GetValueResponse_ErrorReason) *extension.SingleGetValueResponse {
2614 return &extension.SingleGetValueResponse{
2615 Response: &extension.GetValueResponse{
2616 Status: status,
2617 ErrReason: reason,
2618 },
2619 }
2620 }
2621
2622 if err != nil {
2623 if e, ok := status.FromError(err); ok {
2624 switch e.Code() {
2625 case codes.Internal:
2626 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INTERNAL_ERROR)
2627 case codes.DeadlineExceeded:
2628 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_TIMEOUT)
2629 case codes.Unimplemented:
2630 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_UNSUPPORTED)
2631 case codes.NotFound:
2632 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_INVALID_DEVICE)
2633 }
2634 }
2635 }
2636
2637 return errResp(extension.GetValueResponse_ERROR, extension.GetValueResponse_REASON_UNDEFINED)
2638}